Add basic visibility functions and ability to spawn multiple units in group

This commit is contained in:
Pax1601
2023-07-07 17:26:41 +02:00
parent 30568e54f7
commit 327d5c74d9
26 changed files with 589 additions and 348 deletions

View File

@@ -151,13 +151,13 @@ private:
};
/* Spawn ground unit command */
class SpawnGroundUnit : public Command
class SpawnGroundUnits : public Command
{
public:
SpawnGroundUnit(string coalition, string unitType, Coords location, bool immediate) :
SpawnGroundUnits(string coalition, vector<string> unitTypes, vector<Coords> locations, bool immediate) :
coalition(coalition),
unitType(unitType),
location(location),
unitTypes(unitTypes),
locations(locations),
immediate(immediate)
{
priority = immediate? CommandPriority::IMMEDIATE: CommandPriority::LOW;
@@ -167,20 +167,20 @@ public:
private:
const string coalition;
const string unitType;
const Coords location;
const vector<string> unitTypes;
const vector<Coords> locations;
const bool immediate;
};
/* Spawn air unit command */
class SpawnAircraft : public Command
class SpawnAircrafts : public Command
{
public:
SpawnAircraft(string coalition, string unitType, Coords location, string payloadName, string airbaseName, bool immediate) :
SpawnAircrafts(string coalition, vector<string> unitTypes, vector<Coords> locations, vector<string> payloadNames, string airbaseName, bool immediate) :
coalition(coalition),
unitType(unitType),
location(location),
payloadName(payloadName),
unitTypes(unitTypes),
locations(locations),
payloadNames(payloadNames),
airbaseName(airbaseName),
immediate(immediate)
{
@@ -191,9 +191,9 @@ public:
private:
const string coalition;
const string unitType;
const Coords location;
const string payloadName;
const vector<string> unitTypes;
const vector<Coords> locations;
const vector<string> payloadNames;
const string airbaseName;
const bool immediate;
};

View File

@@ -24,10 +24,16 @@ private:
void handle_request(http_request request, function<void(json::value const&, json::value&)> action);
void handle_put(http_request request);
string extractPassword(http_request& request);
void task();
atomic<bool> runListener;
string password = "";
string gameMasterPassword = "";
string blueCommanderPassword = "";
string redCommanderPassword = "";
string atcPassword = "";
string observerPassword = "";
};

View File

@@ -37,38 +37,52 @@ string Smoke::getString(lua_State* L)
return commandSS.str();
}
/* Spawn ground command */
string SpawnGroundUnit::getString(lua_State* L)
/* Spawn ground units command */
string SpawnGroundUnits::getString(lua_State* L)
{
if (unitTypes.size() != locations.size()) return "";
std::ostringstream unitsSS;
unitsSS.precision(10);
for (int i = 0; i < unitTypes.size(); i++) {
unitsSS << "[" << i + 1 << "] = {"
<< "unitType = " << "\"" << unitTypes[i] << "\"" << ", "
<< "lat = " << locations[i].lat << ", "
<< "lng = " << locations[i].lng << "}";
}
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.spawnGroundUnit, "
<< "\"" << coalition << "\"" << ", "
<< "\"" << unitType << "\"" << ", "
<< location.lat << ", "
<< location.lng;
commandSS << "Olympus.spawnUnits, {"
<< "category = " << "\"" << "GroundUnit" << "\"" << ", "
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "units = " << "\"" << unitsSS.str() << "\"" << "}";
return commandSS.str();
}
/* Spawn air command */
string SpawnAircraft::getString(lua_State* L)
/* Spawn aircrafts command */
string SpawnAircrafts::getString(lua_State* L)
{
std::ostringstream optionsSS;
optionsSS.precision(10);
optionsSS << "{"
<< "payloadName = \"" << payloadName << "\", "
<< "airbaseName = \"" << airbaseName << "\", "
<< "}";
if (unitTypes.size() != locations.size() || unitTypes.size() != payloadNames.size()) return "";
std::ostringstream unitsSS;
unitsSS.precision(10);
for (int i = 0; i < unitTypes.size(); i++) {
unitsSS << "[" << i + 1 << "] = {"
<< "unitType = " << "\"" << unitTypes[i] << "\"" << ", "
<< "lat = " << locations[i].lat << ", "
<< "lng = " << locations[i].lng << ", "
<< "alt = " << locations[i].alt << ", "
<< "payloadName = \"" << payloadNames[i] << "\", " << "}";
}
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.spawnAircraft, "
<< "\"" << coalition << "\"" << ", "
<< "\"" << unitType << "\"" << ", "
<< location.lat << ", "
<< location.lng << ", "
<< location.alt << ", "
<< optionsSS.str();
commandSS << "Olympus.spawnUnits, {"
<< "category = " << "\"" << "Aircraft" << "\"" << ", "
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "airbaseName = \"" << airbaseName << "\", "
<< "units = " << "\"" << unitsSS.str() << "\"" << "}";
return commandSS.str();
}

View File

