public byte[] Write(EzPacket packet)
        {
            IBuffer data = EzServer.Buffer.Provide();

            data.WriteInt16(packet.Id);
            data.WriteInt32(packet.Data.Size);
            data.WriteByte(0);
            data.WriteBuffer(packet.Data);
            return(data.GetAllBytes());
        }
예제 #2
0
            protected void Send(ITcpSocket socket, ushort opCode, IBuffer response)
            {
                byte[]  payload = response.GetAllBytes();
                int     opSize  = 2;
                int     size    = payload.Length + opSize;
                IBuffer buffer  = new StreamBuffer();

                buffer.SetPositionStart();
                buffer.WriteInt16((short)size, Endianness.Big);
                buffer.WriteInt16(opCode, Endianness.Big);
                buffer.WriteBytes(payload);
                socket.Send(buffer.GetAllBytes());
                PacketLogOut(buffer);
            }
예제 #3
0
        public byte[] Write(MhfPacket packet)
        {
            if (packet.Data.Size > ushort.MaxValue)
            {
                _logger.Error(
                    $"Packet Size: {packet.Data.Size} exceeds maximum size of {ushort.MaxValue} for PacketId: {packet.Id}");
                return(null);
            }

            byte[] data = packet.Data.GetAllBytes();


            byte keyRotDelta = 2;

            // Update the rolling key index.
            if (keyRotDelta != 0)
            {
                _sendKeyRot = keyRotDelta * (_sendKeyRot + 1);
            }

            data = Encrypt(data, _sendKeyRot,
                           out ushort combinedCheck, out ushort check0,
                           out ushort check1, out ushort check2);

            packet.Header.DataSize      = (ushort)data.Length;
            packet.Header.Pf0           = (byte)(((packet.Header.DataSize >> 12) & 0xF3) | 3);
            packet.Header.KeyRotDelta   = keyRotDelta;
            packet.Header.CombinedCheck = 0;
            packet.Header.Check0        = check0;
            packet.Header.Check1        = check1;
            packet.Header.Check2        = check2;

            Console.WriteLine(packet.Header.ToLogText());

            IBuffer buffer = BufferProvider.Provide();

            buffer.WriteByte(packet.Header.Pf0);
            buffer.WriteByte(packet.Header.KeyRotDelta);
            buffer.WriteInt16(packet.Header.Id, Endianness.Big);
            buffer.WriteInt16(packet.Header.DataSize, Endianness.Big);
            buffer.WriteInt16(packet.Header.CombinedCheck, Endianness.Big);
            buffer.WriteInt16(packet.Header.Check0, Endianness.Big);
            buffer.WriteInt16(packet.Header.Check1, Endianness.Big);
            buffer.WriteInt16(packet.Header.Check2, Endianness.Big);
            buffer.WriteBytes(data);
            byte[] final = buffer.GetAllBytes();
            return(final);
        }
예제 #4
0
        public byte[] Write(Packet packet)
        {
            byte[]  data       = packet.Data.GetAllBytes();
            IBuffer buffer     = KrGameServer.Buffer.Provide();
            int     dataLength = data.Length + PacketHeaderSize;

            if (dataLength < 0 || dataLength > ushort.MaxValue)
            {
                Logger.Error($"dataLength < 0 || dataLength > ushort.MaxValue (dataLength:{dataLength})");
            }

            buffer.WriteUInt16((ushort)dataLength);
            buffer.WriteUInt16(packet.Id);
            buffer.WriteBytes(data);
            return(buffer.GetAllBytes());
        }
예제 #5
0
        public byte[] Write(NecPacket packet, NecClient client)
        {
            // TODO update arrowgene service to write uint*

            byte[]  data     = packet.Data.GetAllBytes();
            IBuffer buffer   = BufferProvider.Provide();
            ulong   dataSize = (ushort)(data.Length + PacketIdSize);

            PacketLengthType packetLengthType;

            if (dataSize < byte.MaxValue)
            {
                packetLengthType = PacketLengthType.Byte;
                buffer.WriteByte((byte)packetLengthType);
                buffer.WriteByte((byte)dataSize);
            }
            else if (dataSize < ushort.MaxValue)
            {
                packetLengthType = PacketLengthType.UInt16;
                buffer.WriteByte((byte)packetLengthType);
                buffer.WriteInt16((ushort)dataSize);
            }
            else if (dataSize < uint.MaxValue)
            {
                packetLengthType = PacketLengthType.UInt32;
                buffer.WriteByte((byte)packetLengthType);
                buffer.WriteInt32((uint)dataSize);
            }
            else
            {
                _logger.Error($"{dataSize} to big");
                return(null);
            }

            buffer.WriteInt16(packet.Id);
            buffer.WriteBytes(data);

            byte headerSize = CalculateHeaderSize(packetLengthType);

            packet.Header = buffer.GetBytes(0, headerSize);

            return(buffer.GetAllBytes());
        }
