#include "load-manager.h" #include "pax.h" // Data UserData_t* UserData; GSXData_t* GSXData; paxPayloadData_t* livePaxPayloadData; paxPayloadData_t* targetPaxPayloadData; fPayloadData_t* liveFPayloadData; fPayloadData_t* targetFPayloadData; FuelData_t* liveFuelData; UserOptions_t* UserOptions; // Operational bool commBusCallbackRegistered; HANDLE simConnect; FILE* logFile; MODULE_VAR tick18 = { TICK18 }; // Init extern "C" MSFS_CALLBACK void module_init(void) { log(stdout, MODULE_NAME"Starting init.\n"); logFile = fopen("\\work\\log.txt", "w"); if (logFile == NULL) { log(stderr, MODULE_NAME"Error creating logfile.\n"); } UserData = new UserData_t(); GSXData = new GSXData_t(); livePaxPayloadData = new paxPayloadData_t(); targetPaxPayloadData = new paxPayloadData_t(); liveFPayloadData = new fPayloadData_t(); targetFPayloadData = new fPayloadData_t(); liveFuelData = new FuelData_t(); UserOptions = new UserOptions_t(); targetFPayloadData->CGTarget = targetPaxPayloadData->CGTarget = 21; #pragma region SimConnect // SimConnect open HRESULT hr; hr = SimConnect_Open(&simConnect, "KHOFMANN TFDi MD-11 Load Manager", nullptr, 0, 0, 0); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not open SimConnect connection, terminating.\n"); return; } // SimConnect Empty Weight data definition hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_EMPTY_WEIGHT, "EMPTY WEIGHT", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add EMPTY WEIGHT to data definition, terminating.\n"); return; } // SimConnect Pax/F Weight data definition hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:1", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:1 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:1", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:1 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:2", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:2 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:2", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:2 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:3", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:3 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:3", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:3 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:4", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:4 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:4", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:4 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:5", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:5 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:5", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:5 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:6", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:6 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:6", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:6 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:7", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:7 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:7", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:7 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:8", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:8 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:8", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:8 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:9", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:9 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:9", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:9 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:10", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:10 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:10", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:10 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:11", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:11 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:11", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:11 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:12", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:12 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:12", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:12 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:13", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:13 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:13", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:13 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:14", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:14 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:14", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:14 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:15", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:15 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:15", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:15 to F data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:16", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:16 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:17", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:17 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:18", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:18 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:19", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:19 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:20", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:20 to PAX data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:21", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:21 to PAX data definition, terminating.\n"); return; } // SimConnect Fuel data definition hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL WEIGHT PER GALLON", "pounds", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL WEIGHT PER GALLON to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT MAIN QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT MAIN QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT MAIN QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT MAIN QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER2 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER2 QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER3 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER3 QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT TIP QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT TIP QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT TIP QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT TIP QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK EXTERNAL1 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK EXTERNAL1 QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT AUX QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT AUX QUANTITY to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT AUX QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT AUX QUANTITY to data definition, terminating.\n"); return; } // GSX LVars hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_BOARDING_STATE to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_DEBOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_DEBOARDING_STATE to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_CARGO_PERCENT", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_BOARDING_CARGO_PERCENT to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_DEBOARDING_CARGO_PERCENT", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_DEBOARDING_CARGO_PERCENT to data definition, terminating.\n"); return; } // User LVars hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_EFB_IS_CARGO", "bool", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:MD11_EFB_IS_CARGO to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_OPT_ER", "bool", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:MD11_OPT_ER to data definition, terminating.\n"); return; } hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_EFB_OPTIONS_GENERAL", "number", SIMCONNECT_DATATYPE_FLOAT64); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not add L:MD11_EFB_OPTIONS_GENERAL to data definition, terminating.\n"); return; } log(stdout, MODULE_NAME"Data definitions created\n"); // SimConnect Requests hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_EMPTY_WEIGHT, DATA_DEFINITION_EMPTY_WEIGHT, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request empty weight, terminating.\n"); return; } hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_PAX, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request payload pax, terminating.\n"); return; } hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_F, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request payload f, terminating.\n"); return; } hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_FUEL, DATA_DEFINITION_FUEL, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request fuel, terminating.\n"); return; } hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_GSX, DATA_DEFINITION_GSX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request GSX, terminating.\n"); return; } hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_USER_DATA, DATA_DEFINITION_USER_DATA, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request user data, terminating.\n"); return; } log(stdout, MODULE_NAME"Requests created.\n"); hr = SimConnect_CallDispatch(simConnect, MyDispatchProc, nullptr); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not set dispatch proc, terminating.\n"); return; } log(stdout, MODULE_NAME"Callback created.\n"); #pragma endregion // CommBus if (!fsCommBusRegister(COMM_BUS_UPDATE_TARGET_EVENT, commBusUpdateTargetCallback)) { log(stderr, MODULE_NAME"Could not register CommBus, terminating.\n"); return; } else { log(stdout, MODULE_NAME"CommBus registered.\n"); } // Options FILE* optionsFile = fopen("\\work\\options.json", "rb"); if (optionsFile != NULL) { char readBuffer[256]; rapidjson::FileReadStream is(optionsFile, readBuffer, sizeof(readBuffer)); rapidjson::Document optionsDoc; optionsDoc.ParseStream(is); if (optionsDoc.HasMember("GSXSync")) UserOptions->GSXSync = optionsDoc["GSXSync"].GetBool(); if (optionsDoc.HasMember("paxWeightKG")) UserOptions->paxWeightKG = optionsDoc["paxWeightKG"].GetDouble(); if (optionsDoc.HasMember("bagWeightKG")) UserOptions->bagWeightKG = optionsDoc["bagWeightKG"].GetDouble(); if (optionsDoc.HasMember("paxWeightLBS")) UserOptions->paxWeightLBS = optionsDoc["paxWeightLBS"].GetDouble(); if (optionsDoc.HasMember("bagWeightLBS")) UserOptions->bagWeightLBS = optionsDoc["bagWeightLBS"].GetDouble(); fclose(optionsFile); log(stdout, MODULE_NAME"Options loaded.\n"); } else { log(stdout, MODULE_NAME"Options file not present, skip.\n"); } log(stdout, MODULE_NAME"Initialized.\n"); } // Deinit extern "C" MSFS_CALLBACK void module_deinit(void) { HRESULT hr; hr = SimConnect_Close(simConnect); if (hr != S_OK) { log(stderr, MODULE_NAME"Failed to close SimConnect.\n"); } log(stdout, MODULE_NAME"SimConnect closed.\n"); delete UserData; delete GSXData; delete livePaxPayloadData; delete targetPaxPayloadData; delete liveFPayloadData; delete targetFPayloadData; delete liveFuelData; log(stdout, MODULE_NAME"Global memory released.\n"); fsCommBusUnregister(COMM_BUS_UPDATE_TARGET_EVENT, commBusUpdateTargetCallback); log(stdout, MODULE_NAME"CommBus unregistered.\n"); // Options rapidjson::Document optionsDoc; rapidjson::Document::AllocatorType& allocator = optionsDoc.GetAllocator(); optionsDoc.SetObject(); optionsDoc.AddMember("GSXSync", UserOptions->GSXSync, allocator); optionsDoc.AddMember("paxWeightKG", UserOptions->paxWeightKG, allocator); optionsDoc.AddMember("bagWeightKG", UserOptions->bagWeightKG, allocator); optionsDoc.AddMember("paxWeightLBS", UserOptions->paxWeightLBS, allocator); optionsDoc.AddMember("bagWeightLBS", UserOptions->bagWeightLBS, allocator); FILE* optionsFile = fopen("\\work\\options.json", "wb"); if (optionsFile != NULL) { char writeBuffer[256]; rapidjson::FileWriteStream os(optionsFile, writeBuffer, sizeof(writeBuffer)); rapidjson::Writer writer(os); optionsDoc.Accept(writer); fclose(optionsFile); log(stdout, MODULE_NAME"Options written.\n"); } else { log(stdout, MODULE_NAME"Filed to open options file for write, skip.\n"); } log(stdout, MODULE_NAME"Deinitialized.\n"); } // Main loop extern "C" MSFS_CALLBACK bool Load_Manager_gauge_callback(FsContext ctx, int service_id, void* pData) { switch (service_id) { case PANEL_SERVICE_PRE_UPDATE: { lookup_var(&tick18); if (fmod(tick18.var_value.n, 3) == 0) sendData(); } default: break; } return true; } // CommBus void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx) { printf("Target payload update request: %d", receiveData(args)); } #pragma region JSON data handling // JSON receive int receiveData(const char* buf) { if (liveFPayloadData == nullptr || livePaxPayloadData == nullptr || targetFPayloadData == nullptr || targetPaxPayloadData == nullptr || liveFuelData == nullptr || UserData == nullptr) return 0; rapidjson::Document document; document.Parse(buf); if (document.HasParseError()) return document.GetParseError(); if (document.HasMember("mode")) { int mode = document["mode"].GetUint(); switch(mode) { // SB Entry case 0: { if (!document.HasMember("cargo") || !document.HasMember("CGTarget") || !document.HasMember("plannedZFW") || !document.HasMember("plannedGW")) return -1; unsigned int cargo = document["cargo"].GetInt(); double CGTarget = document["CGTarget"].GetDouble(); if (UserData->isCargo) { targetFPayloadData->CGTarget = CGTarget; targetFPayloadData->sbPlanned.ZFW = document["plannedZFW"].GetDouble(); targetFPayloadData->sbPlanned.GW = document["plannedGW"].GetDouble(); distribute(targetFPayloadData, liveFuelData, cargo, UserData->isImperial, UserData->isER); } else { if (!document.HasMember("numPax")) return -1; unsigned short numPax = document["numPax"].GetInt(); targetPaxPayloadData->CGTarget = CGTarget; targetPaxPayloadData->sbPlanned.ZFW = document["plannedZFW"].GetDouble(); targetPaxPayloadData->sbPlanned.GW = document["plannedGW"].GetDouble(); distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, UserData->isImperial, UserData->isER); } break; } // ZFW Entry case 1: { if (!document.HasMember("ZFWTarget") || !document.HasMember("CGTarget")) return -1; double ZFWTarget = document["ZFWTarget"].GetDouble(); double CGTarget = document["CGTarget"].GetDouble(); if (UserData->isCargo) { targetFPayloadData->CGTarget = CGTarget; distribute(targetFPayloadData, liveFuelData, ZFWTarget, UserData->isImperial, UserData->isER); } else { targetPaxPayloadData->CGTarget = CGTarget; distribute(targetPaxPayloadData, liveFuelData, ZFWTarget, UserData->isImperial, UserData->isER); } break; } // Station Entry case 2: { if (UserData->isCargo) { if (!document.HasMember("upper1") || !document.HasMember("upper2") || !document.HasMember("upper3") || !document.HasMember("upper4") || !document.HasMember("lowerForward") || !document.HasMember("lowerRear")) return -1; targetFPayloadData->stations.upper1 = document["upper1"].GetInt(); targetFPayloadData->stations.upper2 = document["upper2"].GetInt(); targetFPayloadData->stations.upper3 = document["upper3"].GetInt(); targetFPayloadData->stations.upper4 = document["upper4"].GetInt(); targetFPayloadData->lowerForward = document["lowerForward"].GetDouble(); targetFPayloadData->lowerRear = document["lowerRear"].GetDouble(); generatePayload(targetFPayloadData, UserData->isImperial); } else { if (!document.HasMember("business1") || !document.HasMember("business2") || !document.HasMember("economy1") || !document.HasMember("economy2") || !document.HasMember("forwardCargo") || !document.HasMember("rearCargo")) return -1; targetPaxPayloadData->paxCount.business1 = document["business1"].GetInt(); targetPaxPayloadData->paxCount.business2 = document["business2"].GetInt(); targetPaxPayloadData->paxCount.economy1 = document["economy1"].GetInt(); targetPaxPayloadData->paxCount.economy2 = document["economy2"].GetInt(); targetPaxPayloadData->forwardCargo = document["forwardCargo"].GetDouble(); targetPaxPayloadData->rearCargo = document["rearCargo"].GetDouble(); generatePayload(targetPaxPayloadData, UserData->isImperial); } break; } // Trigger load case 3: { if (UserData->isCargo) { load(targetFPayloadData, simConnect, UserData->isImperial); } else { load(targetPaxPayloadData, simConnect, UserData->isImperial); } break; } // Trigger unload case 4: { if (UserData->isCargo) { unloadF(simConnect, UserData->isER); } else { unload(simConnect, UserData->isER); } break; } // Option set case 5: { if (document.HasMember("GSXSync")) { UserOptions->GSXSync = document["GSXSync"].GetBool(); } rapidjson::Document optionsDoc; rapidjson::Document::AllocatorType& allocator = optionsDoc.GetAllocator(); optionsDoc.SetObject(); optionsDoc.AddMember("GSXSync", UserOptions->GSXSync, allocator); optionsDoc.AddMember("paxWeightKG", UserOptions->paxWeightKG, allocator); optionsDoc.AddMember("bagWeightKG", UserOptions->bagWeightKG, allocator); optionsDoc.AddMember("paxWeightLBS", UserOptions->paxWeightLBS, allocator); optionsDoc.AddMember("bagWeightLBS", UserOptions->bagWeightLBS, allocator); FILE* optionsFile = fopen("\\work\\options.json", "wb"); if (optionsFile != NULL) { char writeBuffer[256]; rapidjson::FileWriteStream os(optionsFile, writeBuffer, sizeof(writeBuffer)); rapidjson::Writer writer(os); optionsDoc.Accept(writer); fclose(optionsFile); log(stdout, MODULE_NAME"Options written.\n"); } break; } default: break; } sendData(); } else return -1; return 0; } // JSON send void sendData () { if (liveFPayloadData == nullptr || livePaxPayloadData == nullptr || targetFPayloadData == nullptr || targetPaxPayloadData == nullptr || liveFuelData == nullptr || UserData == nullptr || GSXData == nullptr) return; rapidjson::Document document; rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); document.SetObject(); rapidjson::Value livePayload; livePayload.SetObject(); rapidjson::Value targetPayload; targetPayload.SetObject(); rapidjson::Value GSX; GSX.SetObject(); rapidjson::Value userData; userData.SetObject(); rapidjson::Value limits; limits.SetObject(); rapidjson::Value options; options.SetObject(); rapidjson::Value sbPlanned; sbPlanned.SetObject(); rapidjson::StringBuffer strbuf; rapidjson::Writer writer(strbuf); #pragma region Live Payload // OEW (empty + aux tank wgts) livePayload.AddMember("empty", FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->empty : livePaxPayloadData->empty) + FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->leftAux : livePaxPayloadData->leftAux) + FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->rightAux : livePaxPayloadData->rightAux), allocator); // Cargo only if (UserData->isCargo) { livePayload.AddMember("crew", FROM_POUNDS(UserData->isImperial, liveFPayloadData->pilot) + FROM_POUNDS(UserData->isImperial, liveFPayloadData->firstOfficer) + FROM_POUNDS(UserData->isImperial, liveFPayloadData->engineer), allocator); livePayload.AddMember("upper1", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper1Left + liveFPayloadData->upper1Right), allocator); livePayload.AddMember("upper2", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper2Left + liveFPayloadData->upper2Right), allocator); livePayload.AddMember("upper3", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper3Left + liveFPayloadData->upper3Right), allocator); livePayload.AddMember("upper4", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper4Left + liveFPayloadData->upper4Right), allocator); livePayload.AddMember("lowerForward", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerForward), allocator); livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator); livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, liveFPayloadData->total), allocator); // CGs calculateCGs(liveFPayloadData, liveFuelData, &liveFPayloadData->ZFWCG, &liveFPayloadData->TOCG, true); livePayload.AddMember("ZFWCG", liveFPayloadData->ZFWCG, allocator); livePayload.AddMember("TOCG", liveFPayloadData->TOCG, allocator); } // Pax only (converted to passengers) else { livePayload.AddMember("crew", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->pilot) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->firstOfficer) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->engineer) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewFront) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewRear), allocator); livePayload.AddMember("business1", (short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->business1Left + livePaxPayloadData->business1Center + livePaxPayloadData->business1Right) / PAX_WEIGHT(UserData->isImperial)), allocator); livePayload.AddMember("business2", (short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->business2Left + livePaxPayloadData->business2Center + livePaxPayloadData->business2Right) / PAX_WEIGHT(UserData->isImperial)), allocator); livePayload.AddMember("economy1", (short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->economy1Left + livePaxPayloadData->economy1Center + livePaxPayloadData->economy1Right) / PAX_WEIGHT(UserData->isImperial)), allocator); livePayload.AddMember("economy2", (short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->economy2Left + livePaxPayloadData->economy2Center + livePaxPayloadData->economy2Right) / PAX_WEIGHT(UserData->isImperial)), allocator); livePayload.AddMember("forwardCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->forwardCargo), allocator); livePayload.AddMember("rearCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->rearCargo), allocator); livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->total), allocator); // CGs calculateCGs(livePaxPayloadData, liveFuelData, &livePaxPayloadData->ZFWCG, &livePaxPayloadData->TOCG, true); livePayload.AddMember("ZFWCG",livePaxPayloadData->ZFWCG, allocator); livePayload.AddMember("TOCG", livePaxPayloadData->TOCG, allocator); } // Fuel livePayload.AddMember("fuel", FROM_POUNDS(UserData->isImperial, liveFuelData->total), allocator); #pragma endregion #pragma region Target Payload // OEW (empty + aux tank wgts) targetPayload.AddMember("empty", (UserData->isCargo ? targetFPayloadData->empty : targetPaxPayloadData->empty)+ (UserData->isCargo ? targetFPayloadData->leftAux : targetPaxPayloadData->leftAux) + (UserData->isCargo ? targetFPayloadData->rightAux : targetPaxPayloadData->rightAux), allocator); // Cargo only if (UserData->isCargo) { targetPayload.AddMember("crew", targetFPayloadData->pilot + targetFPayloadData->firstOfficer + targetFPayloadData->engineer, allocator); targetPayload.AddMember("upper1", targetFPayloadData->upper1Left + targetFPayloadData->upper1Right, allocator); targetPayload.AddMember("upper2", targetFPayloadData->upper2Left + targetFPayloadData->upper2Right, allocator); targetPayload.AddMember("upper3", targetFPayloadData->upper3Left + targetFPayloadData->upper3Right, allocator); targetPayload.AddMember("upper4", targetFPayloadData->upper4Left + targetFPayloadData->upper4Right, allocator); targetPayload.AddMember("lowerForward", targetFPayloadData->lowerForward, allocator); targetPayload.AddMember("lowerRear", targetFPayloadData->lowerRear, allocator); targetPayload.AddMember("total", targetFPayloadData->total, allocator); targetPayload.AddMember("CGTarget", targetFPayloadData->CGTarget, allocator); // CGs calculateCGs(targetFPayloadData, liveFuelData, &targetFPayloadData->ZFWCG, &targetFPayloadData->TOCG, UserData->isImperial); targetPayload.AddMember("ZFWCG", targetFPayloadData->ZFWCG, allocator); targetPayload.AddMember("TOCG", targetFPayloadData->TOCG, allocator); } // Pax only (converted to passengers) else { targetPayload.AddMember("crew", targetPaxPayloadData->pilot + targetPaxPayloadData->firstOfficer + targetPaxPayloadData->engineer + targetPaxPayloadData->cabinCrewFront + targetPaxPayloadData->cabinCrewRear, allocator); targetPayload.AddMember("business1", targetPaxPayloadData->paxCount.business1, allocator); targetPayload.AddMember("business2", targetPaxPayloadData->paxCount.business2, allocator); targetPayload.AddMember("economy1", targetPaxPayloadData->paxCount.economy1, allocator); targetPayload.AddMember("economy2", targetPaxPayloadData->paxCount.economy2, allocator); targetPayload.AddMember("forwardCargo", targetPaxPayloadData->forwardCargo, allocator); targetPayload.AddMember("rearCargo", targetPaxPayloadData->rearCargo, allocator); targetPayload.AddMember("total", targetPaxPayloadData->total, allocator); targetPayload.AddMember("CGTarget", targetPaxPayloadData->CGTarget, allocator); // CGs calculateCGs(targetPaxPayloadData, liveFuelData, &targetPaxPayloadData->ZFWCG, &targetPaxPayloadData->TOCG, UserData->isImperial); targetPayload.AddMember("ZFWCG", targetPaxPayloadData->ZFWCG, allocator); targetPayload.AddMember("TOCG", targetPaxPayloadData->TOCG, allocator); } #pragma endregion // GSX GSX.AddMember("boardingState", GSXData->boardingState, allocator); GSX.AddMember("deboardingState", GSXData->deboardingState, allocator); // User Data userData.AddMember("isCargo", UserData->isCargo, allocator); userData.AddMember("isER", UserData->isER, allocator); userData.AddMember("isImperial", UserData->isImperial, allocator); // Limits limits.AddMember("minCG", MIN_CG, allocator); limits.AddMember("maxCG", MAX_CG, allocator); limits.AddMember("maxFuel", UserData->isER ? MAX_FUEL_ER(UserData->isImperial) : MAX_FUEL(UserData->isImperial), allocator); limits.AddMember("maxTOW", UserData->isER ? MAX_TOW_ER(UserData->isImperial) : MAX_TOW(UserData->isImperial), allocator); // Cargo Only if (UserData->isCargo) { limits.AddMember("upper1", MAX_UPPER_CARGO(UserData->isImperial), allocator); limits.AddMember("upper2", MAX_UPPER_CARGO(UserData->isImperial), allocator); limits.AddMember("upper3", MAX_UPPER_CARGO(UserData->isImperial), allocator); limits.AddMember("upper4", MAX_UPPER_CARGO(UserData->isImperial), allocator); limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator); limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator); limits.AddMember("maxZFW", MAX_F_ZFW(UserData->isImperial), allocator); limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator); } // Pax only else { limits.AddMember("business1", MAX_BUSINESS_1, allocator); limits.AddMember("business2", MAX_BUSINESS_2, allocator); limits.AddMember("economy1", MAX_ECONOMY_1, allocator); limits.AddMember("economy2", MAX_ECONOMY_2, allocator); limits.AddMember("forwardCargo", MAX_FRONT_CARGO(UserData->isImperial), allocator); limits.AddMember("rearCargo", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator); limits.AddMember("maxZFW", MAX_PAX_ZFW(UserData->isImperial), allocator); limits.AddMember("minZFW", targetPaxPayloadData->empty + targetPaxPayloadData->leftAux + targetPaxPayloadData->rightAux, allocator); } // Options options.AddMember("GSXSync", UserOptions->GSXSync, allocator); options.AddMember("paxWeight", UserData->isImperial ? UserOptions->paxWeightLBS : UserOptions->paxWeightKG, allocator); options.AddMember("bagWeight", UserData->isImperial ? UserOptions->bagWeightLBS : UserOptions->bagWeightKG, allocator); // SB Planned sbPlanned.AddMember("ZFW", UserData->isCargo ? targetFPayloadData->sbPlanned.ZFW: targetPaxPayloadData->sbPlanned.ZFW, allocator); sbPlanned.AddMember("GW", UserData->isCargo ? targetFPayloadData->sbPlanned.GW : targetPaxPayloadData->sbPlanned.GW, allocator); // Construct document document.AddMember("livePayload", livePayload.Move(), allocator); document.AddMember("targetPayload", targetPayload.Move(), allocator); document.AddMember("GSX", GSX.Move(), allocator); document.AddMember("userData", userData.Move(), allocator); document.AddMember("limits", limits.Move(), allocator); document.AddMember("options", options.Move(), allocator); document.AddMember("sbPlanned", sbPlanned.Move(), allocator); // Write to CommBus document.Accept(writer); fsCommBusCall(COMM_BUS_LIVE_DATA_EVENT, strbuf.GetString(), strbuf.GetSize(), FsCommBusBroadcast_JS); } #pragma endregion // Logfile void log(FILE* file, const char* format, void* optionalElement) { if (logFile != NULL) { fprintf(logFile, format, optionalElement); fflush(logFile); } fprintf(file, format, optionalElement); } // SimConnect void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) { switch (pData->dwID) { case SIMCONNECT_RECV_ID_SIMOBJECT_DATA: { SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData; switch (pObjData->dwRequestID) { case DATA_REQUEST_EMPTY_WEIGHT: { liveFPayloadData->empty = livePaxPayloadData->empty = *((double*)&pObjData->dwData); break; } case DATA_REQUEST_PAYLOAD_F: { fPayloadData_t* data = (fPayloadData_t*)&pObjData->dwData; data->empty = liveFPayloadData->empty; memcpy(liveFPayloadData, data, sizeof(fPayloadData_t)); liveFPayloadData->total = liveFPayloadData->empty + liveFPayloadData->pilot + liveFPayloadData->firstOfficer + liveFPayloadData->engineer + liveFPayloadData->upper1Left + liveFPayloadData->upper1Right + liveFPayloadData->upper2Left + liveFPayloadData->upper2Right + liveFPayloadData->upper3Left + liveFPayloadData->upper3Right + liveFPayloadData->upper4Left + liveFPayloadData->upper4Right + liveFPayloadData->lowerForward + liveFPayloadData->lowerRear + liveFPayloadData->leftAux + liveFPayloadData->rightAux; break; } case DATA_REQUEST_PAYLOAD_PAX: { paxPayloadData_t* data = (paxPayloadData_t*)&pObjData->dwData; data->empty = livePaxPayloadData->empty; memcpy(livePaxPayloadData, data, sizeof(paxPayloadData_t)); livePaxPayloadData->total = livePaxPayloadData->empty + livePaxPayloadData->pilot + livePaxPayloadData->firstOfficer + livePaxPayloadData->engineer + livePaxPayloadData->cabinCrewFront + livePaxPayloadData->business1Left + livePaxPayloadData->business1Center + livePaxPayloadData->business1Right + livePaxPayloadData->business2Left + livePaxPayloadData->business2Center + livePaxPayloadData->business2Right + livePaxPayloadData->economy1Left + livePaxPayloadData->economy1Center + livePaxPayloadData->economy1Right + livePaxPayloadData->economy2Left + livePaxPayloadData->economy2Center + livePaxPayloadData->economy2Right + livePaxPayloadData->cabinCrewRear + livePaxPayloadData->forwardCargo + livePaxPayloadData->rearCargo + livePaxPayloadData->leftAux + livePaxPayloadData->rightAux; break; } case DATA_REQUEST_FUEL: { FuelData_t* data = (FuelData_t*)&pObjData->dwData; liveFuelData->main1 = data->main1 * data->poundsPerGallon; liveFuelData->main3 = data->main3 * data->poundsPerGallon; liveFuelData->main2 = data->main2 * data->poundsPerGallon; liveFuelData->upperAux = data->upperAux * data->poundsPerGallon; liveFuelData->lowerAux = data->lowerAux * data->poundsPerGallon; liveFuelData->main1Tip = data->main1Tip * data->poundsPerGallon; liveFuelData->main3Tip = data->main3Tip * data->poundsPerGallon; liveFuelData->tail = data->tail * data->poundsPerGallon; liveFuelData->forwardAux1 = data->forwardAux1 * data->poundsPerGallon; liveFuelData->forwardAux2 = data->forwardAux2 * data->poundsPerGallon; liveFuelData->total = liveFuelData->main1 + liveFuelData->main3 + liveFuelData->main2 + liveFuelData->upperAux + liveFuelData->lowerAux + liveFuelData->main1Tip + liveFuelData->main3Tip + liveFuelData->tail + liveFuelData->forwardAux1 + liveFuelData->forwardAux2; break; } case DATA_REQUEST_GSX: { GSXData_t* data = (GSXData_t*)&pObjData->dwData; memcpy(GSXData, data, sizeof(GSXData_t)); if (UserOptions->GSXSync) { if (GSXData->boardingState == GSX_SERVICE_ACTIVE) { double cargoBoarded = GSXData->cargoBoarded; if (UserData->isCargo) { fPayloadData_t localPayload = {}; memcpy(&localPayload, targetFPayloadData, sizeof(localPayload)); localPayload.stations.upper1 = targetFPayloadData->stations.upper1 * (cargoBoarded / 100); localPayload.stations.upper2 = targetFPayloadData->stations.upper2 * (cargoBoarded / 100); localPayload.stations.upper3 = targetFPayloadData->stations.upper3 * (cargoBoarded / 100); localPayload.stations.upper4 = targetFPayloadData->stations.upper4 * (cargoBoarded / 100); localPayload.lowerForward = targetFPayloadData->lowerForward * (cargoBoarded / 100); localPayload.lowerRear = targetFPayloadData->lowerRear * (cargoBoarded / 100); generatePayload(&localPayload, UserData->isImperial); load(&localPayload, simConnect, UserData->isImperial); } else { double passengersBoarded = GSXData->passengersBoarded; paxPayloadData_t localPayload = {}; memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload)); localPayload.paxCount.business1 = min(targetPaxPayloadData->paxCount.business1, passengersBoarded); passengersBoarded -= localPayload.paxCount.business1; localPayload.paxCount.business2 = min(targetPaxPayloadData->paxCount.business2, passengersBoarded); passengersBoarded -= localPayload.paxCount.business2; localPayload.paxCount.economy1 = min(targetPaxPayloadData->paxCount.economy1, passengersBoarded); passengersBoarded -= localPayload.paxCount.economy1; localPayload.paxCount.economy2 = min(targetPaxPayloadData->paxCount.economy2, passengersBoarded); passengersBoarded -= localPayload.paxCount.economy2; localPayload.forwardCargo = targetPaxPayloadData->forwardCargo * (cargoBoarded / 100); localPayload.rearCargo = targetPaxPayloadData->rearCargo * (cargoBoarded / 100); generatePayload(&localPayload, UserData->isImperial); load(&localPayload, simConnect, UserData->isImperial); } } if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) { double cargoDeboarded = GSXData->cargoDeboarded; if (UserData->isCargo) { fPayloadData_t localPayload = {}; memcpy(&localPayload, targetFPayloadData, sizeof(localPayload)); localPayload.stations.upper1 -= targetFPayloadData->stations.upper1 * (cargoDeboarded / 100); localPayload.stations.upper2 -= targetFPayloadData->stations.upper2 * (cargoDeboarded / 100); localPayload.stations.upper3 -= targetFPayloadData->stations.upper3 * (cargoDeboarded / 100); localPayload.stations.upper4 -= targetFPayloadData->stations.upper4 * (cargoDeboarded / 100); localPayload.lowerForward -= targetFPayloadData->lowerForward * (cargoDeboarded / 100); localPayload.lowerRear -= targetFPayloadData->lowerRear * (cargoDeboarded / 100); generatePayload(&localPayload, UserData->isImperial); load(&localPayload, simConnect, UserData->isImperial); } else { double passengersDeboarded = GSXData->passengersDeboarded; paxPayloadData_t localPayload = {}; memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload)); localPayload.paxCount.business1 -= min(targetPaxPayloadData->paxCount.business1, passengersDeboarded); passengersDeboarded -= targetPaxPayloadData->paxCount.business1 - localPayload.paxCount.business1; localPayload.paxCount.business2 -= min(targetPaxPayloadData->paxCount.business2, passengersDeboarded); passengersDeboarded -= targetPaxPayloadData->paxCount.business2 - localPayload.paxCount.business2; localPayload.paxCount.economy1 -= min(targetPaxPayloadData->paxCount.economy1, passengersDeboarded); passengersDeboarded -= targetPaxPayloadData->paxCount.economy1 - localPayload.paxCount.economy1; localPayload.paxCount.economy2 -= min(targetPaxPayloadData->paxCount.economy2, passengersDeboarded); passengersDeboarded -= targetPaxPayloadData->paxCount.economy2 - localPayload.paxCount.economy2; localPayload.forwardCargo -= targetPaxPayloadData->forwardCargo * (cargoDeboarded / 100); localPayload.rearCargo -= targetPaxPayloadData->rearCargo * (cargoDeboarded / 100); generatePayload(&localPayload, UserData->isImperial); load(&localPayload, simConnect, UserData->isImperial); } } } break; } case DATA_REQUEST_USER_DATA: { UserData_t* data = (UserData_t*)&pObjData->dwData; data->isImperial = ((long)data->isImperial) & 1; memcpy(UserData, data, sizeof(UserData_t)); // Update static weights // Shared part 1 targetFPayloadData->empty = targetPaxPayloadData->empty = FROM_POUNDS(UserData->isImperial, liveFPayloadData->empty); targetFPayloadData->pilot = targetPaxPayloadData->pilot = targetFPayloadData->firstOfficer = targetPaxPayloadData->firstOfficer = targetFPayloadData->engineer = targetPaxPayloadData->engineer = PILOT_WEIGHT(UserData->isImperial); // Shared part 2 targetFPayloadData->leftAux = targetPaxPayloadData->leftAux = targetFPayloadData->rightAux = targetPaxPayloadData->rightAux = UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0; // Pax only fixed weights if (!UserData->isCargo) { targetPaxPayloadData->cabinCrewFront = FRONT_CREW_WEIGHT(UserData->isImperial); targetPaxPayloadData->cabinCrewRear = REAR_CREW_WEIGHT(UserData->isImperial); } break; } default: { break; } } break; } case SIMCONNECT_RECV_ID_EXCEPTION: { SIMCONNECT_RECV_EXCEPTION* pEx = (SIMCONNECT_RECV_EXCEPTION*)pData; log(stderr, MODULE_NAME"SimConnect Exception: %i\n", &pEx->dwException); break; } default: { break; } } }