예제 #1
0
        //we only write to the ToD data format.
        public void writeToDat(string filename)
        {
            fileSize  = inputBlockCache.fileSize;
            freeHead  = inputBlockCache.freeHead;
            freeTail  = inputBlockCache.freeTail;
            freeCount = inputBlockCache.freeCount;

            StreamWriter outputFile = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write));

            Console.WriteLine("Writing data to {0}...", filename);
            Stopwatch timer = new Stopwatch();

            timer.Start();

            ////keep some free blocks
            //if (inputBlockCache.freeCount < 1000)
            //    inputBlockCache.addNewFreeBlocks(1000 - (int)inputBlockCache.freeCount);

            //rootDirectory.updateBlockData(this, inputBlockCache);

            //foreach (KeyValuePair<uint, cDatFileBlock> entry in inputBlockCache.blocks)
            //{
            //    outputFile.BaseStream.Seek(entry.Key, SeekOrigin.Begin);
            //    entry.Value.writeToDat(outputFile, blockSize);
            //}

            //fileSize = inputBlockCache.fileSize;
            //freeHead = inputBlockCache.fileSize;
            //freeTail = inputBlockCache.fileSize;
            //freeCount = inputBlockCache.fileSize;

            bTree = new cBTree(31);

            foreach (KeyValuePair <uint, cDatFileEntry> entry in fileCache)
            {
                bTree.Insert(entry.Key);
            }

            outputBlockCache = new cDatFileBlockCache(blockSize, 1024);
            rootDirectory    = buildBtreeStructure(bTree.Root, outputBlockCache);
            rootDirectory.updateBlockData(this, outputBlockCache);

            foreach (KeyValuePair <uint, cDatFileBlock> entry in outputBlockCache.blocks)
            {
                outputFile.BaseStream.Seek(entry.Key, SeekOrigin.Begin);
                entry.Value.writeToDat(outputFile, blockSize);
            }

            if (outputBlockCache.freeCount < 1000)
            {
                outputBlockCache.addNewFreeBlocks(1000 - (int)outputBlockCache.freeCount);
            }

            rootDirectoryOffset = rootDirectory.startBlockOffset;
            fileSize            = outputBlockCache.fileSize;
            freeHead            = outputBlockCache.fileSize;
            freeTail            = outputBlockCache.fileSize;
            freeCount           = outputBlockCache.fileSize;

            outputFile.BaseStream.Seek(256, SeekOrigin.Begin); //skip acVersionStr which is empty
            Utils.writeBytes(acTransactionRecord, outputFile);

            Utils.writeUInt32(fileType, outputFile);

            Utils.writeInt32(blockSize, outputFile);
            Utils.writeUInt32(fileSize, outputFile);
            Utils.writeUInt32(dataSet, outputFile);
            Utils.writeUInt32(dataSubset, outputFile);

            Utils.writeUInt32(freeHead, outputFile);
            Utils.writeUInt32(freeTail, outputFile);
            Utils.writeUInt32(freeCount, outputFile);
            Utils.writeUInt32(rootDirectoryOffset, outputFile);

            Utils.writeUInt32(youngLRU, outputFile);
            Utils.writeUInt32(oldLRU, outputFile);
            Utils.writeUInt32(useLRU, outputFile);

            Utils.writeUInt32(masterMapId, outputFile);

            Utils.writeUInt32(enginePackVersion, outputFile);
            Utils.writeUInt32(gamePackVersion, outputFile);
            Utils.writeBytes(versionMajor, outputFile);
            Utils.writeUInt32(versionMinor, outputFile);

            outputFile.Close();
            timer.Stop();
            Console.WriteLine("{0} blocks written in {1} seconds.", outputBlockCache.blocks.Count, timer.ElapsedMilliseconds / 1000f);

            //exportDirTree(rootDirectory);
        }
예제 #2
0
        public void updateBlockData(cDatFile datFile, cDatFileBlockCache blockCache)
        {
            MemoryStream memoryStream = new MemoryStream(new byte[sizeToD]);
            StreamWriter writer       = new StreamWriter(memoryStream);

            for (int i = 0; i < 62; i++)
            {
                if (i == 0 && subFolders.Count == 0)
                {
                    Utils.writeUInt32(0, writer);
                }
                else if (i < subFolders.Count && i < files.Count + 1) //directory is allowed to have (files + 1) subdirectories
                {
                    cDatFileNode subFolder = subFolders[i];

                    subFolder.updateBlockData(datFile, blockCache);

                    Utils.writeUInt32(subFolder.startBlockOffset, writer);
                }
                else
                {
                    Utils.writeUInt32(0xcdcdcdcd, writer);
                }
            }

            Utils.writeUInt32((uint)files.Count, writer);

            foreach (KeyValuePair <uint, cDatFileEntry> entry in files)
            {
                cDatFileEntry fileEntry = entry.Value;
                if (fileEntry.fileContent != null)
                {
                    fileEntry.fileSize = (int)fileEntry.fileContent.Length;
                    blockCache.dataToBlocks(fileEntry.listOfBlocks, fileEntry.fileContent);
                    if (fileEntry.listOfBlocks.Count > 0)
                    {
                        fileEntry.startBlockOffset = fileEntry.listOfBlocks[0].blockOffset;
                    }
                }
                else
                {
                    fileEntry.fileSize = 0;
                }
                fileEntry.writeHeader(writer);
            }

            cDatFileEntry emptyFileEntry = new cDatFileEntry(0, datFile.fileFormat);

            for (int i = files.Count; i < 61; i++)
            {
                emptyFileEntry.writeHeader(writer);
            }

            writer.Flush();

            blockCache.dataToBlocks(listOfBlocks, memoryStream);
            if (listOfBlocks.Count > 0)
            {
                startBlockOffset = listOfBlocks[0].blockOffset;
            }
        }