예제 #6
0
        public byte[] Write(NecPacket packet)
        {
            byte[]  data   = packet.Data.GetAllBytes();
            IBuffer buffer = BufferProvider.Provide();

            PacketType packetType;

            switch (packet.PacketType)
            {
            case PacketType.HeartBeat:
                packetType = PacketType.HeartBeat;
                buffer.WriteByte((byte)packetType);
                buffer.WriteBytes(data);
                break;

            case PacketType.Unknown1:
                packetType = PacketType.Unknown1;
                buffer.WriteByte((byte)packetType);
                buffer.WriteBytes(data);
                break;

            case PacketType.Disconnect:
                packetType = PacketType.Disconnect;
                buffer.WriteByte((byte)packetType);
                buffer.WriteBytes(data);
                break;

            default:
                ulong dataSize = (ulong)(data.Length + PacketIdSize);
                if (dataSize < byte.MaxValue)
                {
                    packetType = PacketType.Byte;
                    buffer.WriteByte((byte)packetType);
                    buffer.WriteByte((byte)dataSize);
                }
                else if (dataSize < ushort.MaxValue)
                {
                    packetType = PacketType.UInt16;
                    buffer.WriteByte((byte)packetType);
                    buffer.WriteUInt16((ushort)dataSize);
                }
                else if (dataSize < uint.MaxValue)
                {
                    packetType = PacketType.UInt32;
                    buffer.WriteByte((byte)packetType);
                    buffer.WriteUInt32((uint)dataSize);
                }
                else
                {
                    Logger.Error($"{dataSize} to big");
                    return(null);
                }

                buffer.WriteUInt16(packet.Id);
                buffer.WriteBytes(data);
                break;
            }

            byte headerSize = CalculateHeaderSize(packetType);

            packet.Header = buffer.GetBytes(0, headerSize);

            return(buffer.GetAllBytes());
        }
