mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
More work on client conversion to binary data
This commit is contained in:
219
client/src/units/dataextractor.ts
Normal file
219
client/src/units/dataextractor.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { UnitData } from "../@types/unit";
|
||||
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
|
||||
|
||||
export class DataExtractor {
|
||||
#offset = 0;
|
||||
#dataview: DataView;
|
||||
#decoder: TextDecoder;
|
||||
#buffer: ArrayBuffer;
|
||||
|
||||
constructor(buffer: ArrayBuffer) {
|
||||
this.#buffer = buffer;
|
||||
this.#dataview = new DataView(this.#buffer);
|
||||
this.#decoder = new TextDecoder("utf-8");
|
||||
}
|
||||
|
||||
extractData(offset: number) {
|
||||
this.#offset = offset;
|
||||
|
||||
const ID = this.#extractUInt32();
|
||||
const bitmask = this.#extractUInt32();
|
||||
|
||||
const unitData: UnitData = {
|
||||
ID: ID,
|
||||
alive: this.#extractFromBitmask(bitmask, 0),
|
||||
human: this.#extractFromBitmask(bitmask, 1),
|
||||
controlled: this.#extractFromBitmask(bitmask, 2),
|
||||
hasTask: this.#extractFromBitmask(bitmask, 3),
|
||||
desiredAltitudeType: this.#extractFromBitmask(bitmask, 16),
|
||||
desiredSpeedType: this.#extractFromBitmask(bitmask, 17),
|
||||
isTanker: this.#extractFromBitmask(bitmask, 18),
|
||||
isAWACS: this.#extractFromBitmask(bitmask, 19),
|
||||
onOff: this.#extractFromBitmask(bitmask, 20),
|
||||
followRoads: this.#extractFromBitmask(bitmask, 21),
|
||||
EPLRS: this.#extractFromBitmask(bitmask, 22),
|
||||
generalSettings: {
|
||||
prohibitAA: this.#extractFromBitmask(bitmask, 23),
|
||||
prohibitAfterburner: this.#extractFromBitmask(bitmask, 24),
|
||||
prohibitAG: this.#extractFromBitmask(bitmask, 25),
|
||||
prohibitAirWpn: this.#extractFromBitmask(bitmask, 26),
|
||||
prohibitJettison: this.#extractFromBitmask(bitmask, 27),
|
||||
},
|
||||
position: new LatLng(
|
||||
this.#extractFloat64(),
|
||||
this.#extractFloat64(),
|
||||
this.#extractFloat64()
|
||||
),
|
||||
speed: this.#extractFloat64(),
|
||||
heading: this.#extractFloat64(),
|
||||
fuel: this.#extractUInt16(),
|
||||
desiredSpeed: this.#extractFloat64(),
|
||||
desiredAltitude: this.#extractFloat64(),
|
||||
targetID: this.#extractUInt32(),
|
||||
leaderID: 0,
|
||||
targetPosition: new LatLng(
|
||||
this.#extractFloat64(),
|
||||
this.#extractFloat64(),
|
||||
this.#extractFloat64()
|
||||
),
|
||||
state: this.#getState(this.#extractUint8()),
|
||||
ROE: this.#getROE(this.#extractUint8()),
|
||||
reactionToThreat: this.#getReactionToThreat(this.#extractUint8()),
|
||||
emissionsCountermeasures: this.#getEmissionCountermeasure(this.#extractUint8()),
|
||||
TACAN: {
|
||||
isOn: this.#extractBool(),
|
||||
channel: this.#extractUint8(),
|
||||
XY: this.#extractChar(),
|
||||
callsign: this.#extractString(4)
|
||||
},
|
||||
radio: {
|
||||
frequency: this.#extractUInt32(),
|
||||
callsign: this.#extractUint8(),
|
||||
callsignNumber: this.#extractUint8()
|
||||
},
|
||||
activePath: [],
|
||||
ammo: [],
|
||||
contacts: [],
|
||||
name: "",
|
||||
unitName: "",
|
||||
groupName: "",
|
||||
category: "",
|
||||
coalition: "",
|
||||
task: ""
|
||||
}
|
||||
|
||||
const pathLength = this.#extractUInt16();
|
||||
const ammoLength = this.#extractUInt16();
|
||||
const contactsLength = this.#extractUInt16();
|
||||
const nameLength = this.#extractUInt16();
|
||||
const unitNameLength = this.#extractUInt16();
|
||||
const groupNameLength = this.#extractUInt16();
|
||||
const categoryLength = this.#extractUInt16();
|
||||
const coalitionLength = this.#extractUInt16();
|
||||
|
||||
if (pathLength > 0) {
|
||||
unitData.activePath = [];
|
||||
for (let idx = 0; idx < pathLength; idx++) {
|
||||
unitData.activePath.push(new LatLng(this.#extractFloat64(), this.#extractFloat64(), this.#extractFloat64()));
|
||||
}
|
||||
}
|
||||
|
||||
if (ammoLength > 0) {
|
||||
unitData.ammo = [];
|
||||
for (let idx = 0; idx < pathLength; idx++) {
|
||||
unitData.ammo.push({
|
||||
quantity: this.#extractUInt16(),
|
||||
name: this.#extractString(32),
|
||||
guidance: this.#extractUint8(),
|
||||
category: this.#extractUint8(),
|
||||
missileCategory: this.#extractUint8()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (contactsLength > 0) {
|
||||
unitData.contacts = [];
|
||||
for (let idx = 0; idx < pathLength; idx++) {
|
||||
unitData.contacts.push({
|
||||
ID: this.#extractUInt32(),
|
||||
detectionMethod: this.#extractUint8()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (nameLength > 0) {
|
||||
unitData.name = this.#extractString(nameLength);
|
||||
}
|
||||
|
||||
if (unitNameLength > 0) {
|
||||
unitData.unitName = this.#extractString(unitNameLength);
|
||||
}
|
||||
|
||||
if (groupNameLength > 0) {
|
||||
unitData.groupName = this.#extractString(groupNameLength);
|
||||
}
|
||||
|
||||
if (categoryLength > 0) {
|
||||
unitData.category = this.#extractString(categoryLength);
|
||||
}
|
||||
|
||||
if (coalitionLength > 0) {
|
||||
unitData.coalition = this.#extractString(coalitionLength);
|
||||
}
|
||||
|
||||
return {data: unitData, offset: this.#offset};
|
||||
}
|
||||
|
||||
#extractBool() {
|
||||
const value = this.#dataview.getUint8(this.#offset);
|
||||
this.#offset += 1;
|
||||
return value > 0;
|
||||
}
|
||||
|
||||
#extractUint8() {
|
||||
const value = this.#dataview.getUint8(this.#offset);
|
||||
this.#offset += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
#extractUInt16() {
|
||||
const value = this.#dataview.getUint16(this.#offset);
|
||||
this.#offset += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
#extractUInt32() {
|
||||
const value = this.#dataview.getUint32(this.#offset);
|
||||
this.#offset += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
#extractFloat64() {
|
||||
const value = this.#dataview.getFloat64(this.#offset);
|
||||
this.#offset += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
#extractFromBitmask(bitmask: number, position: number) {
|
||||
return (bitmask >> position & 1) > 0;
|
||||
}
|
||||
|
||||
#extractString(length: number) {
|
||||
const value = this.#decoder.decode(this.#buffer.slice(this.#offset, length));
|
||||
this.#offset += length;
|
||||
return value;
|
||||
}
|
||||
|
||||
#extractChar() {
|
||||
return this.#extractString(1);
|
||||
}
|
||||
|
||||
#getState(state: number) {
|
||||
if (state < states.length)
|
||||
return states[state];
|
||||
else
|
||||
return states[0];
|
||||
}
|
||||
|
||||
#getROE(ROE: number) {
|
||||
if (ROE < ROEs.length)
|
||||
return ROEs[ROE];
|
||||
else
|
||||
return ROEs[0];
|
||||
}
|
||||
|
||||
#getReactionToThreat(reactionToThreat: number) {
|
||||
if (reactionToThreat < reactionsToThreat.length)
|
||||
return reactionsToThreat[reactionToThreat];
|
||||
else
|
||||
return reactionsToThreat[0];
|
||||
}
|
||||
|
||||
#getEmissionCountermeasure(emissionCountermeasure: number) {
|
||||
if (emissionCountermeasure < emissionsCountermeasures.length)
|
||||
return emissionsCountermeasures[emissionCountermeasure];
|
||||
else
|
||||
return emissionsCountermeasures[0];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user