#include "scheduler.h" #include "logger.h" #include "dcstools.h" #include "unitsManager.h" #include "utils.h" #include "unit.h" extern UnitsManager* unitsManager; Scheduler::Scheduler(lua_State* L) { LogInfo(L, "Scheduler constructor called successfully"); } Scheduler::~Scheduler() { } /* Appends a */ void Scheduler::appendCommand(Command* newCommand) { for (auto command : commands) { if (command->getString().compare(newCommand->getString()) == 0 && command->getPriority() == newCommand->getPriority()) return; } commands.push_back(newCommand); } int Scheduler::getLoad() { int currentLoad = 0; for (auto command : commands) { currentLoad += command->getLoad(); } return currentLoad; } void Scheduler::execute(lua_State* L) { /* Decrease the active computation load. New commands can be sent only if the load has reached 0. This is needed to avoid server lag. */ if (load > 0) { load--; return; } int priority = CommandPriority::IMMEDIATE; while (priority >= CommandPriority::LOW) { for (auto command : commands) { if (command->getPriority() == priority) { string commandString = "Olympus.protectedCall(" + command->getString() + ")"; string resultString = ""; if (dostring_in(L, "server", (commandString), resultString)) log("Error executing command " + commandString); else log("Command '" + commandString + "' executed correctly, current load " + to_string(getLoad()) + ", result string: " + resultString); /* Adjust the load depending on the fps */ double fpsMultiplier = 20; if (getFrameRate() + 3 > 0) fpsMultiplier = static_cast(max(1, 60 / (getFrameRate() + 3))); /* Multiplier between 1 and 20 */ load = static_cast(command->getLoad() * fpsMultiplier); commands.remove(command); CommandResult commandResult = { command->getHash(), resultString }; executedCommandResults.push_back(commandResult); command->executeCallback(); /* Execute the command callback (this is a lambda function that can be used to execute a function when the command is run) */ delete command; return; } } priority--; }; } void Scheduler::setCommandModeOptions(json::value value) { if (value.has_boolean_field(L"restrictSpawns")) setRestrictSpawns(value[L"restrictSpawns"].as_bool()); if (value.has_boolean_field(L"restrictToCoalition")) setRestrictToCoalition(value[L"restrictToCoalition"].as_bool()); if (value.has_number_field(L"setupTime")) setSetupTime(value[L"setupTime"].as_number().to_int32()); if (value.has_object_field(L"spawnPoints")) { if (value[L"spawnPoints"].has_number_field(L"blue")) setBlueSpawnPoints(value[L"spawnPoints"][L"blue"].as_number().to_int32()); if (value[L"spawnPoints"].has_number_field(L"red")) setRedSpawnPoints(value[L"spawnPoints"][L"red"].as_number().to_int32()); } if (value.has_array_field(L"eras")) { int length = static_cast(value[L"eras"].as_array().size()); vector newEras; for (int idx = 0; idx < length; idx++) newEras.push_back(to_string(value[L"eras"].as_array().at(idx))); setEras(newEras); } } json::value Scheduler::getCommandModeOptions() { json::value json = json::value::object(); json[L"restrictSpawns"] = json::value(getRestrictSpawns()); json[L"restrictToCoalition"] = json::value(getRestrictToCoalition()); json[L"setupTime"] = json::value(getSetupTime()); json[L"spawnPoints"] = json::value::object(); json[L"spawnPoints"][L"blue"] = json::value(getBlueSpawnPoints()); json[L"spawnPoints"][L"red"] = json::value(getRedSpawnPoints()); int idx = 0; json[L"eras"] = json::value::array(); for (string era : getEras()) json[L"eras"][idx++] = json::value(to_wstring(era)); return json; } bool Scheduler::checkSpawnPoints(int spawnPoints, string coalition) { if (!getRestrictSpawns()) return true; if (coalition.compare("blue") == 0) { if (getBlueSpawnPoints() - spawnPoints >= 0) { setBlueSpawnPoints(getBlueSpawnPoints() - spawnPoints); return true; } else { log("Not enough blue coalition spawn points available. Available: " + to_string(getBlueSpawnPoints()) + ", required: " + to_string(spawnPoints)); return false; } } else if (coalition.compare("red") == 0) { if (getRedSpawnPoints() - spawnPoints >= 0) { setRedSpawnPoints(getRedSpawnPoints() - spawnPoints); return true; } else { log("Not enough red coalition spawn points available. Available: " + to_string(getRedSpawnPoints()) + ", required: " + to_string(spawnPoints)); return false; } } return false; } void Scheduler::handleRequest(string key, json::value value, string username, json::value& answer) { Command* command = nullptr; log("Received request with ID: " + key); log(L"Incoming command raw value: " + value.serialize()); /************************/ if (key.compare("setPath") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { json::value path = value[L"path"]; list newPath; for (unsigned int i = 0; i < path.as_array().size(); i++) { string WP = to_string(i); double lat = path[i][L"lat"].as_double(); double lng = path[i][L"lng"].as_double(); if (path[i].has_number_field(L"threshold")) { double threshold = path[i][L"threshold"].as_double(); Coords dest; dest.lat = lat; dest.lng = lng; dest.threshold = threshold; newPath.push_back(dest); continue; } Coords dest; dest.lat = lat; dest.lng = lng; newPath.push_back(dest); } unit->setActivePath(newPath); unit->setState(State::REACH_DESTINATION); log(username + " updated destination path for unit " + unit->getUnitName() + "(" + unit->getName() + ")", true); } } /************************/ else if (key.compare("smoke") == 0) { string color = to_string(value[L"color"]); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; command = dynamic_cast(new Smoke(color, loc)); log(username + " added a " + color + " smoke at (" + to_string(lat) + ", " + to_string(lng) + ")", true); } /************************/ else if (key.compare("spawnAircrafts") == 0 || key.compare("spawnHelicopters") == 0) { bool immediate = value[L"immediate"].as_bool(); string coalition = to_string(value[L"coalition"]); string airbaseName = to_string(value[L"airbaseName"]); string country = to_string(value[L"country"]); int spawnPoints = value[L"spawnPoints"].as_number().to_int32(); if (!checkSpawnPoints(spawnPoints, coalition)) { log(username + " insufficient spawn points ", true); return; } vector spawnOptions; for (auto unit : value[L"units"].as_array()) { string unitType = to_string(unit[L"unitType"]); double lat = unit[L"location"][L"lat"].as_double(); double lng = unit[L"location"][L"lng"].as_double(); double alt = unit[L"altitude"].as_double(); double heading = 0; if (unit.has_number_field(L"heading")) heading = unit[L"heading"].as_double(); Coords location; location.lat = lat; location.lng = lng; location.alt = alt; string loadout = to_string(unit[L"loadout"]); string liveryID = to_string(unit[L"liveryID"]); string skill = to_string(unit[L"skill"]); string payload = "nil"; if (unit.has_string_field(L"payload")) payload = to_string(unit[L"payload"]); spawnOptions.push_back({ unitType, location, loadout, skill, liveryID, heading, payload }); log(username + " spawned a " + coalition + " " + unitType, true); } if (key.compare("spawnAircrafts") == 0) command = dynamic_cast(new SpawnAircrafts(coalition, spawnOptions, airbaseName, country, immediate)); else command = dynamic_cast(new SpawnHelicopters(coalition, spawnOptions, airbaseName, country, immediate)); } /************************/ else if (key.compare("spawnGroundUnits") == 0 || key.compare("spawnNavyUnits") == 0) { bool immediate = value[L"immediate"].as_bool(); string coalition = to_string(value[L"coalition"]); string country = to_string(value[L"country"]); int spawnPoints = value[L"spawnPoints"].as_number().to_int32(); if (!checkSpawnPoints(spawnPoints, coalition)) { log(username + " insufficient spawn points ", true); return; } vector spawnOptions; for (auto unit : value[L"units"].as_array()) { string unitType = to_string(unit[L"unitType"]); double lat = unit[L"location"][L"lat"].as_double(); double lng = unit[L"location"][L"lng"].as_double(); double heading = 0; if (unit.has_number_field(L"heading")) heading = unit[L"heading"].as_double(); Coords location; location.lat = lat; location.lng = lng; string liveryID = to_string(unit[L"liveryID"]); string skill = to_string(unit[L"skill"]); spawnOptions.push_back({ unitType, location, "", skill, liveryID, heading }); log(username + " spawned a " + coalition + " " + unitType, true); } if (key.compare("spawnGroundUnits") == 0) command = dynamic_cast(new SpawnGroundUnits(coalition, spawnOptions, country, immediate)); else command = dynamic_cast(new SpawnNavyUnits(coalition, spawnOptions, country, immediate)); } /************************/ else if (key.compare("attackUnit") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); unsigned int targetID = value[L"targetID"].as_integer(); Unit* unit = unitsManager->getGroupLeader(ID); Unit* target = unitsManager->getUnit(targetID); if (unit != nullptr && target != nullptr) { log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to attack unit " + target->getUnitName() + "(" + target->getName() + ")", true); unit->setTargetID(targetID); unit->setState(State::ATTACK); } } /************************/ else if (key.compare("followUnit") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); unsigned int leaderID = value[L"targetID"].as_integer(); double offsetX = value[L"offsetX"].as_double(); double offsetY = value[L"offsetY"].as_double(); double offsetZ = value[L"offsetZ"].as_double(); Unit* unit = unitsManager->getGroupLeader(ID); Unit* leader = unitsManager->getUnit(leaderID); if (unit != nullptr && leader != nullptr) { log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to follow unit " + leader->getUnitName() + "(" + leader->getName() + ")", true); unit->setFormationOffset(Offset(offsetX, offsetY, offsetZ)); unit->setLeaderID(leaderID); unit->setState(State::FOLLOW); } } /************************/ else if (key.compare("changeSpeed") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->changeSpeed(to_string(value[L"change"])); log(username + " changed " + unit->getUnitName() + "(" + unit->getName() + ") speed: " + to_string(value[L"change"]), true); } } /************************/ else if (key.compare("changeAltitude") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->changeAltitude(to_string(value[L"change"])); log(username + " changed " + unit->getUnitName() + "(" + unit->getName() + ") altitude: " + to_string(value[L"change"]), true); } } /************************/ else if (key.compare("setSpeed") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setDesiredSpeed(value[L"speed"].as_double()); log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") speed: " + to_string(value[L"speed"].as_double()), true); } } /************************/ else if (key.compare("setSpeedType") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setDesiredSpeedType(to_string(value[L"speedType"])); log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") speed type: " + to_string(value[L"speedType"]), true); } } /************************/ else if (key.compare("setAltitude") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setDesiredAltitude(value[L"altitude"].as_double()); log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") altitude: " + to_string(value[L"altitude"].as_double()), true); } } /************************/ else if (key.compare("setAltitudeType") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setDesiredAltitudeType(to_string(value[L"altitudeType"])); log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") altitude type: " + to_string(value[L"altitudeType"]), true); } }/************************/ else if (key.compare("setRacetrack") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setRacetrackLength(value[L"length"].as_double()); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords location; location.lat = lat; location.lng = lng; unit->setRacetrackAnchor(location); unit->setRacetrackBearing(value[L"bearing"].as_double()); log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") racetrack length: " + to_string(value[L"length"].as_double()) + " racetrack bearing: " + to_string(value[L"bearing"].as_double()), true); } } /************************/ else if (key.compare("cloneUnits") == 0) { vector cloneOptions; bool deleteOriginal = value[L"deleteOriginal"].as_bool(); string coalition = to_string(value[L"coalition"]); int spawnPoints = value[L"spawnPoints"].as_number().to_int32(); if (coalition.compare("all") != 0 && !checkSpawnPoints(spawnPoints, coalition)) { log(username + " insufficient spawn points ", true); return; } for (auto unit : value[L"units"].as_array()) { unsigned int ID = unit[L"ID"].as_integer(); double lat = unit[L"location"][L"lat"].as_double(); double lng = unit[L"location"][L"lng"].as_double(); Coords location; location.lat = lat; location.lng = lng; cloneOptions.push_back({ ID, location }); log(username + " cloning unit with ID " + to_string(ID), true); } command = dynamic_cast(new Clone(cloneOptions, deleteOriginal)); } /************************/ else if (key.compare("setROE") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char ROE = value[L"ROE"].as_number().to_uint32(); unit->setROE(ROE); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") ROE to " + to_string(ROE), true); } } else if (key.compare("setAlarmState") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char alarmState = value[L"alarmState"].as_number().to_uint32(); unit->setAlarmState(alarmState); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") alarm state to " + to_string(alarmState), true); } else { log("Error while setting setAlarmState. Unit does not exist."); } } /************************/ else if (key.compare("setReactionToThreat") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char reactionToThreat = value[L"reactionToThreat"].as_number().to_uint32(); unit->setReactionToThreat(reactionToThreat); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") reaction to threat to " + to_string(reactionToThreat), true); } } /************************/ else if (key.compare("setEmissionsCountermeasures") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char emissionsCountermeasures = value[L"emissionsCountermeasures"].as_number().to_uint32(); unit->setEmissionsCountermeasures(emissionsCountermeasures); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") emissions and countermeasures to " + to_string(emissionsCountermeasures), true); } } /************************/ else if (key.compare("landAt") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; unit->landAt(loc); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to land", true); } } /************************/ else if (key.compare("deleteUnit") == 0) { unsigned int ID = value[L"ID"].as_integer(); bool explosion = value[L"explosion"].as_bool(); string explosionType = to_string(value[L"explosionType"]); bool immediate = value[L"immediate"].as_bool(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { unitsManager->deleteUnit(ID, explosion, explosionType, immediate); log(username + " deleted unit " + unit->getUnitName() + "(" + unit->getName() + ")", true); } } /************************/ else if (key.compare("refuel") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setState(State::REFUEL); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to refuel", true); } } /************************/ else if (key.compare("setAdvancedOptions") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { /* Advanced tasking */ unit->setIsActiveTanker(value[L"isActiveTanker"].as_bool()); unit->setIsActiveAWACS(value[L"isActiveAWACS"].as_bool()); /* TACAN Options */ DataTypes::TACAN TACAN; TACAN.isOn = value[L"TACAN"][L"isOn"].as_bool(); TACAN.channel = static_cast(value[L"TACAN"][L"channel"].as_number().to_uint32()); TACAN.XY = to_string(value[L"TACAN"][L"XY"]).at(0); string callsign = to_string(value[L"TACAN"][L"callsign"]); if (callsign.length() > 3) callsign = callsign.substr(0, 3); strcpy_s(TACAN.callsign, 4, callsign.c_str()); unit->setTACAN(TACAN); /* Radio Options */ auto radio = value[L"radio"]; unit->setRadio({ radio[L"frequency"].as_number().to_uint32(), static_cast(radio[L"callsign"].as_number().to_uint32()), static_cast(radio[L"callsignNumber"].as_number().to_uint32()) }); /* General Settings */ auto generalSettings = value[L"generalSettings"]; unit->setGeneralSettings({ generalSettings[L"prohibitJettison"].as_bool(), generalSettings[L"prohibitAA"].as_bool(), generalSettings[L"prohibitAG"].as_bool(), generalSettings[L"prohibitAfterburner"].as_bool(), generalSettings[L"prohibitAirWpn"].as_bool(), }); unit->resetActiveDestination(); log(username + " updated unit " + unit->getUnitName() + "(" + unit->getName() + ") advancedOptions", true); } } /************************/ else if (key.compare("setEngagementProperties") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { /* Engagement properties tasking */ unit->setBarrelHeight(value[L"barrelHeight"].as_number().to_double()); unit->setMuzzleVelocity(value[L"muzzleVelocity"].as_number().to_double()); unit->setAimTime(value[L"aimTime"].as_number().to_double()); unit->setShotsToFire(value[L"shotsToFire"].as_number().to_uint32()); unit->setShotsBaseInterval(value[L"shotsBaseInterval"].as_number().to_double()); unit->setShotsBaseScatter(value[L"shotsBaseScatter"].as_number().to_double()); unit->setEngagementRange(value[L"engagementRange"].as_number().to_double()); unit->setTargetingRange(value[L"targetingRange"].as_number().to_double()); unit->setAimMethodRange(value[L"aimMethodRange"].as_number().to_double()); unit->setAcquisitionRange(value[L"acquisitionRange"].as_number().to_double()); log(username + " updated unit " + unit->getUnitName() + "(" + unit->getName() + ") engagementProperties", true); } } /************************/ else if (key.compare("setFollowRoads") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); bool followRoads = value[L"followRoads"].as_bool(); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setFollowRoads(followRoads); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") followRoads to: " + (followRoads ? "true" : "false"), true); } } /************************/ else if (key.compare("setOnOff") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); bool onOff = value[L"onOff"].as_bool(); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setOnOff(onOff); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") onOff to: " + (onOff ? "true" : "false"), true); } } /************************/ else if (key.compare("explosion") == 0) { unsigned int intensity = value[L"intensity"].as_integer(); string explosionType = to_string(value[L"explosionType"]); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); log("Adding explosion of type " + explosionType + " at (" + to_string(lat) + ", " + to_string(lng) + ")"); Coords loc; loc.lat = lat; loc.lng = lng; command = dynamic_cast(new Explosion(intensity, explosionType, loc)); } /************************/ else if (key.compare("bombPoint") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); unit->setState(State::BOMB_POINT); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to bomb a point", true); } } /************************/ else if (key.compare("carpetBomb") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); unit->setState(State::CARPET_BOMB); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to perform carpet bombing", true); } } /************************/ /* TODO: this command does not appear to be working in DCS and has been disabled */ else if (key.compare("bombBuilding") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); unit->setState(State::BOMB_BUILDING); } } /************************/ else if (key.compare("fireAtArea") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; if (value[L"location"].has_number_field(L"alt")) { loc.alt = value[L"location"][L"alt"].as_double(); } Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); unit->setState(State::FIRE_AT_AREA); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to fire at area", true); } } /************************/ else if (key.compare("simulateFireFight") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); double alt = value[L"altitude"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; loc.alt = alt; Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); unit->setState(State::SIMULATE_FIRE_FIGHT); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to simulate a fire fight", true); } } /************************/ else if (key.compare("scenicAAA") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setState(State::SCENIC_AAA); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to enter scenic AAA state", true); } } /************************/ else if (key.compare("missOnPurpose") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setState(State::MISS_ON_PURPOSE); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to enter Miss On Purpose state", true); } } /************************/ else if (key.compare("setOperateAs") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); unsigned char operateAs = value[L"operateAs"].as_number().to_uint32(); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) unit->setOperateAs(operateAs); } /************************/ else if (key.compare("landAtPoint") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { list newPath; newPath.push_back(loc); unit->setActivePath(newPath); unit->setState(State::LAND_AT_POINT); log(username + " tasked unit " + unit->getUnitName() + "(" + unit->getName() + ") to land at point", true); } } /************************/ else if (key.compare("setShotsScatter") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char shotsScatter = value[L"shotsScatter"].as_number().to_uint32(); unit->setShotsScatter(shotsScatter); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") shots scatter to " + to_string(shotsScatter), true); } } /************************/ else if (key.compare("setShotsIntensity") == 0) { unsigned int ID = value[L"ID"].as_integer(); unitsManager->acquireControl(ID); Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unsigned char shotsIntensity = value[L"shotsIntensity"].as_number().to_uint32(); unit->setShotsIntensity(shotsIntensity); log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") shots intensity to " + to_string(shotsIntensity), true); } } /************************/ else if (key.compare("fireLaser") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; unsigned int code = value[L"code"].as_integer(); log("Firing laser with code " + to_string(code) + " from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")"); command = dynamic_cast(new FireLaser(ID, code, loc)); } } /************************/ else if (key.compare("fireInfrared") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; log("Firing infrared from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")"); command = dynamic_cast(new FireInfrared(ID, loc)); } } /************************/ else if (key.compare("setLaserCode") == 0) { unsigned int spotID = value[L"spotID"].as_integer(); unsigned int code = value[L"code"].as_integer(); log("Setting laser code " + to_string(code) + " to spot with ID " + to_string(spotID)); command = dynamic_cast(new SetLaserCode(spotID, code)); } /************************/ else if (key.compare("moveSpot") == 0) { unsigned int spotID = value[L"spotID"].as_integer(); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; log("Moving spot with ID " + to_string(spotID) + " to (" + to_string(lat) + ", " + to_string(lng) + ")"); command = dynamic_cast(new MoveSpot(spotID, loc)); } /************************/ else if (key.compare("deleteSpot") == 0) { unsigned int spotID = value[L"spotID"].as_integer(); log("Deleting spot with ID " + to_string(spotID)); command = dynamic_cast(new DeleteSpot(spotID)); } /************************/ else if (key.compare("setCommandModeOptions") == 0) { setCommandModeOptions(value); log(username + " updated the Command Mode Options", true); } /************************/ else if (key.compare("reloadDatabases") == 0) { unitsManager->loadDatabases(); } /************************/ else if (key.compare("setCargoWeight") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { double weight = value[L"weight"].as_double(); unit->setCargoWeight(weight); log(username + " set weight to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + to_string(weight), true); } } /************************/ else if (key.compare("registerDrawArgument") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { int argument = value[L"argument"].as_integer(); bool active = value[L"active"].as_bool(); command = dynamic_cast(new RegisterDrawArgument(ID, argument, active)); log(username + " registered draw argument " + to_string(argument) + " for unit " + unit->getUnitName() + "(" + unit->getName() + "), value:" + to_string(active), true); } } /************************/ else if (key.compare("setCustomString") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { string customString = to_string(value[L"customString"]); unit->setCustomString(customString); log(username + " set custom string to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + customString, true); } } /************************/ else if (key.compare("setCustomInteger") == 0) { unsigned int ID = value[L"ID"].as_integer(); Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { double customNumber = value[L"customInteger"].as_double(); unit->setCustomInteger(customNumber); log(username + " set custom number to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + to_string(customNumber), true); } } /************************/ else { log("Unknown command: " + key); } if (command != nullptr) { appendCommand(command); log("New command appended correctly to stack. Current server load: " + to_string(getLoad())); answer[L"commandHash"] = json::value(to_wstring(command->getHash())); } }