Пример #1
0
        protected static TempHeader GetHeader(Bbsa bbsa, string inputFilesFolderPath, string prefix, FileStream[] streams, out uint bbs4Count)
        {
            uint       bbs4Sec    = 0;
            TempHeader tempHeader = new TempHeader(); //Used to count sectors in containers

            for (int i = 0; i < 5; i++)               //Foreach BBS{i} folder/container
            {
                #region Get Container Sector/Index
                uint Sector = 0;
                switch (i)
                {
                case 0:
                    Sector = 125;
                    break;

                default:
                    Sector = 1;
                    break;
                }
                #endregion//Used on Write

                string containerPath = Path.Combine(inputFilesFolderPath, $"{prefix}{i}");

                foreach (var file in bbsa.Files.Where(x => x.ArchiveIndex == i))
                {
                    var    name     = file.CalculateNameWithExtension(x => streams[x]);
                    string filePath = Path.Combine(containerPath, name);

                    var fileinfo = new FileInfo(filePath);
                    Sector += (uint)fileinfo.Length / 0x800;
                }
                bbs4Sec = Sector;
                #region Get Header Offsets
                switch (i)
                {
                case 0:
                    tempHeader.Archive1Sector = (uint)(Sector - 125);
                    //Console.WriteLine($"Arch1: {tempHeader.Archive1Sector}");
                    break;

                case 1:
                    tempHeader.Archive2Sector = (uint)(Sector + tempHeader.Archive1Sector - 2);
                    //Console.WriteLine($"Arch2: {tempHeader.Archive2Sector}");
                    break;

                case 2:
                    tempHeader.Archive3Sector = (uint)(Sector + tempHeader.Archive2Sector - 3);
                    //Console.WriteLine($"Arch3: {tempHeader.Archive3Sector}");
                    break;

                case 3:
                    tempHeader.Archive4Sector = (uint)(Sector + tempHeader.Archive3Sector - 2);
                    //Console.WriteLine($"Arch4: {tempHeader.Archive4Sector}");
                    break;
                }
                #endregion
            }
            bbs4Count = bbs4Sec;
            return(tempHeader);
        }
Пример #2
0
 internal Entry(
     Bbsa bbsa,
     int offset,
     int length,
     string fileName,
     string folderName,
     uint fileHash,
     uint folderHash)
 {
     bbsaHeader      = bbsa._header;
     this.offset     = offset;
     this.length     = length;
     this.fileName   = fileName;
     this.folderName = folderName;
     FileHash        = fileHash;
     FolderHash      = folderHash;
 }
Пример #3
0
 internal Entry(
     Bbsa bbsa,
     int offset,
     int length,
     string fileName,
     string ext,
     string folderName,
     uint fileHash,
     uint folderHash,
     uint locationoffs,
     int archIndex)
 {
     bbsaHeader      = bbsa._header;
     this.offset     = offset;
     this.length     = length;
     this.fileName   = fileName;
     this.ext        = ext;
     this.folderName = folderName;
     FileHash        = fileHash;
     FolderHash      = folderHash;
     Location        = locationoffs;
     ArchiveIndex    = archIndex;
 }