예제 #7
0
        public FpmfArchive Open(string hedFilePath)
        {
            FileInfo hedFile = new FileInfo(hedFilePath);

            if (!hedFile.Exists)
            {
                throw new FileNotFoundException($"File: {hedFilePath} not found.");
            }

            IBuffer hedBuffer = new StreamBuffer(hedFile.FullName);

            if (hedBuffer.Size < 12)
            {
                throw new Exception("File to small");
            }

            hedBuffer.SetPositionStart();
            byte[] magicBytes = hedBuffer.ReadBytes(4);
            for (int i = 0; i < 4; i++)
            {
                if (magicBytes[i] != MagicBytes[i])
                {
                    throw new Exception("Invalid File");
                }
            }

            FpmfArchive archive = new FpmfArchive();

            archive.Size = hedBuffer.ReadUInt32();
            uint unknown0 = hedBuffer.ReadUInt32();

            hedBuffer = DecryptHed(hedBuffer);
            hedBuffer.SetPositionStart();

            uint unknown1 = hedBuffer.ReadUInt32();
            uint unknown2 = hedBuffer.ReadUInt32();
            byte unknown3 = hedBuffer.ReadByte();
            byte unknown4 = hedBuffer.ReadByte();
            uint unknown5 = hedBuffer.ReadUInt32();
            uint unknown6 = hedBuffer.ReadUInt32();
            int  strLen   = hedBuffer.ReadByte();

            archive.DatPath = hedBuffer.ReadString(strLen);
            uint unknown7  = hedBuffer.ReadUInt32();
            uint unknown8  = hedBuffer.ReadUInt32();
            uint unknown9  = hedBuffer.ReadUInt32();
            uint unknown10 = hedBuffer.ReadUInt32();
            uint keyLen    = hedBuffer.ReadUInt32();

            archive.Key = hedBuffer.ReadBytes((int)keyLen);
            uint unknown11 = hedBuffer.ReadUInt32();
            uint unknown12 = hedBuffer.ReadUInt32();
            uint numFiles  = hedBuffer.ReadUInt32();

            string relativeArchiveDir = archive.DatPath
                                        .Replace("/%08x.dat", "")
                                        .Replace("./", "")
                                        .Replace('/', Path.DirectorySeparatorChar);
            string        hedPath       = hedFile.FullName.Replace(".hed", "");
            string        rootPath      = hedPath.Replace(relativeArchiveDir, "");
            DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);

            if (!rootDirectory.Exists)
            {
                throw new FileNotFoundException(
                          $"Could not determinate root path. (Rel:{relativeArchiveDir} Hed:{hedPath}  Root:{rootPath}");
            }

            _logger.Info($"Using Root:{rootPath}");

            Dictionary <uint, IBuffer> datBufferPool = new Dictionary <uint, IBuffer>();

            for (int i = 0; i < numFiles; i++)
            {
                FpmfArchiveFile archiveFile = new FpmfArchiveFile();
                strLen = hedBuffer.ReadByte();
                archiveFile.DirectoryPath = hedBuffer.ReadString(strLen);
                strLen = hedBuffer.ReadByte();
                archiveFile.FilePath  = hedBuffer.ReadString(strLen);
                archiveFile.DatNumber = hedBuffer.ReadUInt32();
                archiveFile.Offset    = hedBuffer.ReadUInt32();
                archiveFile.Size      = hedBuffer.ReadUInt32();
                uint unknown13 = hedBuffer.ReadUInt32();
                uint unknown14 = hedBuffer.ReadUInt32();

                _logger.Info($"Processing: {archiveFile.FilePath}");

                IBuffer datBuffer;
                if (datBufferPool.ContainsKey(archiveFile.DatNumber))
                {
                    datBuffer = datBufferPool[archiveFile.DatNumber];
                }
                else
                {
                    string datFileName = archive.DatPath
                                         .Replace("%08x", $"{archiveFile.DatNumber:X8}")
                                         .Replace("./", "")
                                         .Replace('/', Path.DirectorySeparatorChar);
                    string   datFilePath = Path.Combine(rootDirectory.FullName, datFileName);
                    FileInfo datFile     = new FileInfo(datFilePath);
                    if (!datFile.Exists)
                    {
                        throw new FileNotFoundException($"File: {datFilePath} not found.");
                    }

                    datBuffer = new StreamBuffer(datFile.FullName);
                    datBufferPool.Add(archiveFile.DatNumber, datBuffer);
                }

                IBuffer decrypted = DecryptDat(datBuffer, archiveFile.Offset, archiveFile.Size, archive.Key);
                archiveFile.Data = decrypted.GetAllBytes();

                archive.AddFile(archiveFile);
            }

            return(archive);
        }
예제 #8
0
        public bool Save(string directory, string fileName)
        {
            if (!Directory.Exists(directory))
            {
                Logger.Error($"Directory not found: {directory}");
                Reset();
                return(false);
            }

            string saiPath = directory + fileName + ".sai";

            if (File.Exists(saiPath))
            {
                Logger.Error($"Sai file already exists: {saiPath}");
                Reset();
                return(false);
            }

            _saiFile = new FileInfo(saiPath);

            string sacPath = directory + fileName + ".sac";

            if (File.Exists(sacPath))
            {
                Logger.Error($"Sac file already exists: {sacPath}");
                Reset();
                return(false);
            }

            _sacFile = new FileInfo(sacPath);

            if (_files.Count <= 0)
            {
                Logger.Error($"No Files add");
                Reset();
                return(false);
            }

            if (_sacBuffer == null)
            {
                Logger.Error($"No Data available");
                Reset();
                return(false);
            }

            IBuffer attributeBuffer = new StreamBuffer();
            IBuffer nameBuffer      = new StreamBuffer();
            int     entries         = 0;

            _files.Sort((a, b) => a.Id.CompareTo(b.Id));
            foreach (DataArchiveFile file in _files)
            {
                file.NameOffset = nameBuffer.Position;
                string filePath = "";
                if (file.Path.Length > 0)
                {
                    filePath += file.Path + BafDirectorySeparatorChar;
                }

                filePath += file.Name;
                nameBuffer.WriteCString(filePath);
                attributeBuffer.WriteInt32(file.Id);
                attributeBuffer.WriteInt32(file.Size);
                attributeBuffer.WriteInt32(file.Offset);
                attributeBuffer.WriteInt32(file.NameOffset);
                entries++;
            }

            byte[] dataAttribs   = attributeBuffer.GetAllBytes();
            byte[] dataFileNames = nameBuffer.GetAllBytes();

            dataAttribs   = EncryptData(Password, dataAttribs);
            dataFileNames = EncryptData(Password, dataFileNames);

            IBuffer saiBuffer = new StreamBuffer();

            saiBuffer.WriteCString(BafMagic);
            saiBuffer.WriteInt32(entries);
            saiBuffer.WriteInt32(dataFileNames.Length);
            saiBuffer.WriteInt32(0);
            saiBuffer.WriteBytes(dataAttribs);
            saiBuffer.WriteBytes(dataFileNames);

            File.WriteAllBytes(_saiFile.FullName, saiBuffer.GetAllBytes());
            File.WriteAllBytes(_sacFile.FullName, _sacBuffer.GetAllBytes());

            // decrypted
            StreamBuffer decSaiBuffer = new StreamBuffer();

            decSaiBuffer.WriteCString(BafMagic);
            decSaiBuffer.WriteInt32(entries);
            decSaiBuffer.WriteInt32(dataFileNames.Length);
            decSaiBuffer.WriteInt32(0);
            decSaiBuffer.WriteBytes(attributeBuffer.GetAllBytes());
            decSaiBuffer.WriteBytes(nameBuffer.GetAllBytes());
            File.WriteAllBytes(_saiFile.FullName + ".dec", decSaiBuffer.GetAllBytes());

            return(true);
        }
