private void Parse(DatReader reader, List <DatFile> allFiles) { reader.Seek(Offset); // actual directories are 2 DWORDS over, but validate those 2 DWORDS are 0 uint word1 = reader.ReadUInt32(); uint word2 = reader.ReadUInt32(); if (word1 != 0 || word2 != 0) { return; } byte[] buffer = new byte[DatConstants.DIR_BLOCK_SIZE]; reader.Read(buffer, 0, buffer.Length); // directories for (int i = 0; i < DatConstants.MAX_DIRS; i++) { uint newDirSize = BitConverter.ToUInt32(buffer, (i * 2) * sizeof(uint)); uint newDirOffset = BitConverter.ToUInt32(buffer, (i * 2) * sizeof(uint) + 4); if (Size != newDirSize) { break; } if (newDirOffset == 0x00) { break; } if (newDirOffset == 0xCDCDCDCD) { break; } var subDir = new DatDirectory(newDirOffset, newDirSize); Directories.Add(subDir); } buffer = new byte[DatConstants.FILE_BLOCK_SIZE]; reader.Read(buffer, 0, buffer.Length); // files for (int i = 0; i < DatConstants.MAX_FILES; i++) { // each file is 8 DWORDS int thisFile = i * 8 * sizeof(uint); DatFile df = DatFile.FromDirectoryBuffer(buffer, thisFile); if (df != null) { Files.Add(df); allFiles.Add(df); } else { break; // null file means end of listing } } Directories.ForEach(d => d.Parse(reader, allFiles)); }
public DatDatabase(string filename) { _filename = filename; using (var dr = new DatReader(_filename)) { dr.Seek(_offset); _magicNumber = dr.ReadUInt32(); // 0x0140 _blockSize = dr.ReadUInt32(); // 0x0144 _fileSize = dr.ReadUInt32(); // 0x0148 _fileVersion = dr.ReadUInt32(); // 0x014C dr.ReadUInt32(); // unknown, 0x0150 _firstFreeBlock = dr.ReadUInt32(); // guess? 0x0154 _lastFreeBlock = dr.ReadUInt32(); // 0x0158 _freeBlockCount = dr.ReadUInt32(); // 0x015C _rootOffset = dr.ReadUInt32(); // 0x0160 dr.ReadUInt32(); // unknown, all 0s, 0x0164 dr.ReadUInt32(); // unknown, all 0s, 0x0168 dr.ReadUInt32(); // unknown, all 0s, 0x016C dr.ReadUInt32(); // unknown, all 0s, 0x0170 _datpackEngine = dr.ReadUInt32(); // "datpack version engine" - from dndclient.log, 0x0174 _gameId = dr.ReadUInt32(); // "datpack version game" - from dndclient.log, 0x0178 _rootDirectory = new DatDirectory(_rootOffset, _blockSize, dr, this.AllFiles); } }
internal DatDirectory(uint offset, uint size, DatReader reader, List <DatFile> allFiles) { Offset = offset; Size = size; Parse(reader, allFiles); }
public byte[] GetData(uint offset, int length) { try { byte[] buffer = new byte[length]; using (var dr = new DatReader(_filename)) { dr.Seek(offset, SeekOrigin.Begin); dr.Read(buffer, 0, length); } return(buffer); } catch (OutOfMemoryException) { return(System.Text.ASCIIEncoding.ASCII.GetBytes("Not enough memory.")); } }