@@ -92,30 +92,49 @@ void Scheduler::handleRequest(string key, json::value value)
Coords loc; loc.lat = lat; loc.lng = lng;
command = dynamic_cast<Command*>(new Smoke(color, loc));
}
else if (key.compare("spawnGround") == 0)
else if (key.compare("spawnGroundUnits") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
string type = to_string(value[L"type"]);
double lat = value[L"location"][L"lat"].as_double();
double lng = value[L"location"][L"lng"].as_double();
log("Spawning " + coalition + " ground unit of type " + type + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
Coords loc; loc.lat = lat; loc.lng = lng;
command = dynamic_cast<Command*>(new SpawnGroundUnit(coalition, type, loc, immediate));
vector<string> unitTypes;
vector<Coords> locations;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"type"]);
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;
log("Spawning " + coalition + " ground unit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
}
command = dynamic_cast<Command*>(new SpawnGroundUnits(coalition, unitTypes, locations, immediate));
}
else if (key.compare("spawnAir") == 0)
else if (key.compare("spawnAircrafts") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
string type = to_string(value[L"type"]);
double lat = value[L"location"][L"lat"].as_double();
double lng = value[L"location"][L"lng"].as_double();
double altitude = value[L"altitude"].as_double();
Coords loc; loc.lat = lat; loc.lng = lng; loc.alt = altitude;
string payloadName = to_string(value[L"payloadName"]);
string airbaseName = to_string(value[L"airbaseName"]);
log("Spawning " + coalition + " air unit of type " + type + " with payload " + payloadName + " at (" + to_string(lat) + ", " + to_string(lng) + " " + airbaseName + ")");
command = dynamic_cast<Command*>(new SpawnAircraft(coalition, type, loc, payloadName, airbaseName, immediate));
vector<string> unitTypes;
vector<Coords> locations;
vector<string> payloadNames;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"type"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
double alt = value[L"altitude"].as_double();
Coords location; location.lat = lat; location.lng = lng; location.alt = alt;
string payloadName = to_string(value[L"payloadName"]);
log("Spawning " + coalition + " air unit unit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
payloadNames.push_back(payloadName);
}
command = dynamic_cast<Command*>(new SpawnAircrafts(coalition, unitTypes, locations, payloadNames, airbaseName, immediate));
}
else if (key.compare("attackUnit") == 0)
{

View File

@@ -72,8 +72,9 @@ void Server::handle_get(http_request request)
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
http_response response(status_codes::OK);
string authorization = to_base64("admin:" + password);
if (password.length() == 0 || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second.compare(L"Basic " + to_wstring(authorization)) == 0))
string password = extractPassword(request);
if (password.compare(gameMasterPassword) == 0 || password.compare(blueCommanderPassword) == 0 || password.compare(redCommanderPassword) == 0)
{
std::exception_ptr eptr;
try {
@@ -114,9 +115,15 @@ void Server::handle_get(http_request request)
answer[L"airbases"] = airbases;
else if (URI.compare(BULLSEYE_URI) == 0)
answer[L"bullseyes"] = bullseyes;
else if (URI.compare(MISSION_URI) == 0)
else if (URI.compare(MISSION_URI) == 0) {
if (password.compare(gameMasterPassword) == 0)
mission[L"visibilityMode"] = json::value(L"Game master");
else if (password.compare(blueCommanderPassword) == 0)
mission[L"visibilityMode"] = json::value(L"Blue commander");
else if (password.compare(redCommanderPassword) == 0)
mission[L"visibilityMode"] = json::value(L"Red commander");
answer[L"mission"] = mission;
}
answer[L"time"] = json::value::string(to_wstring(ms.count()));
answer[L"sessionHash"] = json::value::string(to_wstring(sessionHash));
@@ -144,8 +151,10 @@ void Server::handle_get(http_request request)
void Server::handle_request(http_request request, function<void(json::value const&, json::value&)> action)
{
http_response response(status_codes::OK);
string authorization = to_base64("admin:" + password);
if (password.length() == 0 || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second.compare(L"Basic " + to_wstring(authorization)) == 0))
//TODO: limit what a user can do depending on the password
string password = extractPassword(request);
if (password.compare(gameMasterPassword) == 0 || password.compare(blueCommanderPassword) == 0 || password.compare(redCommanderPassword) == 0)
{
auto answer = json::value::object();
request.extract_json().then([&answer, &action](pplx::task<json::value> task)
@@ -200,6 +209,30 @@ void Server::handle_put(http_request request)
});
}
string Server::extractPassword(http_request& request) {
if (request.headers().has(L"Authorization")) {
string authorization = to_string(request.headers().find(L"Authorization")->second);
string s = "Basic ";
string::size_type i = authorization.find(s);
if (i != std::string::npos)
authorization.erase(i, s.length());
else
return "";
string decoded = from_base64(authorization);
i = authorization.find(":");
if (i != std::string::npos)
decoded.erase(0, i);
else
return "";
return decoded;
}
else
return "";
}
void Server::task()
{
string address = REST_ADDRESS;
@@ -225,7 +258,9 @@ void Server::task()
if (config.is_object() && config.has_object_field(L"authentication") &&
config[L"authentication"].has_string_field(L"password"))
{
password = to_string(config[L"authentication"][L"password"]);
gameMasterPassword = to_string(config[L"authentication"][L"gameMasterPassword"]);
blueCommanderPassword = to_string(config[L"authentication"][L"blueCommanderPassword"]);
redCommanderPassword = to_string(config[L"authentication"][L"redCommanderPassword"]);
}
else
log("Error reading configuration file. No password set.");