mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Started transition to binary data on client side
This commit is contained in:
parent
1d62b4c115
commit
916752301a
2
client/src/@types/server.d.ts
vendored
2
client/src/@types/server.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
interface UnitsData {
|
||||
units: {[key: string]: UnitData},
|
||||
units: string,
|
||||
sessionHash: string
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import { UnitDatabase } from "../units/unitdatabase";
|
||||
import { aircraftDatabase } from "../units/aircraftdatabase";
|
||||
import { helicopterDatabase } from "../units/helicopterdatabase";
|
||||
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
export function bearing(lat1: number, lon1: number, lat2: number, lon2: number) {
|
||||
const φ1 = deg2rad(lat1); // φ, λ in radians
|
||||
@ -247,4 +248,8 @@ export function getUnitDatabaseByCategory(category: string) {
|
||||
return groundUnitsDatabase;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function base64ToBytes(base64: string) {
|
||||
return Buffer.from(base64, 'base64').buffer;
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ export function startUpdate() {
|
||||
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
|
||||
getBullseye((data: BullseyesData) => getMissionData()?.update(data));
|
||||
getMission((data: any) => { getMissionData()?.update(data) });
|
||||
getUnits((data: UnitsData) => getUnitsManager()?.update(data), true /* Does a full refresh */);
|
||||
getUnits((data: UnitsData) => getUnitsManager()?.update(data.units), true /* Does a full refresh */);
|
||||
|
||||
requestUpdate();
|
||||
requestRefresh();
|
||||
@ -310,7 +310,7 @@ export function requestUpdate() {
|
||||
/* Main update rate = 250ms is minimum time, equal to server update time. */
|
||||
getUnits((data: UnitsData) => {
|
||||
if (!getPaused()) {
|
||||
getUnitsManager()?.update(data);
|
||||
getUnitsManager()?.update(data.units);
|
||||
checkSessionHash(data.sessionHash);
|
||||
}
|
||||
}, false);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler, getUnitDataTable } from "..";
|
||||
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler } from "..";
|
||||
import { Unit } from "./unit";
|
||||
import { cloneUnit, spawnGroundUnit } from "../server/server";
|
||||
import { deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polygonArea, randomPointInPoly, randomUnitBlueprintByRole } from "../other/utils";
|
||||
import { base64ToBytes, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polygonArea, randomPointInPoly, randomUnitBlueprintByRole } from "../other/utils";
|
||||
import { CoalitionArea } from "../map/coalitionarea";
|
||||
import { Airbase } from "../missionhandler/airbase";
|
||||
import { groundUnitsDatabase } from "./groundunitsdatabase";
|
||||
@ -68,9 +68,61 @@ export class UnitsManager {
|
||||
|
||||
}
|
||||
|
||||
update(data: UnitsData) {
|
||||
update(data: string) {
|
||||
var updatedUnits: Unit[] = [];
|
||||
Object.keys(data.units)
|
||||
var buffer = base64ToBytes(data);
|
||||
|
||||
/*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;
|
||||
unsigned short pathLength;
|
||||
unsigned char nameLength;
|
||||
unsigned char unitNameLength;
|
||||
unsigned char groupNameLength;
|
||||
unsigned char categoryLength;
|
||||
unsigned char coalitionLength;*/
|
||||
|
||||
var offset = 0;
|
||||
var dataview = new DataView(buffer);
|
||||
const ID = dataview.getUint32(offset, true); offset += 4;
|
||||
const bitmask = dataview.getUint32(offset , true); offset += 4;
|
||||
const alive = bitmask & (1 << 0);
|
||||
const human = bitmask >> 1 & 1;
|
||||
const controlled = bitmask >> 2 & 1;
|
||||
const hasTask = bitmask >> 3 & 1;
|
||||
const desiredAltitudeType = bitmask >> 16 & 1;
|
||||
const desiredSpeedType = bitmask >> 17 & 1;
|
||||
const isTanker = bitmask >> 18 & 1;
|
||||
const isAWACS = bitmask >> 19 & 1;
|
||||
const onOff = bitmask >> 20 & 1;
|
||||
const followRoads = bitmask >> 21 & 1;
|
||||
const EPLRS = bitmask >> 22 & 1;
|
||||
const prohibitAA = bitmask >> 23 & 1;
|
||||
const prohibitAfterburner = bitmask >> 24 & 1;
|
||||
const prohibitAG = bitmask >> 25 & 1;
|
||||
const prohibitAirWpn = bitmask >> 26 & 1;
|
||||
const prohibitJettison = bitmask >> 27 & 1;
|
||||
|
||||
const latitude = dataview.getFloat64(offset , true); offset += 8;
|
||||
const longitude = dataview.getFloat64(offset , true); offset += 8;
|
||||
const altitude = dataview.getFloat64(offset , true); offset += 8;
|
||||
const speed = dataview.getFloat64(offset , true); offset += 8;
|
||||
const heading = dataview.getFloat64(offset , true); offset += 8;
|
||||
|
||||
|
||||
var foo = 12;
|
||||
/*Object.keys(data.units)
|
||||
.filter((ID: string) => !(ID in this.#units))
|
||||
.reduce((timeout: number, ID: string) => {
|
||||
window.setTimeout(() => {
|
||||
@ -91,7 +143,7 @@ export class UnitsManager {
|
||||
this.getSelectedUnits().forEach((unit: Unit) => {
|
||||
if (!updatedUnits.includes(unit))
|
||||
unit.setData({})
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
setHiddenType(key: string, value: boolean) {
|
||||
|
||||
@ -29,6 +29,7 @@ namespace State
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
namespace Options {
|
||||
struct TACAN
|
||||
{
|
||||
@ -86,8 +87,15 @@ namespace DataTypes {
|
||||
unsigned char emissionsCountermeasures;
|
||||
Options::TACAN TACAN;
|
||||
Options::Radio Radio;
|
||||
unsigned short pathLength;
|
||||
unsigned char nameLength;
|
||||
unsigned char unitNameLength;
|
||||
unsigned char groupNameLength;
|
||||
unsigned char categoryLength;
|
||||
unsigned char coalitionLength;
|
||||
};
|
||||
}
|
||||
#pragma pack(pop)
|
||||
|
||||
class Unit
|
||||
{
|
||||
@ -102,8 +110,8 @@ public:
|
||||
void runAILoop();
|
||||
void updateExportData(json::value json, double dt = 0);
|
||||
void updateMissionData(json::value json);
|
||||
DataTypes::DataPacket getDataPacket();
|
||||
string getData(bool refresh);
|
||||
unsigned int getUpdateData(char* &data);
|
||||
void getData(stringstream &ss, bool refresh);
|
||||
virtual string getCategory() { return "No category"; };
|
||||
|
||||
/********** Base data **********/
|
||||
|
||||
@ -68,7 +68,7 @@ void AirUnit::setState(unsigned char newState)
|
||||
case State::ATTACK: {
|
||||
if (isTargetAlive()) {
|
||||
Unit* target = unitsManager->getUnit(targetID);
|
||||
Coords targetPosition = Coords(target->getLatitude(), target->getLongitude(), 0);
|
||||
Coords targetPosition = Coords(target->getPosition().lat, target->getPosition().lng, 0);
|
||||
clearActivePath();
|
||||
pushActivePathFront(targetPosition);
|
||||
resetActiveDestination();
|
||||
|
||||
@ -79,18 +79,19 @@ extern "C" DllExport int coreFrame(lua_State* L)
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
frameRate = frameCounter / duration.count();
|
||||
if (duration.count() > 0)
|
||||
frameRate = frameCounter / duration.count();
|
||||
frameCounter = 0;
|
||||
|
||||
if (unitsManager != nullptr) {
|
||||
unitsManager->updateExportData(L, duration.count());
|
||||
unitsManager->runAILoop();
|
||||
//unitsManager->runAILoop();
|
||||
}
|
||||
before = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
if (scheduler != nullptr)
|
||||
scheduler->execute(L);
|
||||
//scheduler->execute(L);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ void Server::handle_get(http_request request)
|
||||
|
||||
http_response response(status_codes::OK);
|
||||
string authorization = to_base64("admin:" + password);
|
||||
log(authorization);
|
||||
if (password == "" || (request.headers().has(L"Authorization") && request.headers().find(L"Authorization")->second == L"Basic " + to_wstring(authorization)))
|
||||
{
|
||||
std::exception_ptr eptr;
|
||||
|
||||
@ -6,9 +6,6 @@
|
||||
#include "defines.h"
|
||||
#include "unitsmanager.h"
|
||||
|
||||
#include "base64.hpp"
|
||||
using namespace base64;
|
||||
|
||||
#include <chrono>
|
||||
using namespace std::chrono;
|
||||
|
||||
@ -54,30 +51,26 @@ void Unit::initialize(json::value json)
|
||||
|
||||
void Unit::setDefaults(bool force)
|
||||
{
|
||||
const bool isUnitControlledByOlympus = getControlled();
|
||||
const bool isUnitAlive = getAlive();
|
||||
const bool isUnitLeader = unitsManager->isUnitGroupLeader(this);
|
||||
const bool isUnitLeaderOfAGroupWithOtherUnits = unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this);
|
||||
if (!getControlled()) return;
|
||||
if (!unitsManager->isUnitGroupLeader(this)) return;
|
||||
if (!(getAlive() || unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this))) return;
|
||||
if (getHuman()) return;
|
||||
|
||||
if (isUnitControlledByOlympus && (isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits) && isUnitLeader && !human) {
|
||||
/* Set the default IDLE state */
|
||||
setState(State::IDLE);
|
||||
/* 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(position.alt);
|
||||
/* Set desired altitude to be equal to current altitude so the unit does not climb/descend after spawn */
|
||||
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(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);
|
||||
setGeneralSettings(generalSettings, force);
|
||||
setOnOff(onOff);
|
||||
setFollowRoads(followRoads);
|
||||
}
|
||||
/* Set the default options */
|
||||
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);
|
||||
setGeneralSettings(generalSettings, force);
|
||||
}
|
||||
|
||||
void Unit::runAILoop() {
|
||||
@ -107,8 +100,7 @@ void Unit::updateExportData(json::value json, double dt)
|
||||
if (dt > 0)
|
||||
setSpeed(getSpeed() * 0.95 + (dist / dt) * 0.05);
|
||||
}
|
||||
oldPosition = position;
|
||||
|
||||
|
||||
if (json.has_string_field(L"Name"))
|
||||
setName(to_string(json[L"Name"]));
|
||||
if (json.has_string_field(L"UnitName"))
|
||||
@ -136,53 +128,63 @@ void Unit::updateExportData(json::value json, double dt)
|
||||
/* All units which contain the name "Olympus" are automatically under AI control */
|
||||
if (getUnitName().find("Olympus") != string::npos)
|
||||
setControlled(true);
|
||||
|
||||
oldPosition = position;
|
||||
}
|
||||
|
||||
void Unit::updateMissionData(json::value json)
|
||||
{
|
||||
if (json.has_number_field(L"fuel"))
|
||||
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_number_field(L"fuel"))
|
||||
// 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());
|
||||
}
|
||||
|
||||
DataTypes::DataPacket Unit::getDataPacket()
|
||||
unsigned int Unit::getUpdateData(char* &data)
|
||||
{
|
||||
/* Reserve data for:
|
||||
1) DataPacket;
|
||||
2) Active path;
|
||||
*/
|
||||
data = (char*)malloc(sizeof(DataTypes::DataPacket) + activePath.size() * sizeof(Coords));
|
||||
unsigned int offset = 0;
|
||||
|
||||
/* Prepare the data packet and copy it to memory */
|
||||
unsigned int bitmask = 0;
|
||||
bitmask |= alive << 0;
|
||||
bitmask |= human << 1;
|
||||
@ -192,16 +194,16 @@ DataTypes::DataPacket Unit::getDataPacket()
|
||||
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;
|
||||
bitmask |= onOff << 20;
|
||||
bitmask |= followRoads << 21;
|
||||
bitmask |= EPLRS << 22;
|
||||
bitmask |= generalSettings.prohibitAA << 23;
|
||||
bitmask |= generalSettings.prohibitAfterburner << 24;
|
||||
bitmask |= generalSettings.prohibitAG << 25;
|
||||
bitmask |= generalSettings.prohibitAirWpn << 26;
|
||||
bitmask |= generalSettings.prohibitJettison << 27;
|
||||
|
||||
DataTypes::DataPacket datapacket{
|
||||
DataTypes::DataPacket dataPacket{
|
||||
ID,
|
||||
bitmask,
|
||||
position,
|
||||
@ -217,37 +219,15 @@ DataTypes::DataPacket Unit::getDataPacket()
|
||||
reactionToThreat,
|
||||
emissionsCountermeasures,
|
||||
TACAN,
|
||||
radio
|
||||
radio,
|
||||
activePath.size(),
|
||||
name.size(),
|
||||
unitName.size(),
|
||||
groupName.size(),
|
||||
getCategory().size(),
|
||||
coalition.size()
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
memcpy(data + offset, &dataPacket, sizeof(dataPacket));
|
||||
offset += sizeof(dataPacket);
|
||||
|
||||
@ -255,14 +235,29 @@ string Unit::getData(bool refresh)
|
||||
std::vector<Coords> path;
|
||||
for (const Coords& c : activePath)
|
||||
path.push_back(c);
|
||||
unsigned short pathLength = activePath.size();
|
||||
|
||||
memcpy(data + offset, &pathLength, sizeof(unsigned short));
|
||||
offset += sizeof(unsigned short);
|
||||
memcpy(data + offset, &path, activePath.size() * sizeof(Coords));
|
||||
offset += sizeof(unsigned short);
|
||||
offset += activePath.size() * sizeof(Coords);
|
||||
|
||||
ss << to_base64(data, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
void Unit::getData(stringstream &ss, bool refresh)
|
||||
{
|
||||
char* data;
|
||||
unsigned int size = getUpdateData(data);
|
||||
|
||||
/* Prepare the data packet and copy it to memory */
|
||||
/* If the unit is in a group, get the update data from the group leader and only replace the position, speed and heading */
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this)) {
|
||||
DataTypes::DataPacket* p = (DataTypes::DataPacket*)data;
|
||||
p->position = position;
|
||||
p->speed = speed;
|
||||
p->heading = heading;
|
||||
}
|
||||
|
||||
ss.write(data, size);
|
||||
delete data;
|
||||
|
||||
if (refresh) {
|
||||
ss << name;
|
||||
@ -271,8 +266,6 @@ string Unit::getData(bool refresh)
|
||||
ss << getCategory();
|
||||
ss << coalition;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void Unit::setActivePath(list<Coords> newPath)
|
||||
@ -397,7 +390,7 @@ void Unit::setROE(unsigned char newROE, bool force)
|
||||
{
|
||||
if (ROE != newROE || force) {
|
||||
ROE = newROE;
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ROE, ROE));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ROE, static_cast<unsigned int>(ROE)));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@ -407,7 +400,7 @@ void Unit::setReactionToThreat(unsigned char newReactionToThreat, bool force)
|
||||
if (reactionToThreat != newReactionToThreat || force) {
|
||||
reactionToThreat = newReactionToThreat;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::REACTION_ON_THREAT, reactionToThreat));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::REACTION_ON_THREAT, static_cast<unsigned int>(reactionToThreat)));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
#include "commands.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
#include "base64.hpp"
|
||||
using namespace base64;
|
||||
|
||||
extern Scheduler* scheduler;
|
||||
|
||||
UnitsManager::UnitsManager(lua_State* L)
|
||||
@ -155,8 +158,8 @@ string UnitsManager::getUnitData(bool refresh)
|
||||
{
|
||||
stringstream ss;
|
||||
for (auto const& p : units)
|
||||
ss << p.second->getData(refresh);
|
||||
return ss.str();
|
||||
p.second->getData(ss, refresh);
|
||||
return to_base64(ss.str());
|
||||
}
|
||||
|
||||
void UnitsManager::deleteUnit(unsigned int ID, bool explosion)
|
||||
|
||||
@ -20,7 +20,7 @@ std::wstring to_wstring(const std::string& str)
|
||||
return wstrTo;
|
||||
}
|
||||
|
||||
std::string to_string(json::value value) {
|
||||
std::string to_string(json::value& value) {
|
||||
return to_string(value.as_string());
|
||||
}
|
||||
|
||||
|
||||
9
third-party/base64/include/base64.hpp
vendored
9
third-party/base64/include/base64.hpp
vendored
@ -12,10 +12,7 @@ namespace base64 {
|
||||
"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(const char* data, size_t size) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
@ -52,6 +49,10 @@ namespace base64 {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
inline std::string to_base64(std::string const& data) {
|
||||
return to_base64(data.c_str(), data.length());
|
||||
}
|
||||
|
||||
inline std::string from_base64(std::string const& data) {
|
||||
int counter = 0;
|
||||
uint32_t bit_stream = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user