예제 #9
0
        public void Write(HdrArchive archive, string destinationPath)
        {
            Dictionary <string, List <HdrFile> > folderDictionary = new Dictionary <string, List <HdrFile> >();
            List <string> orderedKeys = new List <string>();

            foreach (HdrFile file in archive.Files)
            {
                if (archive.Header.ArchiveType == HdrArchiveType.Tro)
                {
                    string[] folderNameParts = file.HdrDirectoryPath.Split('\\');
                    string   folderName      = "";
                    for (int i = 0; i < folderNameParts.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(folderNameParts[i]))
                        {
                            folderName += folderNameParts[i] + '\\';
                            if (!folderDictionary.ContainsKey(folderName))
                            {
                                folderDictionary.Add(folderName, new List <HdrFile>());
                                orderedKeys.Add(folderName);
                            }
                        }
                    }
                }
                if (folderDictionary.ContainsKey(file.HdrDirectoryPath))
                {
                    folderDictionary[file.HdrDirectoryPath].Add(file);
                }
                else
                {
                    folderDictionary.Add(file.HdrDirectoryPath, new List <HdrFile>()
                    {
                        file
                    });
                    orderedKeys.Add(file.HdrDirectoryPath);
                }
            }
            orderedKeys.Sort((s1, s2) => string.Compare(s1, s2, StringComparison.InvariantCultureIgnoreCase));
            IBuffer buffer               = BufferProvider.Provide();
            int     totalFiles           = archive.Files.Count;
            int     currentFile          = 0;
            int     folderIndexStart     = archive.Header.IndexOffset;
            int     fileIndexStart       = folderIndexStart + folderDictionary.Count * IndexBlockSize;
            int     contentStart         = fileIndexStart + IndexBlockSize * archive.Files.Count;
            int     currentFolderIndex   = 0;
            int     currentFileIndex     = 0;
            int     currentContentLength = 0;

            foreach (string key in orderedKeys)
            {
                HdrIndex folderIndex = new HdrIndex();
                folderIndex.Name     = key;
                folderIndex.Length   = folderDictionary[key].Count;
                folderIndex.Position = folderIndexStart + currentFolderIndex;
                if (folderIndex.Length > 0)
                {
                    folderIndex.Offset = fileIndexStart + currentFileIndex;
                }
                else
                {
                    folderIndex.Offset = 0;
                }
                WriteIndex(buffer, folderIndex);
                foreach (HdrFile file in folderDictionary[key])
                {
                    HdrIndex fileIndex = new HdrIndex();
                    fileIndex.Name     = file.FileName;
                    fileIndex.Length   = file.Data.Length;
                    fileIndex.Position = fileIndexStart + currentFileIndex;
                    fileIndex.Offset   = contentStart + currentContentLength;
                    WriteIndex(buffer, fileIndex);
                    buffer.WriteBytes(file.Data, 0, fileIndex.Offset, fileIndex.Length);
                    currentFileIndex     += IndexBlockSize;
                    currentContentLength += file.Data.Length;
                    currentFile++;
                }
                currentFolderIndex += IndexBlockSize;
                OnProgressChanged(totalFiles, currentFile);
            }
            HdrHeader header = new HdrHeader();

            header.ContentOffset = contentStart;
            header.Created       = archive.Header.Created;
            header.FolderCount   = folderDictionary.Count;
            header.Format        = Hdr;
            header.Unknown0      = archive.Header.Unknown0;
            header.IndexOffset   = folderIndexStart;
            buffer.Position      = 0;
            WriteHeader(buffer, header);
            WriteFile(buffer.GetAllBytes(), destinationPath);
        }
        public void Pack(string inPath, string outPath, string archiveName, string archivePath = "")
        {
            uint   fileTime = 0x506fa78e;
            string dirPath  = archivePath;

            if (archivePath.Length > 0)
            {
                if (!dirPath.StartsWith("\\"))
                {
                    dirPath     = "\\" + dirPath;
                    archivePath = "\\" + archivePath;
                }

                if (!dirPath.EndsWith("\\"))
                {
                    dirPath     = dirPath + "\\";
                    archivePath = archivePath + "\\";
                }

                dirPath = ".\\" + archiveName + dirPath + "%08x.dat";
            }
            else
            {
                dirPath = ".\\" + archiveName + "\\" + "%08x.dat";
            }

            dirPath = dirPath.Replace("\\", "/");
            FpmfArchive archive = new FpmfArchive();

            if (inPath.EndsWith("\\"))
            {
                inPath = inPath.Substring(0, inPath.Length - 1);
            }

            uint   currentOffset   = 0;
            string baseArchivePath = inPath + "\\" + archiveName + archivePath;

            string[] inFiles = Directory.GetFiles(baseArchivePath, "*", SearchOption.AllDirectories);
            archive.numFiles   = (uint)inFiles.Length;
            archive.datPath    = dirPath;
            archive.datPathLen = dirPath.Length;

            foreach (string inFile in inFiles)
            {
                IBuffer         inReader = new StreamBuffer(inFile);
                FpmfArchiveFile datFile  = new FpmfArchiveFile();
                datFile.size      = (uint)inReader.Size;
                datFile.datNumber = 0;
                datFile.offset    = currentOffset;
                IBuffer encryptedBuff = EncryptDat(inReader, archive.key);
                datFile.data              = encryptedBuff.GetAllBytes();
                datFile.filePath          = inFile.Replace(inPath + "\\" + archiveName, ".");
                datFile.filePathSize      = (uint)datFile.filePath.Length;
                datFile.directoryPath     = ".\\" + archiveName + "\\";
                datFile.directoryPathSize = (uint)datFile.directoryPath.Length;
                datFile.unknown0          = fileTime;
                datFile.unknown1          = 0;
                archive.AddFile(datFile);
                currentOffset += datFile.size;
            }

            if (archivePath.Length > 0)
            {
                outPath = outPath + "\\" + archiveName + archivePath;
            }
            else
            {
                outPath = outPath + "\\" + archiveName + "\\";
            }

            SavePack(archive, inPath, outPath, archiveName);
        }
