public async Task WriteBinaryResponse(List <DbInventory> inventories)
        {
            //Binary mode writes out structures in binary structs
            //In format header, name table, inventory struct

            //HEADER FORMAT:
            //  4   static  Signature, says "DWMI"
            //  4   int32   File type version, should be 1
            //  4   int32   RESERVED
            //  4   int32   Inventory count

            //  4   int32   Saved epoch
            //  4   int32   Name table entry count
            //  4   int32   RESERVED
            //  4   int32   RESERVED
            //TOTAL: 32 bytes

            //The name table comes next, and is just a list of classnames, with a byte indicating their length before

            //Inventory Struct format:
            //  8   int64   Holder ID
            //  1   byte    Holder type
            //  2   int16   Item count
            //  4   int32   Tribe ID
            //  ?   Item[]  Items
            //TOTAL: VARIABLE

            //Item struct format:
            //  8   int64   Item ID
            //  4   int32   Name table classname index
            //  4   float   Durability
            //  2   int16   Stack size
            //  2   int16   Flags
            //  1   byte    Custom data count
            //  ?   CD[]    Custom datas, number specified above
            //Total: VARIABLE

            //CD (Custom Data) format:
            //  2   int16   Tag
            //  2   int16   String length
            //  ?   string  Data

            //Set headers
            e.Response.ContentType = "application/octet-stream";
            e.Response.StatusCode  = 200;

            //Create name table
            List <string> names = new List <string>();

            foreach (var i in inventories)
            {
                foreach (var ii in i.items)
                {
                    if (!names.Contains(ii.classname))
                    {
                        names.Add(ii.classname);
                    }
                }
            }

            //Create and send file header
            byte[] buf = new byte[32768];
            buf[0] = 0x44;
            buf[1] = 0x57;
            buf[2] = 0x4D;
            buf[3] = 0x49;
            BinaryTool.WriteInt32(buf, 4, 2); //Version tag
            BinaryTool.WriteInt32(buf, 8, 0);
            BinaryTool.WriteInt32(buf, 12, inventories.Count);
            BinaryTool.WriteInt32(buf, 16, 0); //Was epoch, now unused
            BinaryTool.WriteInt32(buf, 20, names.Count);
            BinaryTool.WriteInt32(buf, 24, 0);
            BinaryTool.WriteInt32(buf, 28, 0);
            await e.Response.Body.WriteAsync(buf, 0, 32);

            //Send name table
            foreach (var name in names)
            {
                //Write to buffer
                byte[] d = Encoding.UTF8.GetBytes(name);
                buf[0] = (byte)d.Length;
                if (d.Length > byte.MaxValue)
                {
                    throw new Exception("Encoding failed, name is too long!");
                }
                Array.Copy(d, 0, buf, 1, d.Length);

                //Send on network
                await e.Response.Body.WriteAsync(buf, 0, d.Length + 1);
            }

            //Send inventories
            foreach (var inventory in inventories)
            {
                //Create header
                BinaryTool.WriteUInt64(buf, 0, inventory.holder_id);
                buf[8] = (byte)inventory.holder_type;
                BinaryTool.WriteInt16(buf, 9, (short)inventory.items.Length);
                BinaryTool.WriteInt32(buf, 11, inventory.tribe_id);
                int offset = 15;

                //Add items
                foreach (var i in inventory.items)
                {
                    //Create header
                    BinaryTool.WriteUInt64(buf, offset, i.item_id);
                    BinaryTool.WriteInt32(buf, offset + 8, names.IndexOf(i.classname));
                    BinaryTool.WriteFloat(buf, offset + 12, i.durability);
                    BinaryTool.WriteInt16(buf, offset + 16, (short)i.stack_size);
                    BinaryTool.WriteInt16(buf, offset + 18, (short)i.flags);
                    buf[offset + 20] = (byte)i.custom_data.Count;
                    offset          += 21;

                    //Write custom datas
                    foreach (var c in i.custom_data)
                    {
                        //Write key
                        byte[] d = Encoding.UTF8.GetBytes(c.Key);
                        BinaryTool.WriteInt16(buf, offset, (short)d.Length);
                        Array.Copy(d, 0, buf, offset + 2, d.Length);
                        offset += 2 + d.Length;

                        //Write value
                        d = Encoding.UTF8.GetBytes(c.Value);
                        BinaryTool.WriteInt16(buf, offset, (short)d.Length);
                        Array.Copy(d, 0, buf, offset + 2, d.Length);
                        offset += 2 + d.Length;
                    }
                }

                //Send data
                await e.Response.Body.WriteAsync(buf, 0, offset);

                offset = 0;
            }
        }
        public async Task WriteBinaryResponse(List <DbStructure> structures)
        {
            //Binary mode writes out structures in binary structs

            //HEADER FORMAT:
            //  4   static  Signature, says "DWMS"
            //  4   int32   File type version, should be 3
            //  4   int32   Metadata version
            //  4   int32   Structure count

            //  4   int32   Saved epoch
            //  4   int32   RESERVED
            //  4   int32   RESERVED
            //  4   int32   RESERVED
            //TOTAL: 32 bytes

            //Struct format:
            //  2   short   Metadata Index
            //  1   byte    Rotation (in degrees, 0-360, but scaled so that 256=360)
            //  1   byte    Flags (SEE BELOW)
            //  4   float   Position X
            //  4   float   Position Y
            //  4   int32   ID
            //  4   float   Position Z
            //  4   int32   Tribe ID
            //TOTAL: 24 bytes each

            //FLAGS
            //0: Has inventory
            //1: Is remove
            //2: RESERVED
            //3: RESERVED
            //4: RESERVED
            //5: RESERVED
            //6: RESERVED
            //7: RESERVED

            //Set headers
            e.Response.ContentLength = (24 * structures.Count) + 32;
            e.Response.ContentType   = "application/octet-stream";
            e.Response.StatusCode    = 200;

            //Create and send file header
            byte[] buf = new byte[32];
            buf[0] = 0x44;
            buf[1] = 0x57;
            buf[2] = 0x4D;
            buf[3] = 0x53;
            BinaryTool.WriteInt32(buf, 4, 3); //Version tag
            BinaryTool.WriteInt32(buf, 8, 0);
            BinaryTool.WriteInt32(buf, 12, structures.Count);

            BinaryTool.WriteInt32(buf, 16, 0); //Was epoch, now unused
            BinaryTool.WriteInt32(buf, 20, 0);
            BinaryTool.WriteInt32(buf, 24, 0);
            BinaryTool.WriteInt32(buf, 28, 0);

            await e.Response.Body.WriteAsync(buf, 0, 32);

            //Loop through structures and find where they are
            foreach (var t in structures)
            {
                //Get data
                StructureMetadata metadata = Program.structureMetadata.Where(x => x.names.Contains(t.classname)).FirstOrDefault();
                int index = Program.structureMetadata.IndexOf(metadata);

                //Produce flags
                byte flags = 0;
                if (t.has_inventory)
                {
                    flags |= 0x01 << 0;
                }

                //Write parts
                BinaryTool.WriteInt16(buf, 0, (short)index);
                buf[2] = (byte)(t.location.yaw * 0.70833333333333333333333333333333f); //Scales this to fit the 0-360 degrees into 0-255
                buf[3] = flags;
                BinaryTool.WriteFloat(buf, 4, t.location.x);
                BinaryTool.WriteFloat(buf, 8, t.location.y);
                BinaryTool.WriteInt32(buf, 12, t.structure_id);
                BinaryTool.WriteFloat(buf, 16, t.location.z);
                BinaryTool.WriteInt32(buf, 20, t.tribe_id);

                //Write to stream
                await e.Response.Body.WriteAsync(buf, 0, 24);
            }
        }