2019-07-31 01:08:19 +02:00
|
|
|
class FLYSocket {
|
|
|
|
constructor(ws,
|
2019-08-01 19:02:47 +02:00
|
|
|
callbackData = null,
|
|
|
|
callbackRaw = null) {
|
2019-07-31 01:08:19 +02:00
|
|
|
this.ws = new WebSocket(ws);
|
|
|
|
this.pointer = 0;
|
|
|
|
|
|
|
|
this.callbackData = callbackData;
|
|
|
|
this.callbackRaw = callbackRaw;
|
|
|
|
|
|
|
|
this.ws.onmessage = this.onMessage.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
onMessage(e) {
|
|
|
|
new Response(event.data).arrayBuffer().then(
|
|
|
|
function(buff) {
|
|
|
|
let data = new DataView(buff);
|
2019-08-01 19:02:47 +02:00
|
|
|
if (this.callbackRaw !== null)
|
|
|
|
this.callbackRaw(data);
|
|
|
|
if (this.callbackData !== null)
|
2019-07-31 01:08:19 +02:00
|
|
|
this.callbackData( this.parse(data) );
|
|
|
|
}.bind(this)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
parse(data) {
|
|
|
|
window.data = data; // DEBUG
|
|
|
|
let packets = [];
|
|
|
|
this.pointer = 0;
|
|
|
|
|
|
|
|
while (this.pointer < data.byteLength) {
|
2019-08-01 01:56:46 +02:00
|
|
|
let packetID = this.readUint8(data);
|
2019-07-31 01:08:19 +02:00
|
|
|
packets.push({
|
|
|
|
packetID: packetID,
|
2019-08-01 01:23:19 +02:00
|
|
|
value: (this["handle_packet" + packetID] || this.handle_packetInvalid).call(this, data)
|
2019-07-31 01:08:19 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return packets;
|
|
|
|
}
|
|
|
|
|
2019-08-01 01:56:46 +02:00
|
|
|
readUint8(data) {
|
|
|
|
return data.getUint8(this.pointer++, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
readUint16(data) {
|
|
|
|
let ret = data.getUint16(this.pointer, true); this.pointer += 2;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
readInt16(data) {
|
|
|
|
let ret = data.getInt16(this.pointer, true); this.pointer += 2;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
readUint32(data) {
|
|
|
|
let ret = data.getUint32(this.pointer, true); this.pointer += 4;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
readFloat32(data) {
|
|
|
|
let ret = data.getFloat32(this.pointer, true); this.pointer += 4;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-07-31 01:08:19 +02:00
|
|
|
handle_packet0(data) {
|
|
|
|
// BxI
|
|
|
|
// B: Length
|
|
|
|
// I: FlightUUID
|
|
|
|
let ret = [];
|
2019-08-01 01:56:46 +02:00
|
|
|
let length = this.readUint8(data);
|
|
|
|
for (let i = 0; i < length; i++)
|
|
|
|
ret.push( this.readUint32(data) );
|
2019-07-31 01:08:19 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle_packet1(data) {
|
|
|
|
// ?
|
|
|
|
// ?: Subscribed to changes
|
2019-08-01 01:56:46 +02:00
|
|
|
return this.readUint8(data) != 0;
|
2019-07-31 01:08:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handle_packet2(data) {
|
|
|
|
// I?
|
|
|
|
// I: FlightUUID
|
|
|
|
// ?: Subscribed to flight data
|
|
|
|
let ret = [];
|
2019-08-01 01:56:46 +02:00
|
|
|
ret.push( this.readUint32(data) );
|
|
|
|
ret.push( this.readUint8(data) != 0 );
|
2019-07-31 01:08:19 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle_packet3(data) { // TODO: implement (Whole data / history)
|
2019-08-01 01:14:28 +02:00
|
|
|
// xs
|
2019-07-31 01:08:19 +02:00
|
|
|
// s: DataStream
|
2019-08-01 01:14:28 +02:00
|
|
|
let ret = {};
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["uuid"] = this.readUint32(data);
|
|
|
|
ret["maxFuel"] = this.readFloat32(data);
|
|
|
|
ret["model"] = this.readUint16(data);
|
|
|
|
let playernameLength = this.readUint8(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
let playername = "";
|
|
|
|
for (let i = 0; i < playernameLength; i++)
|
2019-08-01 01:56:46 +02:00
|
|
|
playername += String.fromCharCode( this.readUint8(data) );
|
2019-08-01 01:14:28 +02:00
|
|
|
ret["playername"] = playername;
|
|
|
|
|
|
|
|
let timeline = [];
|
|
|
|
while (this.pointer < data.byteLength)
|
|
|
|
timeline.push( this.parseFrame(data) );
|
|
|
|
ret["timeline"] = timeline;
|
|
|
|
return ret;
|
2019-07-31 01:08:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handle_packet4(data) {
|
|
|
|
// I?
|
|
|
|
// I: FlightUUID
|
|
|
|
// ?: Flight active
|
|
|
|
let ret = [];
|
2019-08-01 01:56:46 +02:00
|
|
|
ret.push( this.readUint32(data) );
|
|
|
|
ret.push( this.readUint8(data) != 0 );
|
2019-07-31 01:08:19 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-08-01 01:14:28 +02:00
|
|
|
handle_packet5(data) {
|
2019-07-31 01:08:19 +02:00
|
|
|
// Ixs
|
2019-08-01 01:14:28 +02:00
|
|
|
// I: FlightUUID
|
2019-07-31 01:08:19 +02:00
|
|
|
// s: DataStream
|
2019-08-01 01:14:28 +02:00
|
|
|
let ret = [];
|
2019-08-01 01:56:46 +02:00
|
|
|
ret.push( this.readUint32(data) );
|
2019-08-01 01:14:28 +02:00
|
|
|
ret.push( this.parseFrame(data) );
|
|
|
|
return ret;
|
2019-07-31 01:08:19 +02:00
|
|
|
}
|
|
|
|
|
2019-07-31 17:10:07 +02:00
|
|
|
handle_packet255(data) {
|
|
|
|
// Hxs
|
|
|
|
// H: Length
|
|
|
|
// s: ErrorMessage
|
|
|
|
let ret = "";
|
2019-08-01 01:56:46 +02:00
|
|
|
let length = this.readUint16(data);
|
2019-07-31 17:10:07 +02:00
|
|
|
for (let i = 0; i < length; i++) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret += String.fromCharCode( this.readUint8(data) );
|
2019-07-31 17:10:07 +02:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-07-31 01:08:19 +02:00
|
|
|
handle_packetInvalid(data) {
|
|
|
|
throw TypeError(`Invalid DATA: ${Array.from( this.buffer2HexArray(data, --this.pointer) ).join(" ")}`);
|
|
|
|
}
|
|
|
|
|
2019-08-01 01:14:28 +02:00
|
|
|
parseFrame(data) {
|
|
|
|
// IBxs
|
|
|
|
// I: Timestamp
|
|
|
|
// B: Flag
|
|
|
|
// s: FrameStream
|
|
|
|
let ret = {};
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["timestamp"] = this.readUint32(data);
|
|
|
|
let flags = this.readUint8(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
if (flags & (1<<0)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
let statusFlag = this.readUint8(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
ret["paused"] = !!( statusFlag & (1<<0) );
|
|
|
|
ret["engine"] = !!( statusFlag & (1<<1) );
|
|
|
|
}
|
|
|
|
if (flags & (1<<1)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["satisfaction"] = this.readUint8(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<2)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["speed"] = this.readUint16(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<3)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["altitude"] = this.readInt16(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<4)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["health"] = this.readUint16(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<5)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["fuel"] = this.readFloat32(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<6)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["x"] = this.readFloat32(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
if (flags & (1<<7)) {
|
2019-08-01 01:56:46 +02:00
|
|
|
ret["y"] = this.readFloat32(data);
|
2019-08-01 01:14:28 +02:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-07-31 01:08:19 +02:00
|
|
|
*buffer2HexArray(buff, start = 0, end = buff.byteLength) {
|
|
|
|
for (let i = start; i < end; i++) {
|
2019-08-01 19:02:47 +02:00
|
|
|
yield buff.getUint8(i).toString(16);
|
2019-07-31 01:08:19 +02:00
|
|
|
}
|
|
|
|
}
|
2019-08-01 19:02:47 +02:00
|
|
|
}
|