mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Transition to json to binary data transfers
This commit is contained in:
parent
9d0e2239e4
commit
1d62b4c115
@ -4,10 +4,10 @@
|
||||
class Aircraft : public AirUnit
|
||||
{
|
||||
public:
|
||||
Aircraft(json::value json, int ID);
|
||||
Aircraft(json::value json, unsigned int ID);
|
||||
|
||||
virtual wstring getCategory() { return L"Aircraft"; };
|
||||
virtual string getCategory() { return "Aircraft"; };
|
||||
|
||||
virtual void changeSpeed(wstring change);
|
||||
virtual void changeAltitude(wstring change);
|
||||
virtual void changeSpeed(string change);
|
||||
virtual void changeAltitude(string change);
|
||||
};
|
||||
@ -5,18 +5,18 @@
|
||||
#include "luatools.h"
|
||||
#include "Unit.h"
|
||||
|
||||
#define AIR_DEST_DIST_THR 2000
|
||||
#define AIR_DEST_DIST_THR 2000 // Meters
|
||||
|
||||
class AirUnit : public Unit
|
||||
{
|
||||
public:
|
||||
AirUnit(json::value json, int ID);
|
||||
AirUnit(json::value json, unsigned int ID);
|
||||
|
||||
virtual void setState(int newState);
|
||||
virtual void setState(unsigned char newState);
|
||||
|
||||
virtual wstring getCategory() = 0;
|
||||
virtual void changeSpeed(wstring change) = 0;
|
||||
virtual void changeAltitude(wstring change) = 0;
|
||||
virtual string getCategory() = 0;
|
||||
virtual void changeSpeed(string change) = 0;
|
||||
virtual void changeAltitude(string change) = 0;
|
||||
|
||||
protected:
|
||||
virtual void AIloop();
|
||||
|
||||
@ -54,6 +54,15 @@ namespace ReactionToThreat {
|
||||
};
|
||||
}
|
||||
|
||||
namespace EmissionCountermeasure {
|
||||
enum ReactionsToThreat {
|
||||
SILENT = 0,
|
||||
ATTACK = 1,
|
||||
DEFEND = 2,
|
||||
FREE = 3
|
||||
};
|
||||
}
|
||||
|
||||
namespace RadarUse {
|
||||
enum RadarUses {
|
||||
NEVER = 0,
|
||||
@ -85,19 +94,19 @@ namespace ECMUse {
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
int getPriority() { return priority; }
|
||||
virtual wstring getString(lua_State* L) = 0;
|
||||
virtual int getLoad() = 0;
|
||||
unsigned int getPriority() { return priority; }
|
||||
virtual string getString(lua_State* L) = 0;
|
||||
virtual unsigned int getLoad() = 0;
|
||||
|
||||
protected:
|
||||
int priority = CommandPriority::LOW;
|
||||
unsigned int priority = CommandPriority::LOW;
|
||||
};
|
||||
|
||||
/* Simple low priority move command (from user click) */
|
||||
class Move : public Command
|
||||
{
|
||||
public:
|
||||
Move(wstring groupName, Coords destination, double speed, wstring speedType, double altitude, wstring altitudeType, wstring taskOptions, wstring category):
|
||||
Move(string groupName, Coords destination, double speed, string speedType, double altitude, string altitudeType, string taskOptions, string category):
|
||||
groupName(groupName),
|
||||
destination(destination),
|
||||
speed(speed),
|
||||
@ -109,35 +118,35 @@ public:
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 5; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 5; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const string groupName;
|
||||
const Coords destination;
|
||||
const double speed;
|
||||
const wstring speedType;
|
||||
const string speedType;
|
||||
const double altitude;
|
||||
const wstring altitudeType;
|
||||
const wstring taskOptions;
|
||||
const wstring category;
|
||||
const string altitudeType;
|
||||
const string taskOptions;
|
||||
const string category;
|
||||
};
|
||||
|
||||
/* Smoke command */
|
||||
class Smoke : public Command
|
||||
{
|
||||
public:
|
||||
Smoke(wstring color, Coords location) :
|
||||
Smoke(string color, Coords location) :
|
||||
color(color),
|
||||
location(location)
|
||||
{
|
||||
priority = CommandPriority::LOW;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 5; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 5; }
|
||||
|
||||
private:
|
||||
const wstring color;
|
||||
const string color;
|
||||
const Coords location;
|
||||
};
|
||||
|
||||
@ -145,7 +154,7 @@ private:
|
||||
class SpawnGroundUnit : public Command
|
||||
{
|
||||
public:
|
||||
SpawnGroundUnit(wstring coalition, wstring unitType, Coords location, bool immediate) :
|
||||
SpawnGroundUnit(string coalition, string unitType, Coords location, bool immediate) :
|
||||
coalition(coalition),
|
||||
unitType(unitType),
|
||||
location(location),
|
||||
@ -153,12 +162,12 @@ public:
|
||||
{
|
||||
priority = immediate? CommandPriority::IMMEDIATE: CommandPriority::LOW;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 100 * !immediate; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 100 * !immediate; }
|
||||
|
||||
private:
|
||||
const wstring coalition;
|
||||
const wstring unitType;
|
||||
const string coalition;
|
||||
const string unitType;
|
||||
const Coords location;
|
||||
const bool immediate;
|
||||
};
|
||||
@ -167,7 +176,7 @@ private:
|
||||
class SpawnAircraft : public Command
|
||||
{
|
||||
public:
|
||||
SpawnAircraft(wstring coalition, wstring unitType, Coords location, wstring payloadName, wstring airbaseName, bool immediate) :
|
||||
SpawnAircraft(string coalition, string unitType, Coords location, string payloadName, string airbaseName, bool immediate) :
|
||||
coalition(coalition),
|
||||
unitType(unitType),
|
||||
location(location),
|
||||
@ -177,15 +186,15 @@ public:
|
||||
{
|
||||
priority = immediate ? CommandPriority::IMMEDIATE : CommandPriority::LOW;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 100 * !immediate; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 100 * !immediate; }
|
||||
|
||||
private:
|
||||
const wstring coalition;
|
||||
const wstring unitType;
|
||||
const string coalition;
|
||||
const string unitType;
|
||||
const Coords location;
|
||||
const wstring payloadName;
|
||||
const wstring airbaseName;
|
||||
const string payloadName;
|
||||
const string airbaseName;
|
||||
const bool immediate;
|
||||
};
|
||||
|
||||
@ -193,17 +202,17 @@ private:
|
||||
class Clone : public Command
|
||||
{
|
||||
public:
|
||||
Clone(int ID, Coords location) :
|
||||
Clone(unsigned int ID, Coords location) :
|
||||
ID(ID),
|
||||
location(location)
|
||||
{
|
||||
priority = CommandPriority::LOW;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 100; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 100; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const unsigned int ID;
|
||||
const Coords location;
|
||||
};
|
||||
|
||||
@ -211,17 +220,17 @@ private:
|
||||
class Delete : public Command
|
||||
{
|
||||
public:
|
||||
Delete(int ID, bool explosion) :
|
||||
Delete(unsigned int ID, bool explosion) :
|
||||
ID(ID),
|
||||
explosion(explosion)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 20; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 20; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const unsigned int ID;
|
||||
const bool explosion;
|
||||
};
|
||||
|
||||
@ -229,59 +238,59 @@ private:
|
||||
class SetTask : public Command
|
||||
{
|
||||
public:
|
||||
SetTask(wstring groupName, wstring task) :
|
||||
SetTask(string groupName, string task) :
|
||||
groupName(groupName),
|
||||
task(task)
|
||||
{
|
||||
priority = CommandPriority::MEDIUM;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 2; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 2; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const wstring task;
|
||||
const string groupName;
|
||||
const string task;
|
||||
};
|
||||
|
||||
/* Reset task command */
|
||||
class ResetTask : public Command
|
||||
{
|
||||
public:
|
||||
ResetTask(wstring groupName) :
|
||||
ResetTask(string groupName) :
|
||||
groupName(groupName)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 2; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 2; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const string groupName;
|
||||
};
|
||||
|
||||
/* Set command */
|
||||
class SetCommand : public Command
|
||||
{
|
||||
public:
|
||||
SetCommand(wstring groupName, wstring command) :
|
||||
SetCommand(string groupName, string command) :
|
||||
groupName(groupName),
|
||||
command(command)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 2; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 2; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const wstring command;
|
||||
const string groupName;
|
||||
const string command;
|
||||
};
|
||||
|
||||
/* Set option command */
|
||||
class SetOption : public Command
|
||||
{
|
||||
public:
|
||||
SetOption(wstring groupName, int optionID, int optionValue) :
|
||||
SetOption(string groupName, unsigned int optionID, unsigned int optionValue) :
|
||||
groupName(groupName),
|
||||
optionID(optionID),
|
||||
optionValue(optionValue),
|
||||
@ -291,7 +300,7 @@ public:
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
|
||||
SetOption(wstring groupName, int optionID, bool optionBool) :
|
||||
SetOption(string groupName, unsigned int optionID, bool optionBool) :
|
||||
groupName(groupName),
|
||||
optionID(optionID),
|
||||
optionValue(0),
|
||||
@ -300,13 +309,13 @@ public:
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 2; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 2; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const int optionID;
|
||||
const int optionValue;
|
||||
const string groupName;
|
||||
const unsigned int optionID;
|
||||
const unsigned int optionValue;
|
||||
const bool optionBool;
|
||||
const bool isBoolean;
|
||||
};
|
||||
@ -315,17 +324,17 @@ private:
|
||||
class SetOnOff : public Command
|
||||
{
|
||||
public:
|
||||
SetOnOff(wstring groupName, bool onOff) :
|
||||
SetOnOff(string groupName, bool onOff) :
|
||||
groupName(groupName),
|
||||
onOff(onOff)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 2; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 2; }
|
||||
|
||||
private:
|
||||
const wstring groupName;
|
||||
const string groupName;
|
||||
const bool onOff;
|
||||
};
|
||||
|
||||
@ -333,16 +342,16 @@ private:
|
||||
class Explosion : public Command
|
||||
{
|
||||
public:
|
||||
Explosion(int intensity, Coords location) :
|
||||
Explosion(unsigned int intensity, Coords location) :
|
||||
location(location),
|
||||
intensity(intensity)
|
||||
{
|
||||
priority = CommandPriority::MEDIUM;
|
||||
};
|
||||
virtual wstring getString(lua_State* L);
|
||||
virtual int getLoad() { return 10; }
|
||||
virtual string getString(lua_State* L);
|
||||
virtual unsigned int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const Coords location;
|
||||
const int intensity;
|
||||
const unsigned int intensity;
|
||||
};
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
class GroundUnit : public Unit
|
||||
{
|
||||
public:
|
||||
GroundUnit(json::value json, int ID);
|
||||
virtual wstring getCategory() { return L"GroundUnit"; };
|
||||
GroundUnit(json::value json, unsigned int ID);
|
||||
virtual string getCategory() { return "GroundUnit"; };
|
||||
|
||||
virtual void setState(int newState);
|
||||
virtual void setState(unsigned char newState);
|
||||
|
||||
virtual void changeSpeed(wstring change);
|
||||
virtual void changeSpeed(string change);
|
||||
virtual void setOnOff(bool newOnOff);
|
||||
virtual void setFollowRoads(bool newFollowRoads);
|
||||
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
class Helicopter : public AirUnit
|
||||
{
|
||||
public:
|
||||
Helicopter(json::value json, int ID);
|
||||
Helicopter(json::value json, unsigned int ID);
|
||||
|
||||
virtual wstring getCategory() { return L"Helicopter"; };
|
||||
virtual string getCategory() { return "Helicopter"; };
|
||||
|
||||
virtual void changeSpeed(wstring change);
|
||||
virtual void changeAltitude(wstring change);
|
||||
virtual void changeSpeed(string change);
|
||||
virtual void changeAltitude(string change);
|
||||
};
|
||||
@ -4,10 +4,10 @@
|
||||
class NavyUnit : public Unit
|
||||
{
|
||||
public:
|
||||
NavyUnit(json::value json, int ID);
|
||||
NavyUnit(json::value json, unsigned int ID);
|
||||
virtual void AIloop();
|
||||
|
||||
virtual wstring getCategory() { return L"NavyUnit"; };
|
||||
virtual void changeSpeed(wstring change);
|
||||
virtual string getCategory() { return "NavyUnit"; };
|
||||
virtual void changeSpeed(string change);
|
||||
|
||||
};
|
||||
@ -11,10 +11,10 @@ public:
|
||||
|
||||
void appendCommand(Command* command);
|
||||
void execute(lua_State* L);
|
||||
void handleRequest(wstring key, json::value value);
|
||||
void handleRequest(string key, json::value value);
|
||||
|
||||
private:
|
||||
list<Command*> commands;
|
||||
int load;
|
||||
unsigned int load;
|
||||
};
|
||||
|
||||
|
||||
@ -15,8 +15,6 @@ public:
|
||||
|
||||
void start(lua_State* L);
|
||||
void stop(lua_State* L);
|
||||
json::value& getUpdateJson() { return updateJson; }
|
||||
json::value& getRefreshJson() { return refreshJson; }
|
||||
|
||||
private:
|
||||
std::thread* serverThread;
|
||||
@ -29,9 +27,7 @@ private:
|
||||
void task();
|
||||
|
||||
atomic<bool> runListener;
|
||||
json::value updateJson;
|
||||
json::value refreshJson;
|
||||
|
||||
wstring password = L"";
|
||||
string password = "";
|
||||
};
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "luatools.h"
|
||||
#include "measure.h"
|
||||
#include "logger.h"
|
||||
#include "commands.h"
|
||||
|
||||
#define TASK_CHECK_INIT_VALUE 10
|
||||
|
||||
@ -32,16 +33,16 @@ namespace Options {
|
||||
struct TACAN
|
||||
{
|
||||
bool isOn = false;
|
||||
int channel = 40;
|
||||
wstring XY = L"X";
|
||||
wstring callsign = L"TKR";
|
||||
unsigned char channel = 40;
|
||||
char XY = 'X';
|
||||
char callsign[4];
|
||||
};
|
||||
|
||||
struct Radio
|
||||
{
|
||||
int frequency = 124000000; // MHz
|
||||
int callsign = 1;
|
||||
int callsignNumber = 1;
|
||||
unsigned int frequency = 124000000; // MHz
|
||||
unsigned char callsign = 1;
|
||||
unsigned char callsignNumber = 1;
|
||||
};
|
||||
|
||||
struct GeneralSettings
|
||||
@ -54,116 +55,145 @@ namespace Options {
|
||||
};
|
||||
}
|
||||
|
||||
namespace DataTypes {
|
||||
struct Ammo {
|
||||
unsigned short quantity = 0;
|
||||
string name;
|
||||
unsigned char guidance = 0;
|
||||
unsigned char category = 0;
|
||||
unsigned char missileCategory = 0;
|
||||
};
|
||||
|
||||
struct Contact {
|
||||
unsigned int ID = 0;
|
||||
unsigned char detectionMethod = 0;
|
||||
};
|
||||
|
||||
struct DataPacket {
|
||||
unsigned int ID;
|
||||
unsigned int bitmask;
|
||||
Coords position;
|
||||
double speed;
|
||||
double heading;
|
||||
unsigned short fuel;
|
||||
double desiredSpeed;
|
||||
double desiredAltitude;
|
||||
unsigned int targetID;
|
||||
Coords targetPosition;
|
||||
unsigned char state;
|
||||
unsigned char ROE;
|
||||
unsigned char reactionToThreat;
|
||||
unsigned char emissionsCountermeasures;
|
||||
Options::TACAN TACAN;
|
||||
Options::Radio Radio;
|
||||
};
|
||||
}
|
||||
|
||||
class Unit
|
||||
{
|
||||
public:
|
||||
Unit(json::value json, int ID);
|
||||
Unit(json::value json, unsigned int ID);
|
||||
~Unit();
|
||||
|
||||
/********** Public methods **********/
|
||||
void initialize(json::value json);
|
||||
void setDefaults(bool force = false);
|
||||
int getID() { return ID; }
|
||||
unsigned int getID() { return ID; }
|
||||
void runAILoop();
|
||||
void updateExportData(json::value json, double dt = 0);
|
||||
void updateMissionData(json::value json);
|
||||
json::value getData(long long time, bool getAll = false);
|
||||
virtual wstring getCategory() { return L"No category"; };
|
||||
DataTypes::DataPacket getDataPacket();
|
||||
string getData(bool refresh);
|
||||
virtual string getCategory() { return "No category"; };
|
||||
|
||||
/********** Base data **********/
|
||||
void setControlled(bool newControlled) { controlled = newControlled; addMeasure(L"controlled", json::value(newControlled)); }
|
||||
void setName(wstring newName) { name = newName; addMeasure(L"name", json::value(newName));}
|
||||
void setUnitName(wstring newUnitName) { unitName = newUnitName; addMeasure(L"unitName", json::value(newUnitName));}
|
||||
void setGroupName(wstring newGroupName) { groupName = newGroupName; addMeasure(L"groupName", json::value(newGroupName));}
|
||||
void setAlive(bool newAlive) { alive = newAlive; addMeasure(L"alive", json::value(newAlive));}
|
||||
void setType(json::value newType) { type = newType; addMeasure(L"type", newType);}
|
||||
void setCountry(int newCountry) { country = newCountry; addMeasure(L"country", json::value(newCountry));}
|
||||
void setControlled(bool newControlled) { controlled = newControlled; }
|
||||
void setName(string newName) { name = newName; }
|
||||
void setUnitName(string newUnitName) { unitName = newUnitName; }
|
||||
void setGroupName(string newGroupName) { groupName = newGroupName; }
|
||||
void setAlive(bool newAlive) { alive = newAlive; }
|
||||
void setCountry(unsigned int newCountry) { country = newCountry; }
|
||||
void setHuman(bool newHuman) { human = newHuman; }
|
||||
|
||||
bool getControlled() { return controlled; }
|
||||
wstring getName() { return name; }
|
||||
wstring getUnitName() { return unitName; }
|
||||
wstring getGroupName() { return groupName; }
|
||||
string getName() { return name; }
|
||||
string getUnitName() { return unitName; }
|
||||
string getGroupName() { return groupName; }
|
||||
bool getAlive() { return alive; }
|
||||
json::value getType() { return type; }
|
||||
int getCountry() { return country; }
|
||||
unsigned int getCountry() { return country; }
|
||||
bool getHuman() { return human; }
|
||||
|
||||
/********** Flight data **********/
|
||||
void setLatitude(double newLatitude) {latitude = newLatitude; addMeasure(L"latitude", json::value(newLatitude));}
|
||||
void setLongitude(double newLongitude) {longitude = newLongitude; addMeasure(L"longitude", json::value(newLongitude));}
|
||||
void setAltitude(double newAltitude) {altitude = newAltitude; addMeasure(L"altitude", json::value(newAltitude));}
|
||||
void setHeading(double newHeading) {heading = newHeading; addMeasure(L"heading", json::value(newHeading));}
|
||||
void setSpeed(double newSpeed) {speed = newSpeed; addMeasure(L"speed", json::value(newSpeed));}
|
||||
void setPosition(Coords newPosition) { position = newPosition; }
|
||||
void setHeading(double newHeading) {heading = newHeading; }
|
||||
void setSpeed(double newSpeed) {speed = newSpeed; }
|
||||
|
||||
double getLatitude() { return latitude; }
|
||||
double getLongitude() { return longitude; }
|
||||
double getAltitude() { return altitude; }
|
||||
Coords getPosition() { return position; }
|
||||
double getHeading() { return heading; }
|
||||
double getSpeed() { return speed; }
|
||||
|
||||
/********** Mission data **********/
|
||||
void setFuel(double newFuel) { fuel = newFuel; addMeasure(L"fuel", json::value(newFuel));}
|
||||
void setAmmo(json::value newAmmo) { ammo = newAmmo; addMeasure(L"ammo", json::value(newAmmo));}
|
||||
void setContacts(json::value newContacts) {contacts = newContacts; addMeasure(L"contacts", json::value(newContacts));}
|
||||
void setFuel(short newFuel) { fuel = newFuel; }
|
||||
void setAmmo(vector<DataTypes::Ammo> newAmmo) { ammo = newAmmo; }
|
||||
void setContacts(vector<DataTypes::Contact> newContacts) {contacts = newContacts; }
|
||||
void setHasTask(bool newHasTask);
|
||||
void setCoalitionID(int newCoalitionID);
|
||||
void setFlags(json::value newFlags) { flags = newFlags; addMeasure(L"flags", json::value(newFlags));}
|
||||
void setCoalitionID(unsigned int newCoalitionID);
|
||||
|
||||
double getFuel() { return fuel; }
|
||||
json::value getAmmo() { return ammo; }
|
||||
json::value getTargets() { return contacts; }
|
||||
vector<DataTypes::Ammo> getAmmo() { return ammo; }
|
||||
vector<DataTypes::Contact> getTargets() { return contacts; }
|
||||
bool getHasTask() { return hasTask; }
|
||||
wstring getCoalition() { return coalition; }
|
||||
int getCoalitionID();
|
||||
json::value getFlags() { return flags; }
|
||||
string getCoalition() { return coalition; }
|
||||
unsigned int getCoalitionID();
|
||||
|
||||
/********** Formation data **********/
|
||||
void setLeaderID(int newLeaderID) { leaderID = newLeaderID; addMeasure(L"leaderID", json::value(newLeaderID)); }
|
||||
void setLeaderID(unsigned int newLeaderID) { leaderID = newLeaderID; }
|
||||
void setFormationOffset(Offset formationOffset);
|
||||
|
||||
int getLeaderID() { return leaderID; }
|
||||
unsigned int getLeaderID() { return leaderID; }
|
||||
Offset getFormationoffset() { return formationOffset; }
|
||||
|
||||
/********** Task data **********/
|
||||
void setCurrentTask(wstring newCurrentTask) { currentTask = newCurrentTask; addMeasure(L"currentTask", json::value(newCurrentTask)); }
|
||||
void setCurrentTask(string newCurrentTask) { currentTask = newCurrentTask; }
|
||||
void setDesiredSpeed(double newDesiredSpeed);
|
||||
void setDesiredAltitude(double newDesiredAltitude);
|
||||
void setDesiredSpeedType(wstring newDesiredSpeedType);
|
||||
void setDesiredAltitudeType(wstring newDesiredAltitudeType);
|
||||
void setActiveDestination(Coords newActiveDestination) { activeDestination = newActiveDestination; addMeasure(L"activeDestination", json::value("")); } // TODO fix
|
||||
void setDesiredSpeedType(string newDesiredSpeedType);
|
||||
void setDesiredAltitudeType(string newDesiredAltitudeType);
|
||||
void setActiveDestination(Coords newActiveDestination) { activeDestination = newActiveDestination; }
|
||||
void setActivePath(list<Coords> newActivePath);
|
||||
void setTargetID(int newTargetID) { targetID = newTargetID; addMeasure(L"targetID", json::value(newTargetID));}
|
||||
void setTargetLocation(Coords newTargetLocation);
|
||||
void setTargetID(unsigned int newTargetID) { targetID = newTargetID; }
|
||||
void setTargetPosition(Coords newTargetPosition);
|
||||
void setIsTanker(bool newIsTanker);
|
||||
void setIsAWACS(bool newIsAWACS);
|
||||
virtual void setOnOff(bool newOnOff) { onOff = newOnOff; addMeasure(L"onOff", json::value(newOnOff));};
|
||||
virtual void setFollowRoads(bool newFollowRoads) { followRoads = newFollowRoads; addMeasure(L"followRoads", json::value(newFollowRoads)); };
|
||||
virtual void setOnOff(bool newOnOff) { onOff = newOnOff; };
|
||||
virtual void setFollowRoads(bool newFollowRoads) { followRoads = newFollowRoads; };
|
||||
|
||||
wstring getCurrentTask() { return currentTask; }
|
||||
string getCurrentTask() { return currentTask; }
|
||||
virtual double getDesiredSpeed() { return desiredSpeed; };
|
||||
virtual double getDesiredAltitude() { return desiredAltitude; };
|
||||
virtual wstring getDesiredSpeedType() { return desiredSpeedType; };
|
||||
virtual wstring getDesiredAltitudeType() { return desiredAltitudeType; };
|
||||
virtual bool getDesiredSpeedType() { return desiredSpeedType; };
|
||||
virtual bool getDesiredAltitudeType() { return desiredAltitudeType; };
|
||||
Coords getActiveDestination() { return activeDestination; }
|
||||
list<Coords> getActivePath() { return activePath; }
|
||||
int getTargetID() { return targetID; }
|
||||
Coords getTargetLocation() { return targetLocation; }
|
||||
unsigned int getTargetID() { return targetID; }
|
||||
Coords getTargetPosition() { return targetPosition; }
|
||||
bool getIsTanker() { return isTanker; }
|
||||
bool getIsAWACS() { return isAWACS; }
|
||||
bool getOnOff() { return onOff; };
|
||||
bool getFollowRoads() { return followRoads; };
|
||||
|
||||
/********** Options data **********/
|
||||
void setROE(wstring newROE, bool force = false);
|
||||
void setReactionToThreat(wstring newReactionToThreat, bool force = false);
|
||||
void setEmissionsCountermeasures(wstring newEmissionsCountermeasures, bool force = false);
|
||||
void setROE(unsigned char newROE, bool force = false);
|
||||
void setReactionToThreat(unsigned char newReactionToThreat, bool force = false);
|
||||
void setEmissionsCountermeasures(unsigned char newEmissionsCountermeasures, bool force = false);
|
||||
void setTACAN(Options::TACAN newTACAN, bool force = false);
|
||||
void setRadio(Options::Radio newradio, bool force = false);
|
||||
void setGeneralSettings(Options::GeneralSettings newGeneralSettings, bool force = false);
|
||||
void setEPLRS(bool newEPLRS, bool force = false);
|
||||
|
||||
wstring getROE() { return ROE; }
|
||||
wstring getReactionToThreat() { return reactionToThreat; }
|
||||
wstring getEmissionsCountermeasures() { return emissionsCountermeasures; };
|
||||
unsigned char getROE() { return ROE; }
|
||||
unsigned char getReactionToThreat() { return reactionToThreat; }
|
||||
unsigned char getEmissionsCountermeasures() { return emissionsCountermeasures; };
|
||||
Options::TACAN getTACAN() { return TACAN; }
|
||||
Options::Radio getRadio() { return radio; }
|
||||
Options::GeneralSettings getGeneralSettings() { return generalSettings; }
|
||||
@ -171,10 +201,10 @@ public:
|
||||
|
||||
/********** Control functions **********/
|
||||
void landAt(Coords loc);
|
||||
virtual void changeSpeed(wstring change) {};
|
||||
virtual void changeAltitude(wstring change) {};
|
||||
virtual void changeSpeed(string change) {};
|
||||
virtual void changeAltitude(string change) {};
|
||||
void resetActiveDestination();
|
||||
virtual void setState(int newState) { state = newState; };
|
||||
virtual void setState(unsigned char newState) { state = newState; };
|
||||
void resetTask();
|
||||
void clearActivePath();
|
||||
void pushActivePathFront(Coords newActivePathFront);
|
||||
@ -182,81 +212,77 @@ public:
|
||||
void popActivePathFront();
|
||||
|
||||
protected:
|
||||
int ID;
|
||||
unsigned int ID;
|
||||
|
||||
map<wstring, Measure*> measures;
|
||||
int taskCheckCounter = 0;
|
||||
map<string, Measure*> measures;
|
||||
unsigned int taskCheckCounter = 0;
|
||||
|
||||
/********** Base data **********/
|
||||
bool controlled = false;
|
||||
wstring name = L"undefined";
|
||||
wstring unitName = L"undefined";
|
||||
wstring groupName = L"undefined";
|
||||
string name = "undefined";
|
||||
string unitName = "undefined";
|
||||
string groupName = "undefined";
|
||||
bool alive = true;
|
||||
json::value type = json::value::null();
|
||||
int country = NULL;
|
||||
bool human = false;
|
||||
unsigned int country = NULL;
|
||||
|
||||
/********** Flight data **********/
|
||||
double latitude = NULL;
|
||||
double longitude = NULL;
|
||||
double altitude = NULL;
|
||||
Coords position = Coords(NULL);
|
||||
double speed = NULL;
|
||||
double heading = NULL;
|
||||
|
||||
/********** Mission data **********/
|
||||
double fuel = 0;
|
||||
unsigned short fuel = 0;
|
||||
double initialFuel = 0; // Used internally to detect refueling completed
|
||||
json::value ammo = json::value::null();
|
||||
json::value contacts = json::value::null();
|
||||
vector<DataTypes::Ammo> ammo;
|
||||
vector<DataTypes::Contact> contacts;
|
||||
bool hasTask = false;
|
||||
wstring coalition = L"";
|
||||
json::value flags = json::value::null();
|
||||
string coalition = "";
|
||||
|
||||
/********** Formation data **********/
|
||||
int leaderID = NULL;
|
||||
unsigned int leaderID = NULL;
|
||||
Offset formationOffset = Offset(NULL);
|
||||
|
||||
/********** Task data **********/
|
||||
wstring currentTask = L"";
|
||||
string currentTask = "";
|
||||
double desiredSpeed = 0;
|
||||
double desiredAltitude = 0;
|
||||
wstring desiredSpeedType = L"GS";
|
||||
wstring desiredAltitudeType = L"AGL";
|
||||
bool desiredSpeedType = 0;
|
||||
bool desiredAltitudeType = 0;
|
||||
list<Coords> activePath;
|
||||
Coords activeDestination = Coords(NULL);
|
||||
int targetID = NULL;
|
||||
Coords targetLocation = Coords(NULL);
|
||||
unsigned int targetID = NULL;
|
||||
Coords targetPosition = Coords(NULL);
|
||||
bool isTanker = false;
|
||||
bool isAWACS = false;
|
||||
bool onOff = true;
|
||||
bool followRoads = false;
|
||||
|
||||
/********** Options data **********/
|
||||
wstring ROE = L"Designated";
|
||||
wstring reactionToThreat = L"Evade";
|
||||
wstring emissionsCountermeasures = L"Defend";
|
||||
unsigned char ROE = ROE::OPEN_FIRE_WEAPON_FREE;
|
||||
unsigned char reactionToThreat = ReactionToThreat::EVADE_FIRE;
|
||||
unsigned char emissionsCountermeasures = EmissionCountermeasure::DEFEND;
|
||||
Options::TACAN TACAN;
|
||||
Options::Radio radio;
|
||||
Options::GeneralSettings generalSettings;
|
||||
bool EPLRS = false;
|
||||
|
||||
/********** State machine **********/
|
||||
int state = State::NONE;
|
||||
unsigned char state = State::NONE;
|
||||
|
||||
/********** Other **********/
|
||||
Coords oldPosition = Coords(0); // Used to approximate speed
|
||||
|
||||
/********** Functions **********/
|
||||
wstring getTargetName();
|
||||
wstring getLeaderName();
|
||||
string getTargetName();
|
||||
string getLeaderName();
|
||||
bool isTargetAlive();
|
||||
bool isLeaderAlive();
|
||||
virtual void AIloop() = 0;
|
||||
void addMeasure(wstring key, json::value value);
|
||||
bool isDestinationReached(double threshold);
|
||||
bool setActiveDestination();
|
||||
bool updateActivePath(bool looping);
|
||||
void goToDestination(wstring enrouteTask = L"nil");
|
||||
void goToDestination(string enrouteTask = "nil");
|
||||
bool checkTaskFailed();
|
||||
void resetTaskFailedCounter();
|
||||
};
|
||||
|
||||
@ -10,23 +10,22 @@ public:
|
||||
UnitsManager(lua_State* L);
|
||||
~UnitsManager();
|
||||
|
||||
map<int, Unit*>& getUnits() { return units; };
|
||||
Unit* getUnit(int ID);
|
||||
map<unsigned int, Unit*>& getUnits() { return units; };
|
||||
Unit* getUnit(unsigned int ID);
|
||||
bool isUnitInGroup(Unit* unit);
|
||||
bool isUnitGroupLeader(Unit* unit);
|
||||
Unit* getGroupLeader(int ID);
|
||||
Unit* getGroupLeader(unsigned int ID);
|
||||
Unit* getGroupLeader(Unit* unit);
|
||||
vector<Unit*> getGroupMembers(wstring groupName);
|
||||
vector<Unit*> getGroupMembers(string groupName);
|
||||
void updateExportData(lua_State* L, double dt = 0);
|
||||
void updateMissionData(json::value missionData);
|
||||
void runAILoop();
|
||||
void getUnitData(json::value& answer, long long time);
|
||||
void appendUnitData(int ID, json::value& answer, long long time);
|
||||
void deleteUnit(int ID, bool explosion);
|
||||
void acquireControl(int ID);
|
||||
string getUnitData(bool refresh);
|
||||
void deleteUnit(unsigned int ID, bool explosion);
|
||||
void acquireControl(unsigned int ID);
|
||||
|
||||
private:
|
||||
map<int, Unit*> units;
|
||||
map<unsigned int, Unit*> units;
|
||||
json::value missionDB;
|
||||
|
||||
};
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
class Weapon : public Unit
|
||||
{
|
||||
public:
|
||||
Weapon(json::value json, int ID);
|
||||
Weapon(json::value json, unsigned int ID);
|
||||
|
||||
virtual wstring getCategory() = 0;
|
||||
virtual string getCategory() = 0;
|
||||
|
||||
protected:
|
||||
/* Weapons are not controllable and have no AIloop */
|
||||
@ -16,15 +16,15 @@ protected:
|
||||
class Missile : public Weapon
|
||||
{
|
||||
public:
|
||||
Missile(json::value json, int ID);
|
||||
Missile(json::value json, unsigned int ID);
|
||||
|
||||
virtual wstring getCategory() { return L"Missile"; };
|
||||
virtual string getCategory() { return "Missile"; };
|
||||
};
|
||||
|
||||
class Bomb : public Weapon
|
||||
{
|
||||
public:
|
||||
Bomb(json::value json, int ID);
|
||||
Bomb(json::value json, unsigned int ID);
|
||||
|
||||
virtual wstring getCategory() { return L"Bomb"; };
|
||||
virtual string getCategory() { return "Bomb"; };
|
||||
};
|
||||
@ -13,10 +13,9 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Aircraft */
|
||||
Aircraft::Aircraft(json::value json, int ID) : AirUnit(json, ID)
|
||||
Aircraft::Aircraft(json::value json, unsigned int ID) : AirUnit(json, ID)
|
||||
{
|
||||
log("New Aircraft created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
|
||||
double desiredSpeed = knotsToMs(300);
|
||||
double desiredAltitude = ftToM(20000);
|
||||
@ -24,13 +23,13 @@ Aircraft::Aircraft(json::value json, int ID) : AirUnit(json, ID)
|
||||
setDesiredAltitude(desiredAltitude);
|
||||
};
|
||||
|
||||
void Aircraft::changeSpeed(wstring change)
|
||||
void Aircraft::changeSpeed(string change)
|
||||
{
|
||||
if (change.compare(L"stop") == 0)
|
||||
if (change.compare("stop") == 0)
|
||||
setState(State::IDLE);
|
||||
else if (change.compare(L"slow") == 0)
|
||||
else if (change.compare("slow") == 0)
|
||||
setDesiredSpeed(getDesiredSpeed() - knotsToMs(25));
|
||||
else if (change.compare(L"fast") == 0)
|
||||
else if (change.compare("fast") == 0)
|
||||
setDesiredSpeed(getDesiredSpeed() + knotsToMs(25));
|
||||
|
||||
if (getDesiredSpeed() < knotsToMs(50))
|
||||
@ -42,16 +41,16 @@ void Aircraft::changeSpeed(wstring change)
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Aircraft::changeAltitude(wstring change)
|
||||
void Aircraft::changeAltitude(string change)
|
||||
{
|
||||
if (change.compare(L"descend") == 0)
|
||||
if (change.compare("descend") == 0)
|
||||
{
|
||||
if (getDesiredAltitude() > 5000)
|
||||
setDesiredAltitude(getDesiredAltitude() - ftToM(2500));
|
||||
else if (getDesiredAltitude() > 0)
|
||||
setDesiredAltitude(getDesiredAltitude() - ftToM(500));
|
||||
}
|
||||
else if (change.compare(L"climb") == 0)
|
||||
else if (change.compare("climb") == 0)
|
||||
{
|
||||
if (getDesiredAltitude() > 5000)
|
||||
setDesiredAltitude(getDesiredAltitude() + ftToM(2500));
|
||||
|
||||
@ -13,12 +13,12 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Air unit */
|
||||
AirUnit::AirUnit(json::value json, int ID) : Unit(json, ID)
|
||||
AirUnit::AirUnit(json::value json, unsigned int ID) : Unit(json, ID)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
void AirUnit::setState(int newState)
|
||||
void AirUnit::setState(unsigned char newState)
|
||||
{
|
||||
/************ Perform any action required when LEAVING a state ************/
|
||||
if (newState != state) {
|
||||
@ -46,7 +46,7 @@ void AirUnit::setState(int newState)
|
||||
case State::BOMB_POINT:
|
||||
case State::CARPET_BOMB:
|
||||
case State::BOMB_BUILDING: {
|
||||
setTargetLocation(Coords(NULL));
|
||||
setTargetPosition(Coords(NULL));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -59,12 +59,10 @@ void AirUnit::setState(int newState)
|
||||
case State::IDLE: {
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Idle"));
|
||||
break;
|
||||
}
|
||||
case State::REACH_DESTINATION: {
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Reach destination"));
|
||||
break;
|
||||
}
|
||||
case State::ATTACK: {
|
||||
@ -74,42 +72,35 @@ void AirUnit::setState(int newState)
|
||||
clearActivePath();
|
||||
pushActivePathFront(targetPosition);
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Attack"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case State::FOLLOW: {
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Follow"));
|
||||
break;
|
||||
}
|
||||
case State::LAND: {
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Land"));
|
||||
break;
|
||||
}
|
||||
case State::REFUEL: {
|
||||
initialFuel = fuel;
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Refuel"));
|
||||
break;
|
||||
}
|
||||
case State::BOMB_POINT: {
|
||||
addMeasure(L"currentState", json::value(L"Bombing point"));
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
break;
|
||||
}
|
||||
case State::CARPET_BOMB: {
|
||||
addMeasure(L"currentState", json::value(L"Carpet bombing"));
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
break;
|
||||
}
|
||||
case State::BOMB_BUILDING: {
|
||||
addMeasure(L"currentState", json::value(L"Bombing building"));
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
break;
|
||||
@ -120,7 +111,7 @@ void AirUnit::setState(int newState)
|
||||
|
||||
resetTask();
|
||||
|
||||
log(unitName + L" setting state from " + to_wstring(state) + L" to " + to_wstring(newState));
|
||||
log(unitName + " setting state from " + to_string(state) + " to " + to_string(newState));
|
||||
state = newState;
|
||||
}
|
||||
|
||||
@ -129,11 +120,11 @@ void AirUnit::AIloop()
|
||||
/* State machine */
|
||||
switch (state) {
|
||||
case State::IDLE: {
|
||||
currentTask = L"Idle";
|
||||
currentTask = "Idle";
|
||||
|
||||
if (!getHasTask())
|
||||
{
|
||||
std::wostringstream taskSS;
|
||||
std::ostringstream taskSS;
|
||||
if (isTanker) {
|
||||
taskSS << "{ [1] = { id = 'Tanker' }, [2] = { id = 'Orbit', pattern = 'Race-Track', altitude = " << desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" << desiredAltitudeType << "' } }";
|
||||
}
|
||||
@ -150,23 +141,23 @@ void AirUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
case State::REACH_DESTINATION: {
|
||||
wstring enrouteTask = L"";
|
||||
string enrouteTask = "";
|
||||
bool looping = false;
|
||||
|
||||
if (isTanker)
|
||||
{
|
||||
enrouteTask = L"{ id = 'Tanker' }";
|
||||
currentTask = L"Tanker";
|
||||
enrouteTask = "{ id = 'Tanker' }";
|
||||
currentTask = "Tanker";
|
||||
}
|
||||
else if (isAWACS)
|
||||
{
|
||||
enrouteTask = L"{ id = 'AWACS' }";
|
||||
currentTask = L"AWACS";
|
||||
enrouteTask = "{ id = 'AWACS' }";
|
||||
currentTask = "AWACS";
|
||||
}
|
||||
else
|
||||
{
|
||||
enrouteTask = L"nil";
|
||||
currentTask = L"Reaching destination";
|
||||
enrouteTask = "nil";
|
||||
currentTask = "Reaching destination";
|
||||
}
|
||||
|
||||
if (activeDestination == NULL || !getHasTask())
|
||||
@ -187,8 +178,8 @@ void AirUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
case State::LAND: {
|
||||
wstring enrouteTask = L"{ id = 'Land' }";
|
||||
currentTask = L"Landing";
|
||||
string enrouteTask = "{ id = 'Land' }";
|
||||
currentTask = "Landing";
|
||||
|
||||
if (activeDestination == NULL)
|
||||
{
|
||||
@ -206,13 +197,13 @@ void AirUnit::AIloop()
|
||||
|
||||
/* Attack state is an "enroute" task, meaning the unit will keep trying to attack even if a new destination is set. This is useful to
|
||||
manoeuvre the unit so that it can detect and engage the target. */
|
||||
std::wostringstream enrouteTaskSS;
|
||||
std::ostringstream enrouteTaskSS;
|
||||
enrouteTaskSS << "{"
|
||||
<< "id = 'EngageUnit'" << ","
|
||||
<< "targetID = " << targetID << ","
|
||||
<< "}";
|
||||
wstring enrouteTask = enrouteTaskSS.str();
|
||||
currentTask = L"Attacking " + getTargetName();
|
||||
string enrouteTask = enrouteTaskSS.str();
|
||||
currentTask = "Attacking " + getTargetName();
|
||||
|
||||
if (!getHasTask())
|
||||
{
|
||||
@ -232,13 +223,13 @@ void AirUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
|
||||
currentTask = L"Following " + getTargetName();
|
||||
currentTask = "Following " + getTargetName();
|
||||
|
||||
Unit* leader = unitsManager->getUnit(leaderID);
|
||||
if (!getHasTask()) {
|
||||
if (leader != nullptr && leader->getAlive() && formationOffset != NULL)
|
||||
{
|
||||
std::wostringstream taskSS;
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{"
|
||||
<< "id = 'FollowUnit'" << ", "
|
||||
<< "leaderID = " << leader->getID() << ","
|
||||
@ -256,11 +247,11 @@ void AirUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
case State::REFUEL: {
|
||||
currentTask = L"Refueling";
|
||||
currentTask = "Refueling";
|
||||
|
||||
if (!getHasTask()) {
|
||||
if (fuel <= initialFuel) {
|
||||
std::wostringstream taskSS;
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{"
|
||||
<< "id = 'Refuel'"
|
||||
<< "}";
|
||||
@ -274,22 +265,22 @@ void AirUnit::AIloop()
|
||||
}
|
||||
}
|
||||
case State::BOMB_POINT: {
|
||||
currentTask = L"Bombing point";
|
||||
currentTask = "Bombing point";
|
||||
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'Bombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{id = 'Bombing', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
}
|
||||
case State::CARPET_BOMB: {
|
||||
currentTask = L"Carpet bombing";
|
||||
currentTask = "Carpet bombing";
|
||||
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'CarpetBombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{id = 'CarpetBombing', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
@ -297,11 +288,11 @@ void AirUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
case State::BOMB_BUILDING: {
|
||||
currentTask = L"Bombing building";
|
||||
currentTask = "Bombing building";
|
||||
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'AttackMapObject', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{id = 'AttackMapObject', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
@ -311,6 +302,4 @@ void AirUnit::AIloop()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addMeasure(L"currentTask", json::value(currentTask));
|
||||
}
|
||||
@ -7,10 +7,10 @@
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Move command */
|
||||
wstring Move::getString(lua_State* L)
|
||||
string Move::getString(lua_State* L)
|
||||
{
|
||||
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.move, "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
@ -26,9 +26,9 @@ wstring Move::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Smoke command */
|
||||
wstring Smoke::getString(lua_State* L)
|
||||
string Smoke::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.smoke, "
|
||||
<< "\"" << color << "\"" << ", "
|
||||
@ -38,9 +38,9 @@ wstring Smoke::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Spawn ground command */
|
||||
wstring SpawnGroundUnit::getString(lua_State* L)
|
||||
string SpawnGroundUnit::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.spawnGroundUnit, "
|
||||
<< "\"" << coalition << "\"" << ", "
|
||||
@ -51,16 +51,16 @@ wstring SpawnGroundUnit::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Spawn air command */
|
||||
wstring SpawnAircraft::getString(lua_State* L)
|
||||
string SpawnAircraft::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream optionsSS;
|
||||
std::ostringstream optionsSS;
|
||||
optionsSS.precision(10);
|
||||
optionsSS << "{"
|
||||
<< "payloadName = \"" << payloadName << "\", "
|
||||
<< "airbaseName = \"" << airbaseName << "\", "
|
||||
<< "}";
|
||||
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.spawnAircraft, "
|
||||
<< "\"" << coalition << "\"" << ", "
|
||||
@ -73,12 +73,12 @@ wstring SpawnAircraft::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Clone unit command */
|
||||
wstring Clone::getString(lua_State* L)
|
||||
string Clone::getString(lua_State* L)
|
||||
{
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.clone, "
|
||||
<< ID << ", "
|
||||
@ -89,14 +89,14 @@ wstring Clone::getString(lua_State* L)
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete unit command */
|
||||
wstring Delete::getString(lua_State* L)
|
||||
string Delete::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.delete, "
|
||||
<< ID << ", "
|
||||
@ -105,9 +105,9 @@ wstring Delete::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Set task command */
|
||||
wstring SetTask::getString(lua_State* L)
|
||||
string SetTask::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setTask, "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
@ -117,9 +117,9 @@ wstring SetTask::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Reset task command */
|
||||
wstring ResetTask::getString(lua_State* L)
|
||||
string ResetTask::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.resetTask, "
|
||||
<< "\"" << groupName << "\"";
|
||||
@ -128,9 +128,9 @@ wstring ResetTask::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Set command command */
|
||||
wstring SetCommand::getString(lua_State* L)
|
||||
string SetCommand::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setCommand, "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
@ -140,9 +140,9 @@ wstring SetCommand::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Set option command */
|
||||
wstring SetOption::getString(lua_State* L)
|
||||
string SetOption::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
|
||||
if (!isBoolean) {
|
||||
@ -160,9 +160,9 @@ wstring SetOption::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Set onOff command */
|
||||
wstring SetOnOff::getString(lua_State* L)
|
||||
string SetOnOff::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
|
||||
commandSS << "Olympus.setOnOff, "
|
||||
@ -173,9 +173,9 @@ wstring SetOnOff::getString(lua_State* L)
|
||||
}
|
||||
|
||||
/* Explosion command */
|
||||
wstring Explosion::getString(lua_State* L)
|
||||
string Explosion::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.explosion, "
|
||||
<< intensity << ", "
|
||||
|
||||
@ -10,19 +10,24 @@
|
||||
using namespace std::chrono;
|
||||
|
||||
auto before = std::chrono::system_clock::now();
|
||||
|
||||
/* Singleton objects */
|
||||
UnitsManager* unitsManager = nullptr;
|
||||
Server* server = nullptr;
|
||||
Scheduler* scheduler = nullptr;
|
||||
|
||||
/* Data jsons */
|
||||
json::value airbases;
|
||||
json::value bullseyes;
|
||||
json::value mission;
|
||||
|
||||
mutex mutexLock;
|
||||
bool initialized = false;
|
||||
string sessionHash;
|
||||
int lastUpdateIndex = 0;
|
||||
int frameCounter = 0;
|
||||
|
||||
bool initialized = false;
|
||||
|
||||
unsigned int frameCounter = 0;
|
||||
double frameRate = 30;
|
||||
long long lastUpdateTime = 0;
|
||||
|
||||
/* Called when DCS simulation stops. All singleton instances are deleted. */
|
||||
extern "C" DllExport int coreDeinit(lua_State* L)
|
||||
@ -64,48 +69,29 @@ extern "C" DllExport int coreFrame(lua_State* L)
|
||||
if (!initialized)
|
||||
return (0);
|
||||
|
||||
/* Lock for thread safety */
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
|
||||
frameCounter++;
|
||||
|
||||
/* Slow down the update rate if the frameRate is very low since it means DCS is struggling to keep up */
|
||||
const std::chrono::duration<double> duration = std::chrono::system_clock::now() - before;
|
||||
|
||||
if (unitsManager != nullptr) {
|
||||
// TODO put in a function
|
||||
vector<int> IDs;
|
||||
for (auto iter = unitsManager->getUnits().begin(); iter != unitsManager->getUnits().end(); ++iter)
|
||||
IDs.push_back(iter->first);
|
||||
|
||||
int updateChunk = 20;
|
||||
int finalUpdateIndex = lastUpdateIndex + updateChunk;
|
||||
|
||||
/* Get all the new data (with some margin) */
|
||||
while (lastUpdateIndex < unitsManager->getUnits().size() && lastUpdateIndex <= finalUpdateIndex)
|
||||
unitsManager->appendUnitData(IDs[lastUpdateIndex++], server->getUpdateJson(), lastUpdateTime - 1000);
|
||||
}
|
||||
|
||||
if (duration.count() > UPDATE_TIME_INTERVAL && lastUpdateIndex == unitsManager->getUnits().size())
|
||||
if (duration.count() > UPDATE_TIME_INTERVAL * (60.0 / frameRate))
|
||||
{
|
||||
/* Lock for thread safety */
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
lastUpdateTime = ms.count();
|
||||
frameRate = frameCounter / duration.count();
|
||||
frameCounter = 0;
|
||||
|
||||
if (unitsManager != nullptr)
|
||||
if (unitsManager != nullptr) {
|
||||
unitsManager->updateExportData(L, duration.count());
|
||||
unitsManager->runAILoop();
|
||||
}
|
||||
before = std::chrono::system_clock::now();
|
||||
|
||||
/* Restart the update counter */
|
||||
lastUpdateIndex = 0;
|
||||
}
|
||||
|
||||
if (scheduler != nullptr)
|
||||
scheduler->execute(L);
|
||||
|
||||
if (duration.count() > UPDATE_TIME_INTERVAL && unitsManager != nullptr)
|
||||
unitsManager->runAILoop();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@ -13,16 +13,15 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Ground unit */
|
||||
GroundUnit::GroundUnit(json::value json, int ID) : Unit(json, ID)
|
||||
GroundUnit::GroundUnit(json::value json, unsigned int ID) : Unit(json, ID)
|
||||
{
|
||||
log("New Ground Unit created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
|
||||
double desiredSpeed = 10;
|
||||
setDesiredSpeed(desiredSpeed);
|
||||
};
|
||||
|
||||
void GroundUnit::setState(int newState)
|
||||
void GroundUnit::setState(unsigned char newState)
|
||||
{
|
||||
/************ Perform any action required when LEAVING a state ************/
|
||||
if (newState != state) {
|
||||
@ -34,7 +33,7 @@ void GroundUnit::setState(int newState)
|
||||
break;
|
||||
}
|
||||
case State::FIRE_AT_AREA: {
|
||||
setTargetLocation(Coords(NULL));
|
||||
setTargetPosition(Coords(NULL));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -47,16 +46,13 @@ void GroundUnit::setState(int newState)
|
||||
case State::IDLE: {
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Idle"));
|
||||
break;
|
||||
}
|
||||
case State::REACH_DESTINATION: {
|
||||
resetActiveDestination();
|
||||
addMeasure(L"currentState", json::value(L"Reach destination"));
|
||||
break;
|
||||
}
|
||||
case State::FIRE_AT_AREA: {
|
||||
addMeasure(L"currentState", json::value(L"Firing at area"));
|
||||
clearActivePath();
|
||||
resetActiveDestination();
|
||||
break;
|
||||
@ -67,7 +63,7 @@ void GroundUnit::setState(int newState)
|
||||
|
||||
resetTask();
|
||||
|
||||
log(unitName + L" setting state from " + to_wstring(state) + L" to " + to_wstring(newState));
|
||||
log(unitName + " setting state from " + to_string(state) + " to " + to_string(newState));
|
||||
state = newState;
|
||||
}
|
||||
|
||||
@ -75,16 +71,16 @@ void GroundUnit::AIloop()
|
||||
{
|
||||
switch (state) {
|
||||
case State::IDLE: {
|
||||
currentTask = L"Idle";
|
||||
currentTask = "Idle";
|
||||
if (getHasTask())
|
||||
resetTask();
|
||||
break;
|
||||
}
|
||||
case State::REACH_DESTINATION: {
|
||||
wstring enrouteTask = L"";
|
||||
string enrouteTask = "";
|
||||
bool looping = false;
|
||||
|
||||
std::wostringstream taskSS;
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{ id = 'FollowRoads', value = " << (getFollowRoads() ? "true" : "false") << " }";
|
||||
enrouteTask = taskSS.str();
|
||||
|
||||
@ -106,11 +102,11 @@ void GroundUnit::AIloop()
|
||||
break;
|
||||
}
|
||||
case State::FIRE_AT_AREA: {
|
||||
currentTask = L"Firing at area";
|
||||
currentTask = "Firing at area";
|
||||
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'FireAtPoint', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << ", radius = 1000}";
|
||||
std::ostringstream taskSS;
|
||||
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 1000}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
@ -119,17 +115,15 @@ void GroundUnit::AIloop()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addMeasure(L"currentTask", json::value(currentTask));
|
||||
}
|
||||
|
||||
void GroundUnit::changeSpeed(wstring change)
|
||||
void GroundUnit::changeSpeed(string change)
|
||||
{
|
||||
if (change.compare(L"stop") == 0)
|
||||
if (change.compare("stop") == 0)
|
||||
setState(State::IDLE);
|
||||
else if (change.compare(L"slow") == 0)
|
||||
else if (change.compare("slow") == 0)
|
||||
setDesiredSpeed(getDesiredSpeed() - knotsToMs(5));
|
||||
else if (change.compare(L"fast") == 0)
|
||||
else if (change.compare("fast") == 0)
|
||||
setDesiredSpeed(getDesiredSpeed() + knotsToMs(5));
|
||||
|
||||
if (getDesiredSpeed() < 0)
|
||||
|
||||
@ -13,10 +13,9 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Helicopter */
|
||||
Helicopter::Helicopter(json::value json, int ID) : AirUnit(json, ID)
|
||||
Helicopter::Helicopter(json::value json, unsigned int ID) : AirUnit(json, ID)
|
||||
{
|
||||
log("New Helicopter created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
|
||||
double desiredSpeed = knotsToMs(100);
|
||||
double desiredAltitude = ftToM(5000);
|
||||
@ -24,16 +23,16 @@ Helicopter::Helicopter(json::value json, int ID) : AirUnit(json, ID)
|
||||
setDesiredAltitude(desiredAltitude);
|
||||
};
|
||||
|
||||
void Helicopter::changeSpeed(wstring change)
|
||||
void Helicopter::changeSpeed(string change)
|
||||
{
|
||||
if (change.compare(L"stop") == 0)
|
||||
if (change.compare("stop") == 0)
|
||||
{
|
||||
/* Air units can't hold a position, so we can only set them to hold. At the moment, this will erase any other command. TODO: helicopters should be able to hover in place */
|
||||
clearActivePath();
|
||||
}
|
||||
else if (change.compare(L"slow") == 0)
|
||||
else if (change.compare("slow") == 0)
|
||||
desiredSpeed -= knotsToMs(10);
|
||||
else if (change.compare(L"fast") == 0)
|
||||
else if (change.compare("fast") == 0)
|
||||
desiredSpeed += knotsToMs(10);
|
||||
if (desiredSpeed < 0)
|
||||
desiredSpeed = 0;
|
||||
@ -41,16 +40,16 @@ void Helicopter::changeSpeed(wstring change)
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Helicopter::changeAltitude(wstring change)
|
||||
void Helicopter::changeAltitude(string change)
|
||||
{
|
||||
if (change.compare(L"descend") == 0)
|
||||
if (change.compare("descend") == 0)
|
||||
{
|
||||
if (desiredAltitude > 100)
|
||||
desiredAltitude -= ftToM(100);
|
||||
else if (desiredAltitude > 0)
|
||||
desiredAltitude -= ftToM(10);
|
||||
}
|
||||
else if (change.compare(L"climb") == 0)
|
||||
else if (change.compare("climb") == 0)
|
||||
{
|
||||
if (desiredAltitude > 100)
|
||||
desiredAltitude += ftToM(100);
|
||||
|
||||
@ -13,10 +13,9 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Navy Unit */
|
||||
NavyUnit::NavyUnit(json::value json, int ID) : Unit(json, ID)
|
||||
NavyUnit::NavyUnit(json::value json, unsigned int ID) : Unit(json, ID)
|
||||
{
|
||||
log("New Navy Unit created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
|
||||
double desiredSpeed = 10;
|
||||
setDesiredSpeed(desiredSpeed);
|
||||
@ -27,17 +26,17 @@ void NavyUnit::AIloop()
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void NavyUnit::changeSpeed(wstring change)
|
||||
void NavyUnit::changeSpeed(string change)
|
||||
{
|
||||
if (change.compare(L"stop") == 0)
|
||||
if (change.compare("stop") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
else if (change.compare(L"slow") == 0)
|
||||
else if (change.compare("slow") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
else if (change.compare(L"fast") == 0)
|
||||
else if (change.compare("fast") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@ -32,16 +32,16 @@ void Scheduler::execute(lua_State* L)
|
||||
return;
|
||||
}
|
||||
|
||||
int priority = CommandPriority::IMMEDIATE;
|
||||
unsigned int priority = CommandPriority::IMMEDIATE;
|
||||
while (priority >= CommandPriority::LOW)
|
||||
{
|
||||
for (auto command : commands)
|
||||
{
|
||||
if (command->getPriority() == priority)
|
||||
{
|
||||
wstring commandString = L"Olympus.protectedCall(" + command->getString(L) + L")";
|
||||
if (dostring_in(L, "server", to_string(commandString)))
|
||||
log(L"Error executing command " + commandString);
|
||||
string commandString = "Olympus.protectedCall(" + command->getString(L) + ")";
|
||||
if (dostring_in(L, "server", (commandString)))
|
||||
log("Error executing command " + commandString);
|
||||
load = command->getLoad();
|
||||
commands.remove(command);
|
||||
return;
|
||||
@ -51,81 +51,81 @@ void Scheduler::execute(lua_State* L)
|
||||
}
|
||||
}
|
||||
|
||||
void Scheduler::handleRequest(wstring key, json::value value)
|
||||
void Scheduler::handleRequest(string key, json::value value)
|
||||
{
|
||||
Command* command = nullptr;
|
||||
|
||||
log(L"Received request with ID: " + key);
|
||||
if (key.compare(L"setPath") == 0)
|
||||
log("Received request with ID: " + key);
|
||||
if (key.compare("setPath") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
wstring unitName = unit->getUnitName();
|
||||
string unitName = unit->getUnitName();
|
||||
json::value path = value[L"path"];
|
||||
list<Coords> newPath;
|
||||
for (int i = 1; i <= path.as_object().size(); i++)
|
||||
for (unsigned int i = 1; i <= path.as_object().size(); i++)
|
||||
{
|
||||
wstring WP = to_wstring(i);
|
||||
double lat = path[WP][L"lat"].as_double();
|
||||
double lng = path[WP][L"lng"].as_double();
|
||||
log(unitName + L" set path destination " + WP + L" (" + to_wstring(lat) + L", " + to_wstring(lng) + L")");
|
||||
string WP = to_string(i);
|
||||
double lat = path[to_wstring(i)][L"lat"].as_double();
|
||||
double lng = path[to_wstring(i)][L"lng"].as_double();
|
||||
log(unitName + " set path destination " + WP + " (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||
Coords dest; dest.lat = lat; dest.lng = lng;
|
||||
newPath.push_back(dest);
|
||||
}
|
||||
|
||||
unit->setActivePath(newPath);
|
||||
unit->setState(State::REACH_DESTINATION);
|
||||
log(unitName + L" new path set successfully");
|
||||
log(unitName + " new path set successfully");
|
||||
}
|
||||
}
|
||||
else if (key.compare(L"smoke") == 0)
|
||||
else if (key.compare("smoke") == 0)
|
||||
{
|
||||
wstring color = value[L"color"].as_string();
|
||||
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();
|
||||
log(L"Adding " + color + L" smoke at (" + to_wstring(lat) + L", " + to_wstring(lng) + L")");
|
||||
log("Adding " + color + " smoke at (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
command = dynamic_cast<Command*>(new Smoke(color, loc));
|
||||
}
|
||||
else if (key.compare(L"spawnGround") == 0)
|
||||
else if (key.compare("spawnGround") == 0)
|
||||
{
|
||||
bool immediate = value[L"immediate"].as_bool();
|
||||
wstring coalition = value[L"coalition"].as_string();
|
||||
wstring type = value[L"type"].as_string();
|
||||
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(L"Spawning " + coalition + L" ground unit of type " + type + L" at (" + to_wstring(lat) + L", " + to_wstring(lng) + L")");
|
||||
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));
|
||||
}
|
||||
else if (key.compare(L"spawnAir") == 0)
|
||||
else if (key.compare("spawnAir") == 0)
|
||||
{
|
||||
bool immediate = value[L"immediate"].as_bool();
|
||||
wstring coalition = value[L"coalition"].as_string();
|
||||
wstring type = value[L"type"].as_string();
|
||||
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;
|
||||
wstring payloadName = value[L"payloadName"].as_string();
|
||||
wstring airbaseName = value[L"airbaseName"].as_string();
|
||||
log(L"Spawning " + coalition + L" air unit of type " + type + L" with payload " + payloadName + L" at (" + to_wstring(lat) + L", " + to_wstring(lng) + L" " + airbaseName + L")");
|
||||
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));
|
||||
}
|
||||
else if (key.compare(L"attackUnit") == 0)
|
||||
else if (key.compare("attackUnit") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
int targetID = value[L"targetID"].as_integer();
|
||||
unsigned int targetID = value[L"targetID"].as_integer();
|
||||
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
Unit* target = unitsManager->getUnit(targetID);
|
||||
|
||||
wstring unitName;
|
||||
wstring targetName;
|
||||
string unitName;
|
||||
string targetName;
|
||||
|
||||
if (unit != nullptr)
|
||||
unitName = unit->getUnitName();
|
||||
@ -137,24 +137,24 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
else
|
||||
return;
|
||||
|
||||
log(L"Unit " + unitName + L" attacking unit " + targetName);
|
||||
log("Unit " + unitName + " attacking unit " + targetName);
|
||||
unit->setTargetID(targetID);
|
||||
unit->setState(State::ATTACK);
|
||||
}
|
||||
else if (key.compare(L"followUnit") == 0)
|
||||
else if (key.compare("followUnit") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
int leaderID = value[L"targetID"].as_integer();
|
||||
int offsetX = value[L"offsetX"].as_integer();
|
||||
int offsetY = value[L"offsetY"].as_integer();
|
||||
int offsetZ = value[L"offsetZ"].as_integer();
|
||||
unsigned int leaderID = value[L"targetID"].as_integer();
|
||||
unsigned int offsetX = value[L"offsetX"].as_integer();
|
||||
unsigned int offsetY = value[L"offsetY"].as_integer();
|
||||
unsigned int offsetZ = value[L"offsetZ"].as_integer();
|
||||
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
Unit* leader = unitsManager->getUnit(leaderID);
|
||||
|
||||
wstring unitName;
|
||||
wstring leaderName;
|
||||
string unitName;
|
||||
string leaderName;
|
||||
|
||||
if (unit != nullptr)
|
||||
unitName = unit->getUnitName();
|
||||
@ -166,95 +166,95 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
else
|
||||
return;
|
||||
|
||||
log(L"Unit " + unitName + L" following unit " + leaderName);
|
||||
log("Unit " + unitName + " following unit " + leaderName);
|
||||
unit->setFormationOffset(Offset(offsetX, offsetY, offsetZ));
|
||||
unit->setLeaderID(leaderID);
|
||||
unit->setState(State::FOLLOW);
|
||||
}
|
||||
else if (key.compare(L"changeSpeed") == 0)
|
||||
else if (key.compare("changeSpeed") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->changeSpeed(value[L"change"].as_string());
|
||||
unit->changeSpeed(to_string(value[L"change"]));
|
||||
}
|
||||
else if (key.compare(L"changeAltitude") == 0)
|
||||
else if (key.compare("changeAltitude") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->changeAltitude(value[L"change"].as_string());
|
||||
unit->changeAltitude(to_string(value[L"change"]));
|
||||
}
|
||||
else if (key.compare(L"setSpeed") == 0)
|
||||
else if (key.compare("setSpeed") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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());
|
||||
}
|
||||
else if (key.compare(L"setSpeedType") == 0)
|
||||
else if (key.compare("setSpeedType") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setDesiredSpeedType(value[L"speedType"].as_string());
|
||||
unit->setDesiredSpeedType(to_string(value[L"speedType"]));
|
||||
}
|
||||
else if (key.compare(L"setAltitude") == 0)
|
||||
else if (key.compare("setAltitude") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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());
|
||||
}
|
||||
else if (key.compare(L"setAltitudeType") == 0)
|
||||
else if (key.compare("setAltitudeType") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setDesiredAltitudeType(value[L"altitudeType"].as_string());
|
||||
unit->setDesiredAltitudeType(to_string(value[L"altitudeType"]));
|
||||
}
|
||||
else if (key.compare(L"cloneUnit") == 0)
|
||||
else if (key.compare("cloneUnit") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].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;
|
||||
command = dynamic_cast<Command*>(new Clone(ID, loc));
|
||||
log(L"Cloning unit " + to_wstring(ID));
|
||||
log("Cloning unit " + to_string(ID));
|
||||
}
|
||||
else if (key.compare(L"setROE") == 0)
|
||||
else if (key.compare("setROE") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring ROE = value[L"ROE"].as_string();
|
||||
unsigned char ROE = value[L"ROE"].as_number().is_uint32();
|
||||
unit->setROE(ROE);
|
||||
}
|
||||
else if (key.compare(L"setReactionToThreat") == 0)
|
||||
else if (key.compare("setReactionToThreat") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring reactionToThreat = value[L"reactionToThreat"].as_string();
|
||||
unsigned char reactionToThreat = value[L"reactionToThreat"].as_number().is_uint32();
|
||||
unit->setReactionToThreat(reactionToThreat);
|
||||
}
|
||||
else if (key.compare(L"setEmissionsCountermeasures") == 0)
|
||||
else if (key.compare("setEmissionsCountermeasures") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring emissionsCountermeasures = value[L"emissionsCountermeasures"].as_string();
|
||||
unsigned char emissionsCountermeasures = value[L"emissionsCountermeasures"].as_number().is_uint32();
|
||||
unit->setEmissionsCountermeasures(emissionsCountermeasures);
|
||||
}
|
||||
else if (key.compare(L"landAt") == 0)
|
||||
else if (key.compare("landAt") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
@ -262,22 +262,22 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
unit->landAt(loc);
|
||||
}
|
||||
else if (key.compare(L"deleteUnit") == 0)
|
||||
else if (key.compare("deleteUnit") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
bool explosion = value[L"explosion"].as_bool();
|
||||
unitsManager->deleteUnit(ID, explosion);
|
||||
}
|
||||
else if (key.compare(L"refuel") == 0)
|
||||
else if (key.compare("refuel") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::REFUEL);
|
||||
}
|
||||
else if (key.compare(L"setAdvancedOptions") == 0)
|
||||
else if (key.compare("setAdvancedOptions") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
@ -287,18 +287,21 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
unit->setIsAWACS(value[L"isAWACS"].as_bool());
|
||||
|
||||
/* TACAN Options */
|
||||
auto TACAN = value[L"TACAN"];
|
||||
unit->setTACAN({ TACAN[L"isOn"].as_bool(),
|
||||
TACAN[L"channel"].as_number().to_int32(),
|
||||
TACAN[L"XY"].as_string(),
|
||||
TACAN[L"callsign"].as_string()
|
||||
});
|
||||
Options::TACAN TACAN;
|
||||
TACAN.isOn = value[L"TACAN"][L"isOn"].as_bool();
|
||||
TACAN.channel = static_cast<unsigned char>(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_int32(),
|
||||
radio[L"callsign"].as_number().to_int32(),
|
||||
radio[L"callsignNumber"].as_number().to_int32()
|
||||
unit->setRadio({ radio[L"frequency"].as_number().to_uint32(),
|
||||
static_cast<unsigned char>(radio[L"callsign"].as_number().to_uint32()),
|
||||
static_cast<unsigned char>(radio[L"callsignNumber"].as_number().to_uint32())
|
||||
});
|
||||
|
||||
/* General Settings */
|
||||
@ -313,78 +316,78 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
unit->resetActiveDestination();
|
||||
}
|
||||
}
|
||||
else if (key.compare(L"setFollowRoads") == 0)
|
||||
else if (key.compare("setFollowRoads") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
bool followRoads = value[L"followRoads"].as_bool();
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setFollowRoads(followRoads);
|
||||
}
|
||||
else if (key.compare(L"setOnOff") == 0)
|
||||
else if (key.compare("setOnOff") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
unitsManager->acquireControl(ID);
|
||||
bool onOff = value[L"onOff"].as_bool();
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setOnOff(onOff);
|
||||
}
|
||||
else if (key.compare(L"explosion") == 0)
|
||||
else if (key.compare("explosion") == 0)
|
||||
{
|
||||
int intensity = value[L"intensity"].as_integer();
|
||||
unsigned int intensity = value[L"intensity"].as_integer();
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
log(L"Adding " + to_wstring(intensity) + L" explosion at (" + to_wstring(lat) + L", " + to_wstring(lng) + L")");
|
||||
log("Adding " + to_string(intensity) + " explosion at (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
command = dynamic_cast<Command*>(new Explosion(intensity, loc));
|
||||
}
|
||||
else if (key.compare(L"bombPoint") == 0)
|
||||
else if (key.compare("bombPoint") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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);
|
||||
unit->setState(State::BOMB_POINT);
|
||||
unit->setTargetLocation(loc);
|
||||
unit->setTargetPosition(loc);
|
||||
}
|
||||
else if (key.compare(L"carpetBomb") == 0)
|
||||
else if (key.compare("carpetBomb") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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);
|
||||
unit->setState(State::CARPET_BOMB);
|
||||
unit->setTargetLocation(loc);
|
||||
unit->setTargetPosition(loc);
|
||||
}
|
||||
else if (key.compare(L"bombBuilding") == 0)
|
||||
else if (key.compare("bombBuilding") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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);
|
||||
unit->setState(State::BOMB_BUILDING);
|
||||
unit->setTargetLocation(loc);
|
||||
unit->setTargetPosition(loc);
|
||||
}
|
||||
else if (key.compare(L"fireAtArea") == 0)
|
||||
else if (key.compare("fireAtArea") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
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);
|
||||
unit->setState(State::FIRE_AT_AREA);
|
||||
unit->setTargetLocation(loc);
|
||||
unit->setTargetPosition(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(L"Unknown command: " + key);
|
||||
log("Unknown command: " + key);
|
||||
}
|
||||
|
||||
if (command != nullptr)
|
||||
|
||||
@ -13,10 +13,12 @@ bool executeLuaScript(lua_State* L, string path)
|
||||
if (dostring_in(L, "server", str.c_str()) != 0)
|
||||
{
|
||||
log("Error registering " + path);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
log(path + " registered successfully");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -36,8 +36,7 @@ Server::Server(lua_State* L):
|
||||
serverThread(nullptr),
|
||||
runListener(true)
|
||||
{
|
||||
refreshJson = json::value::object();
|
||||
updateJson = json::value::object();
|
||||
|
||||
}
|
||||
|
||||
void Server::start(lua_State* L)
|
||||
@ -71,8 +70,8 @@ void Server::handle_get(http_request request)
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
|
||||
http_response response(status_codes::OK);
|
||||
string authorization = to_base64("admin:" + to_string(password));
|
||||
if (password == L"" || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second == L"Basic " + to_wstring(authorization)))
|
||||
string authorization = to_base64("admin:" + password);
|
||||
if (password == "" || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second == L"Basic " + to_wstring(authorization)))
|
||||
{
|
||||
std::exception_ptr eptr;
|
||||
try {
|
||||
@ -81,7 +80,8 @@ void Server::handle_get(http_request request)
|
||||
|
||||
if (path.size() > 0)
|
||||
{
|
||||
if (path[0] == UNITS_URI)
|
||||
string URI = to_string(path[0]);
|
||||
if (URI.compare(UNITS_URI) == 0)
|
||||
{
|
||||
map<utility::string_t, utility::string_t> query = request.relative_uri().split_query(request.relative_uri().query());
|
||||
long long time = 0;
|
||||
@ -94,22 +94,21 @@ void Server::handle_get(http_request request)
|
||||
time = 0;
|
||||
}
|
||||
}
|
||||
if (time == 0)
|
||||
unitsManager->getUnitData(answer, 0);
|
||||
else
|
||||
answer[L"units"] = updateJson;
|
||||
|
||||
// TODO would be nice to optimize this
|
||||
answer[L"units"] = json::value(to_wstring(unitsManager->getUnitData(time == 0)));
|
||||
}
|
||||
else if (path[0] == LOGS_URI)
|
||||
else if (URI.compare(LOGS_URI) == 0)
|
||||
{
|
||||
auto logs = json::value::object();
|
||||
getLogsJSON(logs, 100); // By reference, for thread safety. Get the last 100 log entries
|
||||
answer[L"logs"] = logs;
|
||||
}
|
||||
else if (path[0] == AIRBASES_URI)
|
||||
else if (URI.compare(AIRBASES_URI) == 0)
|
||||
answer[L"airbases"] = airbases;
|
||||
else if (path[0] == BULLSEYE_URI)
|
||||
else if (URI.compare(BULLSEYE_URI) == 0)
|
||||
answer[L"bullseyes"] = bullseyes;
|
||||
else if (path[0] == MISSION_URI)
|
||||
else if (URI.compare(MISSION_URI) == 0)
|
||||
answer[L"mission"] = mission;
|
||||
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
@ -139,8 +138,8 @@ 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:" + to_string(password));
|
||||
if (password == L"" || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second == L"Basic " + to_wstring(authorization)))
|
||||
string authorization = to_base64("admin:" + password);
|
||||
if (password == "" || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second.compare(L"Basic " + to_wstring(authorization))))
|
||||
{
|
||||
auto answer = json::value::object();
|
||||
request.extract_json().then([&answer, &action](pplx::task<json::value> task)
|
||||
@ -148,11 +147,8 @@ void Server::handle_request(http_request request, function<void(json::value cons
|
||||
try
|
||||
{
|
||||
auto const& jvalue = task.get();
|
||||
|
||||
if (!jvalue.is_null())
|
||||
{
|
||||
action(jvalue, answer);
|
||||
}
|
||||
}
|
||||
catch (http_exception const& e)
|
||||
{
|
||||
@ -188,7 +184,7 @@ void Server::handle_put(http_request request)
|
||||
auto value = e.second;
|
||||
std::exception_ptr eptr;
|
||||
try {
|
||||
scheduler->handleRequest(key, value);
|
||||
scheduler->handleRequest(to_string(key), value);
|
||||
}
|
||||
catch (...) {
|
||||
eptr = std::current_exception(); // capture
|
||||
@ -200,8 +196,8 @@ void Server::handle_put(http_request request)
|
||||
|
||||
void Server::task()
|
||||
{
|
||||
wstring address = wstring(REST_ADDRESS);
|
||||
wstring modLocation;
|
||||
string address = REST_ADDRESS;
|
||||
string modLocation;
|
||||
char* buf = nullptr;
|
||||
size_t sz = 0;
|
||||
if (_dupenv_s(&buf, &sz, "DCSOLYMPUS_PATH") == 0 && buf != nullptr)
|
||||
@ -210,31 +206,31 @@ void Server::task()
|
||||
std::stringstream ss;
|
||||
ss << ifstream.rdbuf();
|
||||
std::error_code errorCode;
|
||||
json::value config = json::value::parse(to_wstring(ss.str()), errorCode);
|
||||
json::value config = json::value::parse(ss.str(), errorCode);
|
||||
if (config.is_object() && config.has_object_field(L"server") &&
|
||||
config[L"server"].has_string_field(L"address") && config[L"server"].has_number_field(L"port"))
|
||||
{
|
||||
address = L"http://" + config[L"server"][L"address"].as_string() + L":" + to_wstring(config[L"server"][L"port"].as_number().to_int32());
|
||||
log(L"Starting server on " + address);
|
||||
address = "http://" + to_string(config[L"server"][L"address"]) + ":" + to_string(config[L"server"][L"port"].as_number().to_int32());
|
||||
log("Starting server on " + address);
|
||||
}
|
||||
else
|
||||
log(L"Error reading configuration file. Starting server on " + address);
|
||||
log("Error reading configuration file. Starting server on " + address);
|
||||
|
||||
if (config.is_object() && config.has_object_field(L"authentication") &&
|
||||
config[L"authentication"].has_string_field(L"password"))
|
||||
{
|
||||
password = config[L"authentication"][L"password"].as_string();
|
||||
password = to_string(config[L"authentication"][L"password"]);
|
||||
}
|
||||
else
|
||||
log(L"Error reading configuration file. No password set.");
|
||||
log("Error reading configuration file. No password set.");
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(L"DCSOLYMPUS_PATH environment variable is missing, starting server on " + address);
|
||||
log("DCSOLYMPUS_PATH environment variable is missing, starting server on " + address);
|
||||
}
|
||||
|
||||
http_listener listener(address + L"/" + wstring(REST_URI));
|
||||
http_listener listener(to_wstring(address + "/" + REST_URI));
|
||||
|
||||
std::function<void(http_request)> handle_options = std::bind(&Server::handle_options, this, std::placeholders::_1);
|
||||
std::function<void(http_request)> handle_get = std::bind(&Server::handle_get, this, std::placeholders::_1);
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
#include "defines.h"
|
||||
#include "unitsmanager.h"
|
||||
|
||||
#include "base64.hpp"
|
||||
using namespace base64;
|
||||
|
||||
#include <chrono>
|
||||
using namespace std::chrono;
|
||||
|
||||
@ -32,7 +35,7 @@ bool operator==(const Options::GeneralSettings& lhs, const Options::GeneralSetti
|
||||
lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison;
|
||||
}
|
||||
|
||||
Unit::Unit(json::value json, int ID) :
|
||||
Unit::Unit(json::value json, unsigned int ID) :
|
||||
ID(ID)
|
||||
{
|
||||
log("Creating unit with ID: " + to_string(ID));
|
||||
@ -55,18 +58,19 @@ void Unit::setDefaults(bool force)
|
||||
const bool isUnitAlive = getAlive();
|
||||
const bool isUnitLeader = unitsManager->isUnitGroupLeader(this);
|
||||
const bool isUnitLeaderOfAGroupWithOtherUnits = unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this);
|
||||
const bool isUnitHuman = getFlags()[L"Human"].as_bool();
|
||||
if (isUnitControlledByOlympus && (isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits) && isUnitLeader && !isUnitHuman) {
|
||||
|
||||
if (isUnitControlledByOlympus && (isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits) && isUnitLeader && !human) {
|
||||
/* Set the default IDLE state */
|
||||
setState(State::IDLE);
|
||||
|
||||
/* Set desired altitude to be equal to current altitude so the unit does not climb/descend after spawn */
|
||||
setDesiredAltitude(altitude);
|
||||
setDesiredAltitude(position.alt);
|
||||
|
||||
/* Set the default options (these are all defaults so will only affect the export data, no DCS command will be sent) */
|
||||
setROE(L"Designated", force);
|
||||
setReactionToThreat(L"Evade", force);
|
||||
setEmissionsCountermeasures(L"Defend", force);
|
||||
setROE(ROE::OPEN_FIRE_WEAPON_FREE, force);
|
||||
setReactionToThreat(ReactionToThreat::EVADE_FIRE, force);
|
||||
setEmissionsCountermeasures(EmissionCountermeasure::DEFEND, force);
|
||||
strcpy_s(TACAN.callsign, 4, "TKR");
|
||||
setTACAN(TACAN, force);
|
||||
setRadio(radio, force);
|
||||
setEPLRS(EPLRS, force);
|
||||
@ -76,28 +80,13 @@ void Unit::setDefaults(bool force)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::addMeasure(wstring key, json::value value)
|
||||
{
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
if (measures.find(key) == measures.end())
|
||||
measures[key] = new Measure(value, ms.count());
|
||||
else
|
||||
{
|
||||
if (measures[key]->getValue() != value)
|
||||
{
|
||||
measures[key]->setValue(value);
|
||||
measures[key]->setTime(ms.count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::runAILoop() {
|
||||
/* If the unit is alive, controlled and it is not a human, run the AI Loop that performs the requested commands and instructions (moving, attacking, etc) */
|
||||
if (!getControlled()) return;
|
||||
if (!unitsManager->isUnitGroupLeader(this)) return;
|
||||
if (getFlags()[L"Human"].as_bool()) return;
|
||||
if (human) return;
|
||||
|
||||
// Keep running the AI loop even if the unit is dead if it is the leader of a group which has other members in it
|
||||
/* Keep running the AI loop even if the unit is dead if it is the leader of a group which has other members in it */
|
||||
const bool isUnitAlive = getAlive();
|
||||
const bool isUnitLeaderOfAGroupWithOtherUnits = unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this);
|
||||
if (!(isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits)) return;
|
||||
@ -114,146 +103,182 @@ void Unit::updateExportData(json::value json, double dt)
|
||||
if (oldPosition != NULL)
|
||||
{
|
||||
double dist = 0;
|
||||
Geodesic::WGS84().Inverse(latitude, longitude, oldPosition.lat, oldPosition.lng, dist);
|
||||
Geodesic::WGS84().Inverse(getPosition().lat, getPosition().lng, oldPosition.lat, oldPosition.lng, dist);
|
||||
if (dt > 0)
|
||||
setSpeed(getSpeed() * 0.95 + (dist / dt) * 0.05);
|
||||
}
|
||||
oldPosition = Coords(latitude, longitude, altitude);
|
||||
oldPosition = position;
|
||||
|
||||
if (json.has_string_field(L"Name"))
|
||||
setName(json[L"Name"].as_string());
|
||||
setName(to_string(json[L"Name"]));
|
||||
if (json.has_string_field(L"UnitName"))
|
||||
setUnitName(json[L"UnitName"].as_string());
|
||||
setUnitName(to_string(json[L"UnitName"]));
|
||||
if (json.has_string_field(L"GroupName"))
|
||||
setGroupName(json[L"GroupName"].as_string());
|
||||
if (json.has_object_field(L"Type"))
|
||||
setType(json[L"Type"]);
|
||||
setGroupName(to_string(json[L"GroupName"]));
|
||||
if (json.has_number_field(L"Country"))
|
||||
setCountry(json[L"Country"].as_number().to_int32());
|
||||
if (json.has_number_field(L"CoalitionID"))
|
||||
setCoalitionID(json[L"CoalitionID"].as_number().to_int32());
|
||||
if (json.has_object_field(L"LatLongAlt"))
|
||||
{
|
||||
setLatitude(json[L"LatLongAlt"][L"Lat"].as_number().to_double());
|
||||
setLongitude(json[L"LatLongAlt"][L"Long"].as_number().to_double());
|
||||
setAltitude(json[L"LatLongAlt"][L"Alt"].as_number().to_double());
|
||||
Coords position = {
|
||||
json[L"LatLongAlt"][L"Lat"].as_number().to_double(),
|
||||
json[L"LatLongAlt"][L"Long"].as_number().to_double(),
|
||||
json[L"LatLongAlt"][L"Alt"].as_number().to_double()
|
||||
};
|
||||
setPosition(position);
|
||||
}
|
||||
if (json.has_number_field(L"Heading"))
|
||||
setHeading(json[L"Heading"].as_number().to_double());
|
||||
if (json.has_object_field(L"Flags"))
|
||||
setFlags(json[L"Flags"]);
|
||||
setHuman(json[L"Flags"][L"Human"].as_bool());
|
||||
|
||||
/* All units which contain the name "Olympus" are automatically under AI control */
|
||||
if (getUnitName().find(L"Olympus") != wstring::npos)
|
||||
if (getUnitName().find("Olympus") != string::npos)
|
||||
setControlled(true);
|
||||
}
|
||||
|
||||
void Unit::updateMissionData(json::value json)
|
||||
{
|
||||
if (json.has_number_field(L"fuel"))
|
||||
setFuel(int(json[L"fuel"].as_number().to_double() * 100));
|
||||
if (json.has_object_field(L"ammo"))
|
||||
setAmmo(json[L"ammo"]);
|
||||
if (json.has_object_field(L"contacts"))
|
||||
setContacts(json[L"contacts"]);
|
||||
setFuel(short(json[L"fuel"].as_number().to_double() * 100));
|
||||
|
||||
if (json.has_object_field(L"ammo")) {
|
||||
vector<DataTypes::Ammo> ammo;
|
||||
for (auto const& el : json[L"ammo"].as_object()) {
|
||||
DataTypes::Ammo ammoItem;
|
||||
auto ammoJson = el.second;
|
||||
ammoItem.quantity = ammoJson[L"count"].as_number().to_uint32();
|
||||
ammoItem.name = to_string(ammoJson[L"desc"][L"displayName"]);
|
||||
ammoItem.guidance = ammoJson[L"desc"][L"guidance"].as_number().to_uint32();
|
||||
ammoItem.category = ammoJson[L"desc"][L"category"].as_number().to_uint32();
|
||||
ammoItem.missileCategory = ammoJson[L"desc"][L"missileCategory"].as_number().to_uint32();
|
||||
ammo.push_back(ammoItem);
|
||||
}
|
||||
setAmmo(ammo);
|
||||
}
|
||||
|
||||
if (json.has_object_field(L"contacts")) {
|
||||
vector<DataTypes::Contact> contacts;
|
||||
for (auto const& el : json[L"ammo"].as_object()) {
|
||||
DataTypes::Contact contactItem;
|
||||
auto contactJson = el.second;
|
||||
contactItem.ID = contactJson[L"object"][L"id_"].as_number().to_uint32();
|
||||
|
||||
string detectionMethod = to_string(contactJson[L"detectionMethod"]);
|
||||
if (detectionMethod.compare("VISUAL")) contactItem.detectionMethod = 1;
|
||||
else if (detectionMethod.compare("OPTIC")) contactItem.detectionMethod = 2;
|
||||
else if (detectionMethod.compare("RADAR")) contactItem.detectionMethod = 4;
|
||||
else if (detectionMethod.compare("IRST")) contactItem.detectionMethod = 8;
|
||||
else if (detectionMethod.compare("RWR")) contactItem.detectionMethod = 16;
|
||||
else if (detectionMethod.compare("DLINK")) contactItem.detectionMethod = 32;
|
||||
contacts.push_back(contactItem);
|
||||
}
|
||||
setContacts(contacts);
|
||||
}
|
||||
|
||||
if (json.has_boolean_field(L"hasTask"))
|
||||
setHasTask(json[L"hasTask"].as_bool());
|
||||
}
|
||||
|
||||
json::value Unit::getData(long long time, bool getAll)
|
||||
DataTypes::DataPacket Unit::getDataPacket()
|
||||
{
|
||||
auto json = json::value::object();
|
||||
unsigned int bitmask = 0;
|
||||
bitmask |= alive << 0;
|
||||
bitmask |= human << 1;
|
||||
bitmask |= controlled << 2;
|
||||
bitmask |= hasTask << 3;
|
||||
bitmask |= desiredAltitudeType << 16;
|
||||
bitmask |= desiredSpeedType << 17;
|
||||
bitmask |= isTanker << 18;
|
||||
bitmask |= isAWACS << 19;
|
||||
bitmask |= onOff << 19;
|
||||
bitmask |= followRoads << 19;
|
||||
bitmask |= EPLRS << 20;
|
||||
bitmask |= generalSettings.prohibitAA << 21;
|
||||
bitmask |= generalSettings.prohibitAfterburner << 22;
|
||||
bitmask |= generalSettings.prohibitAG << 23;
|
||||
bitmask |= generalSettings.prohibitAirWpn << 24;
|
||||
bitmask |= generalSettings.prohibitJettison << 25;
|
||||
|
||||
/* If the unit is in a group, task & option data is given by the group leader */
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this))
|
||||
json = unitsManager->getGroupLeader(this)->getData(time, true);
|
||||
DataTypes::DataPacket datapacket{
|
||||
ID,
|
||||
bitmask,
|
||||
position,
|
||||
speed,
|
||||
heading,
|
||||
fuel,
|
||||
desiredSpeed,
|
||||
desiredAltitude,
|
||||
targetID,
|
||||
targetPosition,
|
||||
state,
|
||||
ROE,
|
||||
reactionToThreat,
|
||||
emissionsCountermeasures,
|
||||
TACAN,
|
||||
radio
|
||||
};
|
||||
|
||||
return datapacket;
|
||||
}
|
||||
|
||||
string Unit::getData(bool refresh)
|
||||
{
|
||||
/* Prepare the data in a stringstream */
|
||||
stringstream ss;
|
||||
|
||||
/* Reserve data for:
|
||||
1) DataPacket;
|
||||
2) Length of active path;
|
||||
3) Active path;
|
||||
*/
|
||||
char* data = (char*)malloc(sizeof(DataTypes::DataPacket) + sizeof(unsigned short) + activePath.size() * sizeof(Coords));
|
||||
unsigned int offset = 0;
|
||||
|
||||
/* Prepare the data packet and copy it to memory */
|
||||
DataTypes::DataPacket dataPacket;
|
||||
/* If the unit is in a group, get the datapacket from the group leader and only replace the position, speed and heading */
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this)) {
|
||||
dataPacket = unitsManager->getGroupLeader(this)->getDataPacket();
|
||||
dataPacket.position = position;
|
||||
dataPacket.speed = speed;
|
||||
dataPacket.heading = heading;
|
||||
}
|
||||
else
|
||||
dataPacket = getDataPacket();
|
||||
|
||||
/********** Base data **********/
|
||||
json[L"baseData"] = json::value::object();
|
||||
for (auto key : { L"controlled", L"name", L"unitName", L"groupName", L"alive", L"category"})
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"baseData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"baseData"].size() == 0)
|
||||
json.erase(L"baseData");
|
||||
memcpy(data + offset, &dataPacket, sizeof(dataPacket));
|
||||
offset += sizeof(dataPacket);
|
||||
|
||||
if (alive || getAll) {
|
||||
/********** Flight data **********/
|
||||
json[L"flightData"] = json::value::object();
|
||||
for (auto key : { L"latitude", L"longitude", L"altitude", L"speed", L"heading" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"flightData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"flightData"].size() == 0)
|
||||
json.erase(L"flightData");
|
||||
/* Prepare the path memory and copy it to memory */
|
||||
std::vector<Coords> path;
|
||||
for (const Coords& c : activePath)
|
||||
path.push_back(c);
|
||||
unsigned short pathLength = activePath.size();
|
||||
|
||||
/********** Mission data **********/
|
||||
json[L"missionData"] = json::value::object();
|
||||
for (auto key : { L"fuel", L"ammo", L"contacts", L"hasTask", L"coalition", L"flags" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"missionData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"missionData"].size() == 0)
|
||||
json.erase(L"missionData");
|
||||
memcpy(data + offset, &pathLength, sizeof(unsigned short));
|
||||
offset += sizeof(unsigned short);
|
||||
memcpy(data + offset, &path, activePath.size() * sizeof(Coords));
|
||||
offset += sizeof(unsigned short);
|
||||
|
||||
/********** Formation data **********/
|
||||
json[L"formationData"] = json::value::object();
|
||||
for (auto key : { L"leaderID" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"formationData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"formationData"].size() == 0)
|
||||
json.erase(L"formationData");
|
||||
ss << to_base64(data, offset);
|
||||
|
||||
/* If the unit is in a group, task & option data is given by the group leader */
|
||||
if (unitsManager->isUnitGroupLeader(this)) {
|
||||
/********** Task data **********/
|
||||
json[L"taskData"] = json::value::object();
|
||||
for (auto key : { L"currentState", L"currentTask", L"desiredSpeed", L"desiredAltitude", L"desiredSpeedType", L"desiredAltitudeType", L"activePath", L"isTanker", L"isAWACS", L"onOff", L"followRoads", L"targetID", L"targetLocation" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"taskData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"taskData"].size() == 0)
|
||||
json.erase(L"taskData");
|
||||
|
||||
/********** Options data **********/
|
||||
json[L"optionsData"] = json::value::object();
|
||||
for (auto key : { L"ROE", L"reactionToThreat", L"emissionsCountermeasures", L"TACAN", L"radio", L"generalSettings" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"optionsData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"optionsData"].size() == 0)
|
||||
json.erase(L"optionsData");
|
||||
}
|
||||
if (refresh) {
|
||||
ss << name;
|
||||
ss << unitName;
|
||||
ss << groupName;
|
||||
ss << getCategory();
|
||||
ss << coalition;
|
||||
}
|
||||
|
||||
return json;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void Unit::setActivePath(list<Coords> newPath)
|
||||
{
|
||||
activePath = newPath;
|
||||
resetActiveDestination();
|
||||
|
||||
auto path = json::value::object();
|
||||
if (activePath.size() > 0) {
|
||||
int count = 1;
|
||||
for (auto& destination : activePath)
|
||||
{
|
||||
auto json = json::value::object();
|
||||
json[L"lat"] = destination.lat;
|
||||
json[L"lng"] = destination.lng;
|
||||
json[L"alt"] = destination.alt;
|
||||
path[to_wstring(count++)] = json;
|
||||
}
|
||||
}
|
||||
addMeasure(L"activePath", path);
|
||||
}
|
||||
|
||||
void Unit::clearActivePath()
|
||||
@ -283,28 +308,27 @@ void Unit::popActivePathFront()
|
||||
setActivePath(path);
|
||||
}
|
||||
|
||||
void Unit::setCoalitionID(int newCoalitionID)
|
||||
void Unit::setCoalitionID(unsigned int newCoalitionID)
|
||||
{
|
||||
if (newCoalitionID == 0)
|
||||
coalition = L"neutral";
|
||||
coalition = "neutral";
|
||||
else if (newCoalitionID == 1)
|
||||
coalition = L"red";
|
||||
coalition = "red";
|
||||
else
|
||||
coalition = L"blue";
|
||||
addMeasure(L"coalition", json::value(coalition));
|
||||
coalition = "blue";
|
||||
}
|
||||
|
||||
int Unit::getCoalitionID()
|
||||
unsigned int Unit::getCoalitionID()
|
||||
{
|
||||
if (coalition == L"neutral")
|
||||
if (coalition == "neutral")
|
||||
return 0;
|
||||
else if (coalition == L"red")
|
||||
else if (coalition == "red")
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
wstring Unit::getTargetName()
|
||||
string Unit::getTargetName()
|
||||
{
|
||||
if (isTargetAlive())
|
||||
{
|
||||
@ -312,7 +336,7 @@ wstring Unit::getTargetName()
|
||||
if (target != nullptr)
|
||||
return target->getUnitName();
|
||||
}
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Unit::isTargetAlive()
|
||||
@ -327,7 +351,7 @@ bool Unit::isTargetAlive()
|
||||
return false;
|
||||
}
|
||||
|
||||
wstring Unit::getLeaderName()
|
||||
string Unit::getLeaderName()
|
||||
{
|
||||
if (isLeaderAlive())
|
||||
{
|
||||
@ -335,7 +359,7 @@ wstring Unit::getLeaderName()
|
||||
if (leader != nullptr)
|
||||
return leader->getUnitName();
|
||||
}
|
||||
return L"";
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Unit::isLeaderAlive()
|
||||
@ -369,84 +393,52 @@ void Unit::setFormationOffset(Offset newFormationOffset)
|
||||
resetTask();
|
||||
}
|
||||
|
||||
void Unit::setROE(wstring newROE, bool force) {
|
||||
addMeasure(L"ROE", json::value(newROE));
|
||||
|
||||
void Unit::setROE(unsigned char newROE, bool force)
|
||||
{
|
||||
if (ROE != newROE || force) {
|
||||
ROE = newROE;
|
||||
|
||||
int ROEEnum;
|
||||
if (ROE.compare(L"Free") == 0)
|
||||
ROEEnum = ROE::WEAPON_FREE;
|
||||
else if (ROE.compare(L"Designated free") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE_WEAPON_FREE;
|
||||
else if (ROE.compare(L"Designated") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE;
|
||||
else if (ROE.compare(L"Return") == 0)
|
||||
ROEEnum = ROE::RETURN_FIRE;
|
||||
else if (ROE.compare(L"Hold") == 0)
|
||||
ROEEnum = ROE::WEAPON_HOLD;
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ROE, ROEEnum));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ROE, ROE));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setReactionToThreat(wstring newReactionToThreat, bool force) {
|
||||
addMeasure(L"reactionToThreat", json::value(newReactionToThreat));
|
||||
|
||||
void Unit::setReactionToThreat(unsigned char newReactionToThreat, bool force)
|
||||
{
|
||||
if (reactionToThreat != newReactionToThreat || force) {
|
||||
reactionToThreat = newReactionToThreat;
|
||||
|
||||
int reactionToThreatEnum;
|
||||
if (reactionToThreat.compare(L"None") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::NO_REACTION;
|
||||
else if (reactionToThreat.compare(L"Passive") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::PASSIVE_DEFENCE;
|
||||
else if (reactionToThreat.compare(L"Evade") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::EVADE_FIRE;
|
||||
else if (reactionToThreat.compare(L"Escape") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::BYPASS_AND_ESCAPE;
|
||||
else if (reactionToThreat.compare(L"Abort") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::ALLOW_ABORT_MISSION;
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::REACTION_ON_THREAT, reactionToThreat));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setEmissionsCountermeasures(wstring newEmissionsCountermeasures, bool force) {
|
||||
addMeasure(L"emissionsCountermeasures", json::value(newEmissionsCountermeasures));
|
||||
|
||||
void Unit::setEmissionsCountermeasures(unsigned char newEmissionsCountermeasures, bool force)
|
||||
{
|
||||
if (emissionsCountermeasures != newEmissionsCountermeasures || force) {
|
||||
emissionsCountermeasures = newEmissionsCountermeasures;
|
||||
|
||||
int radarEnum;
|
||||
int flareEnum;
|
||||
int ECMEnum;
|
||||
if (emissionsCountermeasures.compare(L"Silent") == 0)
|
||||
unsigned int radarEnum;
|
||||
unsigned int flareEnum;
|
||||
unsigned int ECMEnum;
|
||||
if (emissionsCountermeasures == EmissionCountermeasure::SILENT)
|
||||
{
|
||||
radarEnum = RadarUse::NEVER;
|
||||
flareEnum = FlareUse::NEVER;
|
||||
ECMEnum = ECMUse::NEVER_USE;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Attack") == 0)
|
||||
else if (emissionsCountermeasures == EmissionCountermeasure::ATTACK)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_ATTACK_ONLY;
|
||||
flareEnum = FlareUse::AGAINST_FIRED_MISSILE;
|
||||
ECMEnum = ECMUse::USE_IF_ONLY_LOCK_BY_RADAR;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Defend") == 0)
|
||||
else if (emissionsCountermeasures == EmissionCountermeasure::DEFEND)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_SEARCH_IF_REQUIRED;
|
||||
flareEnum = FlareUse::WHEN_FLYING_IN_SAM_WEZ;
|
||||
ECMEnum = ECMUse::USE_IF_DETECTED_LOCK_BY_RADAR;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Free") == 0)
|
||||
else if (emissionsCountermeasures == EmissionCountermeasure::FREE)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_CONTINUOUS_SEARCH;
|
||||
flareEnum = FlareUse::WHEN_FLYING_NEAR_ENEMIES;
|
||||
@ -468,42 +460,37 @@ void Unit::setEmissionsCountermeasures(wstring newEmissionsCountermeasures, bool
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::landAt(Coords loc) {
|
||||
void Unit::landAt(Coords loc)
|
||||
{
|
||||
clearActivePath();
|
||||
pushActivePathBack(loc);
|
||||
setState(State::LAND);
|
||||
}
|
||||
|
||||
void Unit::setIsTanker(bool newIsTanker) {
|
||||
void Unit::setIsTanker(bool newIsTanker)
|
||||
{
|
||||
isTanker = newIsTanker;
|
||||
resetTask();
|
||||
addMeasure(L"isTanker", json::value(newIsTanker));
|
||||
}
|
||||
|
||||
void Unit::setIsAWACS(bool newIsAWACS) {
|
||||
void Unit::setIsAWACS(bool newIsAWACS)
|
||||
{
|
||||
isAWACS = newIsAWACS;
|
||||
resetTask();
|
||||
addMeasure(L"isAWACS", json::value(newIsAWACS));
|
||||
setEPLRS(isAWACS);
|
||||
}
|
||||
|
||||
void Unit::setTACAN(Options::TACAN newTACAN, bool force) {
|
||||
auto json = json::value();
|
||||
json[L"isOn"] = json::value(newTACAN.isOn);
|
||||
json[L"channel"] = json::value(newTACAN.channel);
|
||||
json[L"XY"] = json::value(newTACAN.XY);
|
||||
json[L"callsign"] = json::value(newTACAN.callsign);
|
||||
addMeasure(L"TACAN", json);
|
||||
|
||||
void Unit::setTACAN(Options::TACAN newTACAN, bool force)
|
||||
{
|
||||
if (TACAN != newTACAN || force)
|
||||
{
|
||||
TACAN = newTACAN;
|
||||
if (TACAN.isOn) {
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'ActivateBeacon',"
|
||||
<< "params = {"
|
||||
<< "type = " << ((TACAN.XY.compare(L"X") == 0) ? 4 : 5) << ","
|
||||
<< "type = " << ((TACAN.XY == 'X' == 0) ? 4 : 5) << ","
|
||||
<< "system = 3,"
|
||||
<< "name = \"Olympus_TACAN\","
|
||||
<< "callsign = \"" << TACAN.callsign << "\", "
|
||||
@ -514,7 +501,7 @@ void Unit::setTACAN(Options::TACAN newTACAN, bool force) {
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
else {
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'DeactivateBeacon',"
|
||||
<< "params = {"
|
||||
@ -526,19 +513,13 @@ void Unit::setTACAN(Options::TACAN newTACAN, bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setRadio(Options::Radio newRadio, bool force) {
|
||||
|
||||
auto json = json::value();
|
||||
json[L"frequency"] = json::value(newRadio.frequency);
|
||||
json[L"callsign"] = json::value(newRadio.callsign);
|
||||
json[L"callsignNumber"] = json::value(newRadio.callsignNumber);
|
||||
addMeasure(L"radio", json);
|
||||
|
||||
void Unit::setRadio(Options::Radio newRadio, bool force)
|
||||
{
|
||||
if (radio != newRadio || force)
|
||||
{
|
||||
radio = newRadio;
|
||||
|
||||
std::wostringstream commandSS;
|
||||
std::ostringstream commandSS;
|
||||
Command* command;
|
||||
|
||||
commandSS << "{"
|
||||
@ -552,7 +533,7 @@ void Unit::setRadio(Options::Radio newRadio, bool force) {
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
// Clear the stringstream
|
||||
commandSS.str(wstring());
|
||||
commandSS.str(string(""));
|
||||
|
||||
commandSS << "{"
|
||||
<< "id = 'SetCallsign',"
|
||||
@ -568,12 +549,12 @@ void Unit::setRadio(Options::Radio newRadio, bool force) {
|
||||
|
||||
void Unit::setEPLRS(bool newEPLRS, bool force)
|
||||
{
|
||||
//addMeasure(L"EPLRS", json::value(newEPLRS));
|
||||
//addMeasure("EPLRS", json::value(newEPLRS));
|
||||
//
|
||||
//if (EPLRS != newEPLRS || force) {
|
||||
// EPLRS = newEPLRS;
|
||||
//
|
||||
// std::wostringstream commandSS;
|
||||
// std::ostringstream commandSS;
|
||||
// commandSS << "{"
|
||||
// << "id = 'EPLRS',"
|
||||
// << "params = {"
|
||||
@ -585,16 +566,8 @@ void Unit::setEPLRS(bool newEPLRS, bool force)
|
||||
//}
|
||||
}
|
||||
|
||||
void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings, bool force) {
|
||||
|
||||
auto json = json::value();
|
||||
json[L"prohibitJettison"] = json::value(newGeneralSettings.prohibitJettison);
|
||||
json[L"prohibitAA"] = json::value(newGeneralSettings.prohibitAA);
|
||||
json[L"prohibitAG"] = json::value(newGeneralSettings.prohibitAG);
|
||||
json[L"prohibitAfterburner"] = json::value(newGeneralSettings.prohibitAfterburner);
|
||||
json[L"prohibitAirWpn"] = json::value(newGeneralSettings.prohibitAirWpn);
|
||||
addMeasure(L"generalSettings", json);
|
||||
|
||||
void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings, bool force)
|
||||
{
|
||||
if (generalSettings != newGeneralSettings)
|
||||
{
|
||||
generalSettings = newGeneralSettings;
|
||||
@ -613,47 +586,47 @@ void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings, bool
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setDesiredSpeed(double newDesiredSpeed) {
|
||||
void Unit::setDesiredSpeed(double newDesiredSpeed)
|
||||
{
|
||||
desiredSpeed = newDesiredSpeed;
|
||||
addMeasure(L"desiredSpeed", json::value(newDesiredSpeed));
|
||||
if (state == State::IDLE)
|
||||
resetTask();
|
||||
else
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Unit::setDesiredAltitude(double newDesiredAltitude) {
|
||||
void Unit::setDesiredAltitude(double newDesiredAltitude)
|
||||
{
|
||||
desiredAltitude = newDesiredAltitude;
|
||||
addMeasure(L"desiredAltitude", json::value(newDesiredAltitude));
|
||||
if (state == State::IDLE)
|
||||
resetTask();
|
||||
else
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Unit::setDesiredSpeedType(wstring newDesiredSpeedType) {
|
||||
desiredSpeedType = newDesiredSpeedType;
|
||||
addMeasure(L"desiredSpeedType", json::value(newDesiredSpeedType));
|
||||
void Unit::setDesiredSpeedType(string newDesiredSpeedType)
|
||||
{
|
||||
desiredSpeedType = newDesiredSpeedType.compare("GS") == 0;
|
||||
if (state == State::IDLE)
|
||||
resetTask();
|
||||
else
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Unit::setDesiredAltitudeType(wstring newDesiredAltitudeType) {
|
||||
desiredAltitudeType = newDesiredAltitudeType;
|
||||
addMeasure(L"desiredAltitudeType", json::value(newDesiredAltitudeType));
|
||||
void Unit::setDesiredAltitudeType(string newDesiredAltitudeType)
|
||||
{
|
||||
desiredAltitudeType = newDesiredAltitudeType.compare("AGL") == 0;
|
||||
if (state == State::IDLE)
|
||||
resetTask();
|
||||
else
|
||||
goToDestination(); /* Send the command to reach the destination */
|
||||
}
|
||||
|
||||
void Unit::goToDestination(wstring enrouteTask)
|
||||
void Unit::goToDestination(string enrouteTask)
|
||||
{
|
||||
if (activeDestination != NULL)
|
||||
{
|
||||
Command* command = dynamic_cast<Command*>(new Move(groupName, activeDestination, getDesiredSpeed(), getDesiredSpeedType(), getDesiredAltitude(), getDesiredAltitudeType(), enrouteTask, getCategory()));
|
||||
Command* command = dynamic_cast<Command*>(new Move(groupName, activeDestination, getDesiredSpeed(), getDesiredSpeedType()? "GS": "CAS", getDesiredAltitude(), getDesiredAltitudeType()? "AGL" : "ASL", enrouteTask, getCategory()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@ -667,16 +640,17 @@ bool Unit::isDestinationReached(double threshold)
|
||||
for (auto const& p: unitsManager->getGroupMembers(groupName))
|
||||
{
|
||||
double dist = 0;
|
||||
Geodesic::WGS84().Inverse(p->getLatitude(), p->getLongitude(), activeDestination.lat, activeDestination.lng, dist);
|
||||
Geodesic::WGS84().Inverse(p->getPosition().lat, p->getPosition().lng, activeDestination.lat, activeDestination.lng, dist);
|
||||
if (dist < threshold)
|
||||
{
|
||||
log(unitName + L" destination reached");
|
||||
log(unitName + " destination reached");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
@ -687,13 +661,13 @@ bool Unit::setActiveDestination()
|
||||
if (activePath.size() > 0)
|
||||
{
|
||||
activeDestination = activePath.front();
|
||||
log(unitName + L" active destination set to queue front");
|
||||
log(unitName + " active destination set to queue front");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeDestination = Coords(0);
|
||||
log(unitName + L" active destination set to NULL");
|
||||
log(unitName + " active destination set to NULL");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -706,7 +680,7 @@ bool Unit::updateActivePath(bool looping)
|
||||
if (looping)
|
||||
pushActivePathBack(activePath.front());
|
||||
popActivePathFront();
|
||||
log(unitName + L" active path front popped");
|
||||
log(unitName + " active path front popped");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@ -714,15 +688,13 @@ bool Unit::updateActivePath(bool looping)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setTargetLocation(Coords newTargetLocation) {
|
||||
targetLocation = newTargetLocation;
|
||||
auto json = json::value();
|
||||
json[L"latitude"] = json::value(newTargetLocation.lat);
|
||||
json[L"longitude"] = json::value(newTargetLocation.lng);
|
||||
addMeasure(L"targetLocation", json::value(json));
|
||||
void Unit::setTargetPosition(Coords newTargetPosition)
|
||||
{
|
||||
targetPosition = newTargetPosition;
|
||||
}
|
||||
|
||||
bool Unit::checkTaskFailed() {
|
||||
bool Unit::checkTaskFailed()
|
||||
{
|
||||
if (getHasTask())
|
||||
return false;
|
||||
else {
|
||||
@ -736,7 +708,7 @@ void Unit::resetTaskFailedCounter() {
|
||||
taskCheckCounter = TASK_CHECK_INIT_VALUE;
|
||||
}
|
||||
|
||||
void Unit::setHasTask(bool newHasTask) {
|
||||
void Unit::setHasTask(bool newHasTask)
|
||||
{
|
||||
hasTask = newHasTask;
|
||||
addMeasure(L"hasTask", json::value(newHasTask));
|
||||
}
|
||||
@ -22,7 +22,7 @@ UnitsManager::~UnitsManager()
|
||||
|
||||
}
|
||||
|
||||
Unit* UnitsManager::getUnit(int ID)
|
||||
Unit* UnitsManager::getUnit(unsigned int ID)
|
||||
{
|
||||
if (units.find(ID) == units.end()) {
|
||||
return nullptr;
|
||||
@ -35,7 +35,7 @@ Unit* UnitsManager::getUnit(int ID)
|
||||
bool UnitsManager::isUnitInGroup(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
wstring groupName = unit->getGroupName();
|
||||
string groupName = unit->getGroupName();
|
||||
for (auto const& p : units)
|
||||
{
|
||||
if (p.second->getGroupName().compare(groupName) == 0 && p.second != unit)
|
||||
@ -57,7 +57,7 @@ bool UnitsManager::isUnitGroupLeader(Unit* unit)
|
||||
Unit* UnitsManager::getGroupLeader(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
wstring groupName = unit->getGroupName();
|
||||
string groupName = unit->getGroupName();
|
||||
|
||||
/* Find the first unit that has the same groupName */
|
||||
for (auto const& p : units)
|
||||
@ -69,7 +69,7 @@ Unit* UnitsManager::getGroupLeader(Unit* unit)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
vector<Unit*> UnitsManager::getGroupMembers(wstring groupName)
|
||||
vector<Unit*> UnitsManager::getGroupMembers(string groupName)
|
||||
{
|
||||
vector<Unit*> members;
|
||||
for (auto const& p : units)
|
||||
@ -80,7 +80,7 @@ vector<Unit*> UnitsManager::getGroupMembers(wstring groupName)
|
||||
return members;
|
||||
}
|
||||
|
||||
Unit* UnitsManager::getGroupLeader(int ID)
|
||||
Unit* UnitsManager::getGroupLeader(unsigned int ID)
|
||||
{
|
||||
Unit* unit = getUnit(ID);
|
||||
return getGroupLeader(unit);
|
||||
@ -88,12 +88,12 @@ Unit* UnitsManager::getGroupLeader(int ID)
|
||||
|
||||
void UnitsManager::updateExportData(lua_State* L, double dt)
|
||||
{
|
||||
map<int, json::value> unitJSONs = getAllUnits(L);
|
||||
map<unsigned int, json::value> unitJSONs = getAllUnits(L);
|
||||
|
||||
/* Update all units, create them if needed TODO: move code to get constructor in dedicated function */
|
||||
for (auto const& p : unitJSONs)
|
||||
{
|
||||
int ID = p.first;
|
||||
unsigned int ID = p.first;
|
||||
if (units.count(ID) == 0)
|
||||
{
|
||||
json::value type = static_cast<json::value>(p.second)[L"Type"];
|
||||
@ -139,7 +139,7 @@ void UnitsManager::updateMissionData(json::value missionData)
|
||||
/* Update all units */
|
||||
for (auto const& p : units)
|
||||
{
|
||||
int ID = p.first;
|
||||
unsigned int ID = p.first;
|
||||
if (missionData.has_field(to_wstring(ID)))
|
||||
p.second->updateMissionData(missionData[to_wstring(ID)]);
|
||||
}
|
||||
@ -151,29 +151,15 @@ void UnitsManager::runAILoop() {
|
||||
unit.second->runAILoop();
|
||||
}
|
||||
|
||||
void UnitsManager::getUnitData(json::value& answer, long long time)
|
||||
string UnitsManager::getUnitData(bool refresh)
|
||||
{
|
||||
auto unitsJson = json::value::object();
|
||||
stringstream ss;
|
||||
for (auto const& p : units)
|
||||
{
|
||||
auto unitJson = p.second->getData(time);
|
||||
if (unitJson.size() > 0)
|
||||
unitsJson[to_wstring(p.first)] = unitJson;
|
||||
}
|
||||
answer[L"units"] = unitsJson;
|
||||
ss << p.second->getData(refresh);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void UnitsManager::appendUnitData(int ID, json::value& answer, long long time)
|
||||
{
|
||||
Unit* unit = getUnit(ID);
|
||||
if (unit != nullptr) {
|
||||
auto unitJson = unit->getData(time);
|
||||
if (unitJson.size() > 0)
|
||||
answer[to_wstring(ID)] = unitJson;
|
||||
}
|
||||
}
|
||||
|
||||
void UnitsManager::deleteUnit(int ID, bool explosion)
|
||||
void UnitsManager::deleteUnit(unsigned int ID, bool explosion)
|
||||
{
|
||||
if (getUnit(ID) != nullptr)
|
||||
{
|
||||
@ -182,7 +168,7 @@ void UnitsManager::deleteUnit(int ID, bool explosion)
|
||||
}
|
||||
}
|
||||
|
||||
void UnitsManager::acquireControl(int ID) {
|
||||
void UnitsManager::acquireControl(unsigned int ID) {
|
||||
Unit* unit = getUnit(ID);
|
||||
if (unit != nullptr) {
|
||||
for (auto const& groupMember : getGroupMembers(unit->getGroupName())) {
|
||||
|
||||
@ -13,21 +13,19 @@ extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
/* Weapon */
|
||||
Weapon::Weapon(json::value json, int ID) : Unit(json, ID)
|
||||
Weapon::Weapon(json::value json, unsigned int ID) : Unit(json, ID)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
/* Missile */
|
||||
Missile::Missile(json::value json, int ID) : Weapon(json, ID)
|
||||
Missile::Missile(json::value json, unsigned int ID) : Weapon(json, ID)
|
||||
{
|
||||
log("New Missile created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
/* Bomb */
|
||||
Bomb::Bomb(json::value json, int ID) : Weapon(json, ID)
|
||||
Bomb::Bomb(json::value json, unsigned int ID) : Weapon(json, ID)
|
||||
{
|
||||
log("New Bomb created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
@ -5,8 +5,8 @@
|
||||
void DllExport LogInfo(lua_State* L, string message);
|
||||
void DllExport LogWarning(lua_State* L, string message);
|
||||
void DllExport LogError(lua_State* L, string message);
|
||||
void DllExport Log(lua_State* L, string message, int level);
|
||||
void DllExport Log(lua_State* L, string message, unsigned int level);
|
||||
int DllExport dostring_in(lua_State* L, string target, string command);
|
||||
map<int, json::value> DllExport getAllUnits(lua_State* L);
|
||||
int DllExport TACANChannelToFrequency(int channel, wstring XY);
|
||||
map<unsigned int, json::value> DllExport getAllUnits(lua_State* L);
|
||||
unsigned int DllExport TACANChannelToFrequency(unsigned int channel, char XY);
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ void LogError(lua_State* L, string message)
|
||||
Log(L, message, errorLevel);
|
||||
}
|
||||
|
||||
void Log(lua_State* L, string message, int level)
|
||||
void Log(lua_State* L, string message, unsigned int level)
|
||||
{
|
||||
STACK_INIT;
|
||||
|
||||
@ -56,10 +56,10 @@ void Log(lua_State* L, string message, int level)
|
||||
STACK_CLEAN;
|
||||
}
|
||||
|
||||
map<int, json::value> getAllUnits(lua_State* L)
|
||||
map<unsigned int, json::value> getAllUnits(lua_State* L)
|
||||
{
|
||||
int res = 0;
|
||||
map<int, json::value> units;
|
||||
unsigned int res = 0;
|
||||
map<unsigned int, json::value> units;
|
||||
|
||||
STACK_INIT;
|
||||
|
||||
@ -83,7 +83,8 @@ map<int, json::value> getAllUnits(lua_State* L)
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0)
|
||||
{
|
||||
int ID = lua_tonumber(L, -2);
|
||||
unsigned int ID = lua_tonumber(L, -2);
|
||||
// TODO more efficient method can be used, converting all the lua data to a json object may be overkill
|
||||
units[ID] = luaTableToJSON(L, -1);
|
||||
STACK_POP(1)
|
||||
}
|
||||
@ -103,8 +104,8 @@ int dostring_in(lua_State* L, string target, string command)
|
||||
return lua_pcall(L, 2, 0, 0);
|
||||
}
|
||||
|
||||
int TACANChannelToFrequency(int channel, wstring XY)
|
||||
unsigned int TACANChannelToFrequency(unsigned int channel, char XY)
|
||||
{
|
||||
int basef = (XY == L"X" && channel > 63) || (XY == L"Y" && channel < 64) ? 1087: 961;
|
||||
unsigned int basef = (XY == 'X' && channel > 63) || (XY == 'Y' && channel < 64) ? 1087 : 961;
|
||||
return (basef + channel) * 1000000;
|
||||
}
|
||||
@ -3,4 +3,4 @@
|
||||
|
||||
void DllExport log(const std::string& sMessage);
|
||||
void DllExport log(const std::wstring& sMessage);
|
||||
void DllExport getLogsJSON(json::value& json, int logsNumber = NULL);
|
||||
void DllExport getLogsJSON(json::value& json, unsigned int logsNumber = NULL);
|
||||
|
||||
@ -7,7 +7,7 @@ class Logger
|
||||
public:
|
||||
void log(const string& sMessage);
|
||||
void log(const wstring& sMessage);
|
||||
void toJSON(json::value& json, int logsNumber = NULL);
|
||||
void toJSON(json::value& json, unsigned int logsNumber = NULL);
|
||||
|
||||
static Logger* GetLogger();
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ void log(const wstring& message)
|
||||
LOGGER->log(message);
|
||||
}
|
||||
|
||||
void getLogsJSON(json::value& json, int logsNumber)
|
||||
void getLogsJSON(json::value& json, unsigned int logsNumber)
|
||||
{
|
||||
LOGGER->toJSON(json, logsNumber);
|
||||
}
|
||||
@ -32,10 +32,10 @@ void Logger::Close()
|
||||
m_Logfile.close();
|
||||
}
|
||||
|
||||
void Logger::toJSON(json::value& json, int logsNumber)
|
||||
void Logger::toJSON(json::value& json, unsigned int logsNumber)
|
||||
{
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
int i = 0;
|
||||
unsigned int i = 0;
|
||||
for (auto itr = m_logs.end(); itr != m_logs.begin(); --itr)
|
||||
{
|
||||
json[to_wstring(m_logs.size() - 1 - i)] = json::value::string(to_wstring(*itr));
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
#define VERSION "v0.2.1"
|
||||
#define LOG_NAME "Olympus_log.txt"
|
||||
#define REST_ADDRESS L"http://localhost:30000"
|
||||
#define REST_URI L"olympus"
|
||||
#define UNITS_URI L"units"
|
||||
#define LOGS_URI L"logs"
|
||||
#define AIRBASES_URI L"airbases"
|
||||
#define BULLSEYE_URI L"bullseyes"
|
||||
#define MISSION_URI L"mission"
|
||||
#define REST_ADDRESS "http://localhost:30000"
|
||||
#define REST_URI "olympus"
|
||||
#define UNITS_URI "units"
|
||||
#define LOGS_URI "logs"
|
||||
#define AIRBASES_URI "airbases"
|
||||
#define BULLSEYE_URI "bullseyes"
|
||||
#define MISSION_URI "mission"
|
||||
|
||||
#define UPDATE_TIME_INTERVAL 0.25
|
||||
@ -20,6 +20,7 @@
|
||||
#include <codecvt>
|
||||
#include <cpprest/http_listener.h>
|
||||
#include <cpprest/json.h>
|
||||
#include <cpprest/streams.h>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -16,18 +16,19 @@ struct Offset {
|
||||
// Get current date/time, format is YYYY-MM-DD.HH:mm:ss
|
||||
const DllExport std::string CurrentDateTime();
|
||||
std::wstring DllExport to_wstring(const std::string& str);
|
||||
std::string DllExport to_string(json::value& value);
|
||||
std::string DllExport to_string(const std::wstring& wstr);
|
||||
std::string DllExport random_string(size_t length);
|
||||
|
||||
bool DllExport operator== (const Coords& a, const Coords& b);
|
||||
bool DllExport operator!= (const Coords& a, const Coords& b);
|
||||
bool DllExport operator== (const Coords& a, const int& b);
|
||||
bool DllExport operator!= (const Coords& a, const int& b);
|
||||
bool DllExport operator== (const Coords& a, const double& b);
|
||||
bool DllExport operator!= (const Coords& a, const double& b);
|
||||
|
||||
bool DllExport operator== (const Offset& a, const Offset& b);
|
||||
bool DllExport operator!= (const Offset& a, const Offset& b);
|
||||
bool DllExport operator== (const Offset& a, const int& b);
|
||||
bool DllExport operator!= (const Offset& a, const int& b);
|
||||
bool DllExport operator== (const Offset& a, const double& b);
|
||||
bool DllExport operator!= (const Offset& a, const double& b);
|
||||
|
||||
double DllExport knotsToMs(const double knots);
|
||||
double DllExport msToKnots(const double ms);
|
||||
|
||||
@ -14,12 +14,16 @@ const std::string CurrentDateTime()
|
||||
|
||||
std::wstring to_wstring(const std::string& str)
|
||||
{
|
||||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
|
||||
unsigned int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (unsigned int)str.size(), NULL, 0);
|
||||
std::wstring wstrTo(size_needed, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (unsigned int)str.size(), &wstrTo[0], size_needed);
|
||||
return wstrTo;
|
||||
}
|
||||
|
||||
std::string to_string(json::value value) {
|
||||
return to_string(value.as_string());
|
||||
}
|
||||
|
||||
std::string to_string(const std::wstring& wstr)
|
||||
{
|
||||
if (wstr.empty())
|
||||
@ -27,14 +31,14 @@ std::string to_string(const std::wstring& wstr)
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (int)wstr.size(), nullptr, 0, nullptr, nullptr);
|
||||
const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (unsigned int)wstr.size(), nullptr, 0, nullptr, nullptr);
|
||||
if (size_needed <= 0)
|
||||
{
|
||||
throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed));
|
||||
}
|
||||
|
||||
std::string result(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (int)wstr.size(), &result.at(0), size_needed, nullptr, nullptr);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (unsigned int)wstr.size(), &result.at(0), size_needed, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -56,13 +60,13 @@ std::string random_string(size_t length)
|
||||
|
||||
bool operator== (const Coords& a, const Coords& b) { return a.lat == b.lat && a.lng == b.lng && a.alt == b.alt; }
|
||||
bool operator!= (const Coords& a, const Coords& b) { return !(a == b); }
|
||||
bool operator== (const Coords& a, const int& b) { return a.lat == b && a.lng == b && a.alt == b; }
|
||||
bool operator!= (const Coords& a, const int& b) { return !(a == b); }
|
||||
bool operator== (const Coords& a, const double& b) { return a.lat == b && a.lng == b && a.alt == b; }
|
||||
bool operator!= (const Coords& a, const double& b) { return !(a == b); }
|
||||
|
||||
bool operator== (const Offset& a, const Offset& b) { return a.x == b.x && a.y == b.y && a.z == b.z; }
|
||||
bool operator!= (const Offset& a, const Offset& b) { return !(a == b); }
|
||||
bool operator== (const Offset& a, const int& b) { return a.x == b && a.y == b && a.z == b; }
|
||||
bool operator!= (const Offset& a, const int& b) { return !(a == b); }
|
||||
bool operator== (const Offset& a, const double& b) { return a.x == b && a.y == b && a.z == b; }
|
||||
bool operator!= (const Offset& a, const double& b) { return !(a == b); }
|
||||
|
||||
|
||||
double knotsToMs(const double knots) {
|
||||
@ -79,4 +83,4 @@ double ftToM(const double ft) {
|
||||
|
||||
double mToFt(const double m) {
|
||||
return m / 0.3048;
|
||||
}
|
||||
}
|
||||
|
||||
141
third-party/base64/include/base64.hpp
vendored
141
third-party/base64/include/base64.hpp
vendored
@ -6,76 +6,81 @@
|
||||
|
||||
namespace base64 {
|
||||
|
||||
inline std::string get_base64_chars() {
|
||||
static std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
return base64_chars;
|
||||
}
|
||||
inline std::string get_base64_chars() {
|
||||
static std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
return base64_chars;
|
||||
}
|
||||
inline std::string to_base64(std::string const& data) {
|
||||
return to_base64(data.c_str(), data.length());
|
||||
}
|
||||
|
||||
inline std::string to_base64(std::string const &data) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
const std::string base64_chars = get_base64_chars();
|
||||
std::string encoded;
|
||||
int offset = 0;
|
||||
for (unsigned char c : data) {
|
||||
auto num_val = static_cast<unsigned int>(c);
|
||||
offset = 16 - counter % 3 * 8;
|
||||
bit_stream += num_val << offset;
|
||||
if (offset == 16) {
|
||||
encoded += base64_chars.at(bit_stream >> 18 & 0x3f);
|
||||
}
|
||||
if (offset == 8) {
|
||||
encoded += base64_chars.at(bit_stream >> 12 & 0x3f);
|
||||
}
|
||||
if (offset == 0 && counter != 3) {
|
||||
encoded += base64_chars.at(bit_stream >> 6 & 0x3f);
|
||||
encoded += base64_chars.at(bit_stream & 0x3f);
|
||||
bit_stream = 0;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
if (offset == 16) {
|
||||
encoded += base64_chars.at(bit_stream >> 12 & 0x3f);
|
||||
encoded += "==";
|
||||
}
|
||||
if (offset == 8) {
|
||||
encoded += base64_chars.at(bit_stream >> 6 & 0x3f);
|
||||
encoded += '=';
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
inline std::string from_base64(std::string const &data) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
std::string decoded;
|
||||
int offset = 0;
|
||||
const std::string base64_chars = get_base64_chars();
|
||||
for (unsigned char c : data) {
|
||||
auto num_val = base64_chars.find(c);
|
||||
if (num_val != std::string::npos) {
|
||||
offset = 18 - counter % 4 * 6;
|
||||
bit_stream += num_val << offset;
|
||||
if (offset == 12) {
|
||||
decoded += static_cast<char>(bit_stream >> 16 & 0xff);
|
||||
}
|
||||
if (offset == 6) {
|
||||
decoded += static_cast<char>(bit_stream >> 8 & 0xff);
|
||||
}
|
||||
if (offset == 0 && counter != 4) {
|
||||
decoded += static_cast<char>(bit_stream & 0xff);
|
||||
bit_stream = 0;
|
||||
}
|
||||
} else if (c != '=') {
|
||||
return std::string();
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
inline std::string to_base64(const char* data, size_t size) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
const std::string base64_chars = get_base64_chars();
|
||||
std::string encoded;
|
||||
encoded.reserve(ceil(4.0 / 3.0 * size));
|
||||
int offset = 0;
|
||||
for (unsigned int idx = 0; idx < size; idx++) {
|
||||
unsigned char c = data[idx];
|
||||
auto num_val = static_cast<unsigned int>(c);
|
||||
offset = 16 - counter % 3 * 8;
|
||||
bit_stream += num_val << offset;
|
||||
if (offset == 16) {
|
||||
encoded += base64_chars.at(bit_stream >> 18 & 0x3f);
|
||||
}
|
||||
if (offset == 8) {
|
||||
encoded += base64_chars.at(bit_stream >> 12 & 0x3f);
|
||||
}
|
||||
if (offset == 0 && counter != 3) {
|
||||
encoded += base64_chars.at(bit_stream >> 6 & 0x3f);
|
||||
encoded += base64_chars.at(bit_stream & 0x3f);
|
||||
bit_stream = 0;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
if (offset == 16) {
|
||||
encoded += base64_chars.at(bit_stream >> 12 & 0x3f);
|
||||
encoded += "==";
|
||||
}
|
||||
if (offset == 8) {
|
||||
encoded += base64_chars.at(bit_stream >> 6 & 0x3f);
|
||||
encoded += '=';
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
inline std::string from_base64(std::string const& data) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
std::string decoded;
|
||||
int offset = 0;
|
||||
const std::string base64_chars = get_base64_chars();
|
||||
for (unsigned char c : data) {
|
||||
auto num_val = base64_chars.find(c);
|
||||
if (num_val != std::string::npos) {
|
||||
offset = 18 - counter % 4 * 6;
|
||||
bit_stream += num_val << offset;
|
||||
if (offset == 12) {
|
||||
decoded += static_cast<char>(bit_stream >> 16 & 0xff);
|
||||
}
|
||||
if (offset == 6) {
|
||||
decoded += static_cast<char>(bit_stream >> 8 & 0xff);
|
||||
}
|
||||
if (offset == 0 && counter != 4) {
|
||||
decoded += static_cast<char>(bit_stream & 0xff);
|
||||
bit_stream = 0;
|
||||
}
|
||||
}
|
||||
else if (c != '=') {
|
||||
return std::string();
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BASE_64_HPP
|
||||
Loading…
x
Reference in New Issue
Block a user