Separate specification from example implementation.

Unkie 2016-04-25 16:38:17 +10:00
parent fbf95d2eac
commit 63a2f6cd7f

@ -1,3 +1,34 @@
The Classic BlockDB format is relatively simple, with the format consisting of a sequence of 16 byte blocks.<br/>
The blocks are in the order: _BlockDB header_, then _BlockDB metadata_, then a variable number of _BlockDB entry_.
##### BlockDB header block
```
4 | Format identifier "cbdb"
1 | Format version, currently '1'
1 | Years offset (unsigned). Reference point = first second of year (1970 + offset)
2 | Width of the map
2 | Height of the map (vertical)
2 | Length of the map
4 | Reserved
```
##### BlockDB metadata block
```
16 | ASCII software name
16 | Reserved
16 | Reserved
```
##### BlockDB entry block
```
4 | Player ID
4 | Packed index (x + width * (z + y * length))
4 | Time delta in seconds from reference point
1 | Old block ID
1 | New block ID
2 | Flags
```
```CSharp
using System;
using System.IO;
@ -28,7 +59,7 @@ namespace ClassicBlockDB {
if (r.ReadByte() > formatVersion)
throw new NotSupportedException("Only version 1 of the format is currently supported.");
referenceOffset = r.ReadSByte();
referenceOffset = r.ReadUInt8();
Width = r.ReadUInt16(); Height = r.ReadUInt16(); Length = r.ReadUInt16();
padding = r.ReadInt32();
ReferenceTime = new DateTime(1970 + referenceOffset, 1, 1, 1, 1, 1, DateTimeKind.Utc);
@ -47,8 +78,7 @@ namespace ClassicBlockDB {
chunk[chunkIndex + 12] = entry.OldBlock;
chunk[chunkIndex + 13] = entry.NewBlock;
chunk[chunkIndex + 14] = entry.Context;
chunk[chunkIndex + 15] = entry.Flags;
WriteUInt16(chunk, chunkIndex + 14, entry.Flags);
}
s.Write(chunk, 0, count * BlockDBEntry.Size);
}
@ -69,8 +99,7 @@ namespace ClassicBlockDB {
entry.OldBlock = chunk[j + 12];
entry.NewBlock = chunk[j + 13];
entry.Context = chunk[j + 14];
entry.Flags = chunk[j + 15];
entry.Flags = ReadUInt16(chunk, j + 14);
entries[i + (j / BlockDBEntry.Size)] = entry;
}
}
@ -118,12 +147,12 @@ namespace ClassicBlockDB {
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BlockDBEntry {
public int PlayerID; // numerical player id unique for each player
public int Index; // packed index according to (width, height, length)
public int TimeDelta; // seconds since the reference point
public byte OldBlock, NewBlock;
public byte Context, Flags;
struct BlockDBEntry {
Int32 PlayerID; // numerical player id unique for each player
Int32 Index; // packed index according to (width, height, length)
Int32 TimeDelta; // seconds since the reference point
UInt8 OldBlock, NewBlock;
UInt16 Flags;
// MCGalaxy specific flags:
// bit 0 set: old block is a physics block, not an ext tile.