diff --git a/test.html b/test.html
deleted file mode 100644
index 4a6266f..0000000
--- a/test.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- WebSocket test
-
-
-
-
-
\ No newline at end of file
diff --git a/www/js/fly-ws.js b/www/js/fly-ws.js
new file mode 100644
index 0000000..0135fc1
--- /dev/null
+++ b/www/js/fly-ws.js
@@ -0,0 +1,115 @@
+class FLYSocket {
+ constructor(ws,
+ callbackData = this.callbackDummy,
+ callbackRaw = this.callbackDummy) {
+ 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);
+ this.callbackRaw(data);
+
+ if (this.callbackData != this.callbackDummy || true) { // DEBUG
+ this.callbackData( this.parse(data) );
+ }
+ }.bind(this)
+ );
+ }
+
+ parse(data) {
+ window.data = data; // DEBUG
+ let packets = [];
+ this.pointer = 0;
+
+ while (this.pointer < data.byteLength) {
+ let packetID = data.getInt8(this.pointer++);
+ packets.push({
+ packetID: packetID,
+ value: (this["handle_packet" + packetID] || this.handle_packetInvalid)(data)
+ });
+ }
+
+ return packets;
+ }
+
+ handle_packet0(data) {
+ // BxI
+ // B: Length
+ // I: FlightUUID
+ let ret = [];
+ let length = data.getUint8(this.pointer++);
+ for (let i = 0; i < length; i++) {
+ ret.push( data.getUint16(this.pointer) );
+ this.pointer += 2;
+ }
+ return ret;
+ }
+
+ handle_packet1(data) {
+ // ?
+ // ?: Subscribed to changes
+ return data.getUint8(this.pointer++) != 0;
+ }
+
+ handle_packet2(data) {
+ // I?
+ // I: FlightUUID
+ // ?: Subscribed to flight data
+ let ret = [];
+ ret.push( data.getUint16(this.pointer) ); this.pointer += 2;
+ ret.push( data.getUint8(this.pointer++) != 0 );
+ return ret;
+ }
+
+ handle_packet3(data) { // TODO: implement (Whole data / history)
+ // Ixs
+ // I: Length
+ // s: DataStream
+ return ret = [];
+ }
+
+ handle_packet4(data) {
+ // I?
+ // I: FlightUUID
+ // ?: Flight active
+ let ret = [];
+ ret.push( data.getUint16(this.pointer) ); this.pointer += 2;
+ ret.push( data.getUint8(this.pointer++) != 0 );
+ return ret;
+ }
+
+ handle_packet5(data) { // TODO: implement (One frame)
+ // Ixs
+ // I: Length
+ // s: DataStream
+ }
+
+ handle_packetInvalid(data) {
+ throw TypeError(`Invalid DATA: ${Array.from( this.buffer2HexArray(data, --this.pointer) ).join(" ")}`);
+ }
+
+ *buffer2HexArray(buff, start = 0, end = buff.byteLength) {
+ for (let i = start; i < end; i++) {
+ yield hex.push( buff.getUint8(i).toString(16) );
+ }
+ }
+
+ callbackDummy(_) {}
+}
+
+class Flight {
+ constructor(uuid) {
+ this.uuid = uuid;
+ this.playername;
+ }
+}
+
+console.log("OK") // TODO: please remove...
\ No newline at end of file
diff --git a/www/js/struct/LICENSE b/www/js/struct/LICENSE
new file mode 100644
index 0000000..7faf434
--- /dev/null
+++ b/www/js/struct/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Aksel Jensen (TheRealAksel at github)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/www/js/struct/struct.js b/www/js/struct/struct.js
new file mode 100644
index 0000000..abcfc20
--- /dev/null
+++ b/www/js/struct/struct.js
@@ -0,0 +1,60 @@
+// https://github.com/lyngklip/structjs
+"use strict"
+const rechk = /^([<>])?(([1-9]\d*)?([xcbB?hHiIfdsp]))*$/
+const refmt = /([1-9]\d*)?([xcbB?hHiIfdsp])/g
+const str = (v,o,c) => String.fromCharCode(
+ ...new Uint8Array(v.buffer, v.byteOffset + o, c))
+const rts = (v,o,c,s) => new Uint8Array(v.buffer, v.byteOffset + o, c)
+ .set(s.split('').map(str => str.charCodeAt(0)))
+const pst = (v,o,c) => str(v, o + 1, Math.min(v.getUint8(o), c - 1))
+const tsp = (v,o,c,s) => { v.setUint8(o, s.length); rts(v, o + 1, c - 1, s) }
+const lut = le => ({
+ x: c=>[1,c,0],
+ c: c=>[c,1,o=>({u:v=>str(v, o, 1) , p:(v,c)=>rts(v, o, 1, c) })],
+ '?': c=>[c,1,o=>({u:v=>Boolean(v.getUint8(o)),p:(v,B)=>v.setUint8(o,B)})],
+ b: c=>[c,1,o=>({u:v=>v.getInt8( o ), p:(v,b)=>v.setInt8( o,b )})],
+ B: c=>[c,1,o=>({u:v=>v.getUint8( o ), p:(v,B)=>v.setUint8( o,B )})],
+ h: c=>[c,2,o=>({u:v=>v.getInt16( o,le), p:(v,h)=>v.setInt16( o,h,le)})],
+ H: c=>[c,2,o=>({u:v=>v.getUint16( o,le), p:(v,H)=>v.setUint16( o,H,le)})],
+ i: c=>[c,4,o=>({u:v=>v.getInt32( o,le), p:(v,i)=>v.setInt32( o,i,le)})],
+ I: c=>[c,4,o=>({u:v=>v.getUint32( o,le), p:(v,I)=>v.setUint32( o,I,le)})],
+ f: c=>[c,4,o=>({u:v=>v.getFloat32(o,le), p:(v,f)=>v.setFloat32(o,f,le)})],
+ d: c=>[c,8,o=>({u:v=>v.getFloat64(o,le), p:(v,d)=>v.setFloat64(o,d,le)})],
+ s: c=>[1,c,o=>({u:v=>str(v,o,c), p:(v,s)=>rts(v,o,c,s.slice(0,c ) )})],
+ p: c=>[1,c,o=>({u:v=>pst(v,o,c), p:(v,s)=>tsp(v,o,c,s.slice(0,c - 1) )})]
+})
+const errbuf = new RangeError("Structure larger than remaining buffer")
+const errval = new RangeError("Not enough values for structure")
+const struct = format => {
+ let fns = [], size = 0, m = rechk.exec(format)
+ if (!m) { throw new RangeError("Invalid format string") }
+ const t = lut('<' === m[1]), lu = (n, c) => t[c](n ? parseInt(n, 10) : 1)
+ while ((m = refmt.exec(format))) { ((r, s, f) => {
+ for (let i = 0; i < r; ++i, size += s) { if (f) {fns.push(f(size))} }
+ })(...lu(...m.slice(1)))}
+ const unpack_from = (arrb, offs) => {
+ if (arrb.byteLength < (offs|0) + size) { throw errbuf }
+ let v = new DataView(arrb, offs|0)
+ return fns.map(f => f.u(v))
+ }
+ const pack_into = (arrb, offs, ...values) => {
+ if (values.length < fns.length) { throw errval }
+ if (arrb.byteLength < offs + size) { throw errbuf }
+ const v = new DataView(arrb, offs)
+ new Uint8Array(arrb, offs, size).fill(0)
+ fns.forEach((f, i) => f.p(v, values[i]))
+ }
+ const pack = (...values) => {
+ let b = new ArrayBuffer(size)
+ pack_into(b, 0, ...values)
+ return b
+ }
+ const unpack = arrb => unpack_from(arrb, 0)
+ function* iter_unpack(arrb) {
+ for (let offs = 0; offs + size <= arrb.byteLength; offs += size) {
+ yield unpack_from(arrb, offs);
+ }
+ }
+ return Object.freeze({
+ unpack, pack, unpack_from, pack_into, iter_unpack, format, size})
+}
\ No newline at end of file
diff --git a/www/main.html b/www/main.html
new file mode 100644
index 0000000..df3739b
--- /dev/null
+++ b/www/main.html
@@ -0,0 +1,164 @@
+
+
+
+ WebSocket DEMO
+
+
+
+
+
+
+
Websocket DEMO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file