Пример #4
0
        public static void RepackfromFolder(string inputBBSAFolderPath, string inputFilesFolderPath,
                                            string outputFolderPath, string ArchivePrefix = "BBS")
        {
            var prefix = ArchivePrefix ?? "BBS";

            var bbsaFileNames = Enumerable.Range(0, 5)
                                .Select(x => Path.Combine(inputBBSAFolderPath, $"{prefix}{x}.DAT"));

            var OUTbbsaFileNames = Enumerable.Range(0, 5)
                                   .Select(x => Path.Combine(outputFolderPath, $"{prefix}{x}.DAT"));


            var streams = bbsaFileNames
                          .Select(x => File.OpenRead(x))
                          .ToArray();

            var OUTstreams = OUTbbsaFileNames
                             .Select(x => new FileStream(x, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                             .ToArray();

            Bbsa bbsa = Bbs.Bbsa.Read(streams[0]);

            byte[] Header = new byte[bbsa._header.Archive0Sector * 0x800];
            streams[0].Position = 0;
            streams[0].Read(Header, 0, (int)(bbsa._header.Archive0Sector * 0x800));
            WriteBytes(Header, OUTstreams[0], 0);

            var tempHeader = GetHeader(bbsa, inputFilesFolderPath, prefix, streams, out uint bbs4Count);

            #region Header Sectors Counts
            WriteUint(tempHeader.Archive4Sector + bbs4Count - 3, OUTstreams[0], 0x1c);
            WriteUint(tempHeader.Archive1Sector, OUTstreams[0], 0x20);
            WriteUint(tempHeader.Archive2Sector, OUTstreams[0], 0x24);
            WriteUint(tempHeader.Archive3Sector, OUTstreams[0], 0x28);
            WriteUint(tempHeader.Archive4Sector, OUTstreams[0], 0x2c);
            #endregion

            for (int i = 0; i < 5; i++)//Foreach BBS{i} folder/container
            {
                //Write container name+index+extension
                if (i > 0)
                {
                    byte[] writeName = System.Text.Encoding.Default.GetBytes($"{prefix.ToLower()}{i}.dat");
                    WriteBytes(writeName, OUTstreams[i], 0);
                    WriteBytes(new byte[] { (byte)bbsa._header.Version }, OUTstreams[i], 0x10);//Version IMPORTANT!!
                }

                #region Get Container Sector/Index
                uint Sector = 0;
                switch (i)
                {
                case 0:
                    Sector = (uint)bbsa._header.Archive0Sector;
                    break;

                default:
                    Sector = 1;
                    break;
                }
                #endregion//Used on Write

                string containerPath = Path.Combine(inputFilesFolderPath, $"{prefix}{i}");

                foreach (var file in bbsa.Files.Where(x => x.ArchiveIndex == i).OrderBy(x => x.offset))
                {
                    var    name     = file.CalculateNameWithExtension(x => streams[x]);
                    string filePath = Path.Combine(containerPath, name);

                    //Verify file existence
                    if (!File.Exists(filePath))
                    {
                        Console.WriteLine("File not found:");
                        Console.WriteLine(filePath);
                        return;
                    }

                    byte[] FileX = File.ReadAllBytes(filePath);

                    //Verify file Sector Padding
                    if (FileX.Length % 0x800 != 0)
                    {
                        var FileXPadd = new List <byte>();
                        FileXPadd.AddRange(FileX);
                        while (FileXPadd.Count % 0x800 != 0)
                        {
                            FileXPadd.Add(0);
                        }
                        FileX = FileXPadd.ToArray();
                    }

                    //Get Pointer
                    uint FileSize   = GetFileSectorSize((uint)FileX.Length);
                    uint FileOffset = (uint)GetFileOffset(tempHeader, (int)Sector, i);
                    uint Info       = (FileOffset << 12) + (FileSize >= 0xFFF ? 0xFFF : FileSize);

                    //Write Pointer
                    WriteUint(Info, OUTstreams[0], file.Location + 4);

                    //Write Files
                    OUTstreams[i].Position = Sector * 0x800;
                    foreach (var b in FileX)
                    {
                        OUTstreams[i].WriteByte(b);
                    }

                    //Info Out
                    Console.WriteLine($"Nome: {name}\n" +
                                      $"Index: {prefix}{i}");

                    //Add Size written
                    Sector += FileSize;
                    FileX   = null;
                }
            }

            //Close and flush data(write remaining and close)
            OUTstreams[0].Close();
            OUTstreams[1].Close();
            OUTstreams[2].Close();
            OUTstreams[3].Close();
            OUTstreams[4].Close();
        }