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); }
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; }
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; }
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(); }