From 63a2f6cd7f1d3f9319bc3fdad0386cd6ed9c28fa Mon Sep 17 00:00:00 2001 From: Unkie Date: Mon, 25 Apr 2016 16:38:17 +1000 Subject: [PATCH] Separate specification from example implementation. --- Classic-BlockDB-draft.md | 51 +++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/Classic-BlockDB-draft.md b/Classic-BlockDB-draft.md index 9857ddc..9a0e6c0 100644 --- a/Classic-BlockDB-draft.md +++ b/Classic-BlockDB-draft.md @@ -1,3 +1,34 @@ +The Classic BlockDB format is relatively simple, with the format consisting of a sequence of 16 byte blocks.
+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.