예제 #11
0
 public virtual void WriteBuffer(IBuffer value)
 {
     WriteBytes(value.GetAllBytes());
 }
예제 #12
0
        public FpmfArchive Open(string hedFilePath, string outPath = "")
        {
            FileInfo hedFile = new FileInfo(hedFilePath);

            if (!hedFile.Exists)
            {
                throw new FileNotFoundException($"File: {hedFilePath} not found.");
            }

            IBuffer hedBuffer = new StreamBuffer(hedFile.FullName);

            if (hedBuffer.Size < 12)
            {
                throw new Exception("File to small");
            }

            hedBuffer.SetPositionStart();
            byte[] magicBytes = hedBuffer.ReadBytes(4);
            for (int i = 0; i < 4; i++)
            {
                if (magicBytes[i] != MagicBytes[i])
                {
                    throw new Exception("Invalid File");
                }
            }

            FpmfArchive archive = new FpmfArchive();

            archive.Size = hedBuffer.ReadUInt32();
            uint unknown0 = hedBuffer.ReadUInt32();

            //BinaryWriter tmpwriter = new BinaryWriter(File.Open("C:\\Users\\kevin\\Desktop\\GameFilesSteamTest\\script_encrypted.hed", FileMode.Create));
            //tmpwriter.Write(hedBuffer.GetAllBytes());
            //tmpwriter.Flush();
            //tmpwriter.Close();

            hedBuffer = DecryptHed(hedBuffer);
            //tmpwriter = new BinaryWriter(File.Open("C:\\Users\\kevin\\Desktop\\GameFilesSteamTest\\script_unencrypted.hed", FileMode.Create));
            //tmpwriter.Write(magicBytes);
            //tmpwriter.Write(archive.Size);
            //tmpwriter.Write(unknown0);
            //tmpwriter.Write(hedBuffer.GetAllBytes());
            //tmpwriter.Flush();
            //tmpwriter.Close();

            hedBuffer.SetPositionStart();
            uint unknown1 = hedBuffer.ReadUInt32();
            uint unknown2 = hedBuffer.ReadUInt32();
            byte unknown3 = hedBuffer.ReadByte();
            byte unknown4 = hedBuffer.ReadByte();
            uint unknown5 = hedBuffer.ReadUInt32();
            uint unknown6 = hedBuffer.ReadUInt32();
            int  strLen   = hedBuffer.ReadByte();

            archive.DatPath = hedBuffer.ReadString(strLen);
            uint unknown7  = hedBuffer.ReadUInt32();
            uint unknown8  = hedBuffer.ReadUInt32();
            uint unknown9  = hedBuffer.ReadUInt32();
            uint unknown10 = hedBuffer.ReadUInt32();
            uint keyLen    = hedBuffer.ReadUInt32();

            archive.Key = hedBuffer.ReadBytes((int)keyLen);
            uint unknown11 = hedBuffer.ReadUInt32();
            uint unknown12 = hedBuffer.ReadUInt32();
            uint numFiles  = hedBuffer.ReadUInt32();

            //headerBuff.SetPositionStart();
            string relativeArchiveDir = archive.DatPath
                                        .Replace("/%08x.dat", "")
                                        .Replace("./", "")
                                        .Replace('/', Path.DirectorySeparatorChar);
            string        hedPath       = hedFile.FullName.Replace(".hed", "");
            string        hedName       = hedPath.Substring(hedPath.LastIndexOf("\\") + 1);
            string        rootPath      = hedPath.Replace(relativeArchiveDir, "");
            DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);

            if (!rootDirectory.Exists)
            {
                throw new FileNotFoundException(
                          $"Could not determinate root path. (Rel:{relativeArchiveDir} Hed:{hedPath}  Root:{rootPath}");
            }

            Logger.Info($"Using Root:{rootPath}");
            Dictionary <uint, IBuffer> datBufferPool = new Dictionary <uint, IBuffer>();

            for (int i = 0; i < numFiles; i++)
            {
                FpmfArchiveFile archiveFile = new FpmfArchiveFile();
                strLen = hedBuffer.ReadByte();
                archiveFile.DirectoryPath = hedBuffer.ReadString(strLen);
                strLen = hedBuffer.ReadByte();
                archiveFile.FilePath  = hedBuffer.ReadString(strLen);
                archiveFile.DatNumber = hedBuffer.ReadUInt32();
                archiveFile.Offset    = hedBuffer.ReadUInt32();
                archiveFile.Size      = hedBuffer.ReadUInt32();
                uint unknown13 = hedBuffer.ReadUInt32();
                uint unknown14 = hedBuffer.ReadUInt32();

                uint unknown15 = addFileName(archiveFile.FilePath);
                uint unknown16 = addFileName(archiveFile.DirectoryPath);
                Logger.Info($"Processing: {archiveFile.FilePath}");

                IBuffer datBuffer;
                if (datBufferPool.ContainsKey(archiveFile.DatNumber))
                {
                    datBuffer = datBufferPool[archiveFile.DatNumber];
                }
                else
                {
                    string datFileName = archive.DatPath
                                         .Replace("%08x", $"{archiveFile.DatNumber:X8}")
                                         .Replace("./", "")
                                         .Replace('/', Path.DirectorySeparatorChar);
                    string   datFilePath = Path.Combine(rootDirectory.FullName, datFileName);
                    FileInfo datFile     = new FileInfo(datFilePath);
                    if (!datFile.Exists)
                    {
                        throw new FileNotFoundException($"File: {datFilePath} not found.");
                    }

                    datBuffer = new StreamBuffer(datFile.FullName);
                    datBufferPool.Add(archiveFile.DatNumber, datBuffer);
                }

                IBuffer decrypted = DecryptDat(datBuffer, archiveFile.Offset, archiveFile.Size, archive.Key);
                if (archiveFile.FilePath.Contains("\\item.csv"))
                {
                    decrypted = OpenWoItm(decrypted);
                }

                archiveFile.Data = decrypted.GetAllBytes();

                archive.AddFile(archiveFile);
            }

            return(archive);
        }