Пример #1
0
        public bool Extract(DataArchiveFile file, string destinationDirectory)
        {
            if (!_loaded)
            {
                Logger.Error($"Archive is not loaded");
                return(false);
            }

            if (!Directory.Exists(destinationDirectory))
            {
                Logger.Error($"Directory not found: {destinationDirectory}");
                return(false);
            }

            DirectoryInfo destination = new DirectoryInfo(destinationDirectory);

            byte[] fileData = _sacBuffer.GetBytes(file.Offset, file.Size);
            string dir      = Path.Combine(destination.FullName, file.Path);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            string path = Path.Combine(dir, file.Name);

            File.WriteAllBytes(path, fileData);

            Logger.Info($"Extract: {file.Id} {file.Path}{file.Name}");

            return(true);
        }
Пример #2
0
        public bool Load(string path)
        {
            Reset();

            string saiPath = path + ".sai";

            if (!File.Exists(saiPath))
            {
                Logger.Error($".sai file not found: {saiPath}");
                Reset();
                return(false);
            }

            _saiFile = new FileInfo(saiPath);

            string sacPath = path + ".sac";

            if (!File.Exists(sacPath))
            {
                Logger.Error($".sac file not found: {sacPath}");
                Reset();
                return(false);
            }

            _sacFile = new FileInfo(sacPath);

            byte[]  saiData   = File.ReadAllBytes(_saiFile.FullName);
            IBuffer saiBuffer = new StreamBuffer(saiData);

            saiBuffer.SetPositionStart();

            string magic = saiBuffer.ReadCString();

            if (BafMagic != magic)
            {
                Logger.Error($"Invalid Magic File Bytes: {magic}");
                Reset();
                return(false);
            }

            int entries      = saiBuffer.ReadInt32();
            int fileNameSize = saiBuffer.ReadInt32();
            int unk1         = saiBuffer.ReadInt32();

            byte[] dataAttribs = saiBuffer.ReadBytes(entries * EntrySize);
            dataAttribs = DecryptData(Password, dataAttribs);
            byte[] dataFileNames = saiBuffer.ReadBytes(fileNameSize);
            dataFileNames = DecryptData(Password, dataFileNames);

            IBuffer nameBuffer      = new StreamBuffer(dataFileNames);
            IBuffer attributeBuffer = new StreamBuffer(dataAttribs);

            attributeBuffer.SetPositionStart();

            for (int i = 0; i < entries; i++)
            {
                DataArchiveFile item = new DataArchiveFile();
                item.Id         = attributeBuffer.ReadInt32();
                item.Size       = attributeBuffer.ReadInt32();
                item.Offset     = attributeBuffer.ReadInt32();
                item.NameOffset = attributeBuffer.ReadInt32();

                nameBuffer.Position = item.NameOffset;
                string filePath = nameBuffer.ReadCString();
                filePath = filePath.Replace(BafDirectorySeparatorChar, Path.DirectorySeparatorChar);
                string fileName      = Path.GetFileName(filePath);
                string directoryName = Path.GetDirectoryName(filePath);

                item.Name = fileName;
                item.Path = directoryName;

                _files.Add(item);
            }

            byte[] sacData = File.ReadAllBytes(_sacFile.FullName);
            _sacBuffer = new StreamBuffer(sacData);
            _sacBuffer.SetPositionStart();
            _loaded = true;

            // decrypted
            StreamBuffer decSaiBuffer = new StreamBuffer();

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

            return(true);
        }
Пример #3
0
        public bool AddFile(string rootDirectory, string filePath)
        {
            if (_sacBuffer == null)
            {
                _sacBuffer = new StreamBuffer();
            }

            FileInfo fileInfo = new FileInfo(filePath);

            if (!fileInfo.Exists)
            {
                return(false);
            }

            byte[] fileData = File.ReadAllBytes(fileInfo.FullName);
            int    offset   = _sacBuffer.Position;

            _sacBuffer.WriteBytes(fileData);

            string bafFilePath   = filePath.Replace(rootDirectory, "");
            string fileName      = Path.GetFileName(bafFilePath);
            string directoryName = Path.GetDirectoryName(bafFilePath);

            if (directoryName == null)
            {
                directoryName = "";
                bafFilePath   = fileName;
            }
            else
            {
                directoryName = directoryName.Replace(Path.DirectorySeparatorChar, BafDirectorySeparatorChar);
                if (directoryName.StartsWith(BafDirectorySeparatorChar))
                {
                    directoryName = directoryName.Substring(1);
                }

                if (directoryName == string.Empty)
                {
                    bafFilePath = fileName;
                }
                else
                {
                    bafFilePath = directoryName + BafDirectorySeparatorChar + fileName;
                }
            }

            DataArchiveFile file = new DataArchiveFile();

            file.Id         = GetPathIndex(bafFilePath);
            file.Size       = fileData.Length;
            file.Name       = fileName;
            file.Path       = directoryName;
            file.Offset     = offset;
            file.NameOffset = NoNameOffset;

            _files.Add(file);

            Logger.Info($"Add: {file.Id} {file.Path}{file.Name}");

            return(true);
        }