internal static R_MythicPackageHeader Create(List <R_MythicPackageBlock> blocks) { /* * [1] - General Format Header (sizeof: 40bytes ) * Byte(23) 0x0 - 0x17 -> Containing general file headers (Version etc.) * DWORD? 0x18 -> Amount of contained files/indexes * byte(12) -> Unknown gibberish * * DWORD MYTH -> Start of every Myth package * DWORD -> Version * DWORD 0xFD -> Misc ( 0xFD23EC43 ) * DWORD -> Header Size * DWORD 0x00 -> Empty bytes * DWORD -> Block size * DWORD -> File count */ R_MythicPackageHeader package = new R_MythicPackageHeader(); int counted = 0; //We count all files number. for (int i = 0; i < blocks.Count; i++) { counted += blocks[i].FileCount; } //Whole Size must be 40bytes package.Start[0] = (BitConverter.GetBytes('M'))[0]; package.Start[1] = (BitConverter.GetBytes('Y'))[0]; package.Start[2] = (BitConverter.GetBytes('P'))[0]; package.Start[3] = (BitConverter.GetBytes(0))[0]; package.Version = 4; //Version package.Misc = 0xFD23EC43; //Misc ( 0xFD23EC43 ) package.HeaderSize = 40; //Size ( fixed! ) package.Zeros = 0; //DWORD empty bytes package.BlockSize = 100; //Block size package.FileCount = counted; //Number of files package.Blocks = blocks; //Should copy all blocks into new list. package.Fill = (package.HeaderSize - 28); return(package); }
internal static R_MythicPackageHeader Create( List<R_MythicPackageBlock> blocks ) { /* * [1] - General Format Header (sizeof: 40bytes ) * Byte(23) 0x0 - 0x17 -> Containing general file headers (Version etc.) * DWORD? 0x18 -> Amount of contained files/indexes * byte(12) -> Unknown gibberish * * DWORD MYTH -> Start of every Myth package * DWORD -> Version * DWORD 0xFD -> Misc ( 0xFD23EC43 ) * DWORD -> Header Size * DWORD 0x00 -> Empty bytes * DWORD -> Block size * DWORD -> File count */ R_MythicPackageHeader package = new R_MythicPackageHeader(); int counted = 0; //We count all files number. for (int i = 0; i < blocks.Count; i++) { counted += blocks[i].FileCount; } //Whole Size must be 40bytes package.Start[0] = (BitConverter.GetBytes('M'))[0]; package.Start[1] = (BitConverter.GetBytes('Y'))[0]; package.Start[2] = (BitConverter.GetBytes('P'))[0]; package.Start[3] = (BitConverter.GetBytes(0))[0]; package.Version = 4; //Version package.Misc = 0xFD23EC43; //Misc ( 0xFD23EC43 ) package.HeaderSize = 40; //Size ( fixed! ) package.Zeros = 0; //DWORD empty bytes package.BlockSize = 100; //Block size package.FileCount = counted; //Number of files package.Blocks = blocks; //Should copy all blocks into new list. package.Fill = (package.HeaderSize - 28); return package; }
// private long B_offset(R_MythicPackageHeader towrite, int a, int j) { long offsettodatablock = towrite.HeaderSize; int limit = 0; for (int i = 0; i < a+1; i++) { //BlockOffset offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].FileCount)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].NextBlock)).Length; for (int k = 0; k < 100; k++) //for (int k = 0; k < (towrite.Blocks[i]).FileCount; k++) { //Index Offset offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlockOffset)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].HeadLength)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].CompressedSize)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DecompressedSize)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].FileHash)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].CRC)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].Flag)).Length; } if (i < a) limit = (towrite.Blocks[i]).FileCount; else if (i == a) { limit = j; if (j == 0) return offsettodatablock; } for (int k = 0; k < limit; k++) { //DataBlock if (towrite.Blocks[i].Files[k].DataBlock != null) { //calculate offset to compressed data byte[] offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.Flag)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.DataOffset)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.DateTime)).Length; offsettodatablock += (towrite.Blocks[i].Files[k].DataBlock.Data).Length; } } } return offsettodatablock; }
//Calculate Offsets v2.0 private long C_offset(bool nextblock, R_MythicPackageHeader towrite, int i) { long offsettodatablock = 0; //BlockOffset offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].FileCount)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].NextBlock)).Length; for (int j = 0; j < (towrite.Blocks[i]).FileCount; j++) { //Index Offset offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlockOffset)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].HeadLength)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].CompressedSize)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DecompressedSize)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].FileHash)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].CRC)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].Flag)).Length; //DataBlock if (towrite.Blocks[i].Files[j].DataBlock != null && nextblock) { //calculate offset to compressed data byte[] offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.Flag)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.DataOffset)).Length; offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.DateTime)).Length; offsettodatablock += (towrite.Blocks[i].Files[j].DataBlock.Data).Length; } } return offsettodatablock; }
//Third write method RIGHT SIZE RIGHT POSITION private void write3(R_MythicPackageHeader towrite, string name) { using (FileStream uop = new FileStream(name, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { //Declarations List<List<long>> offset = new List<List<long>>(); //First, we calculate space in stream using (BinaryWriter writer = new BinaryWriter(uop)) { //Write first Header, then blocks. writer.Write(towrite.Start); writer.Write(towrite.Version); writer.Write(towrite.Misc); writer.Write(towrite.HeaderSize); writer.Write(towrite.Zeros); writer.Write(towrite.BlockSize); writer.Write(towrite.FileCount); byte zero = 0; for (int i = 0; i < towrite.Fill; i++) { writer.Write(zero); } // Header is done, let's write Blocks long nextblockoffset = towrite.HeaderSize; for (int i = 0; i < towrite.Blocks.Count; i++) { //Need to set nextblockoffset nextblockoffset += C_offset(true, towrite, i); if (i == towrite.Blocks.Count - 1) towrite.Blocks[i].NextBlock = 0; else towrite.Blocks[i].NextBlock = nextblockoffset; // writer.Write(towrite.Blocks[i].FileCount); //Ok writer.Write(towrite.Blocks[i].NextBlock); //Ok for (int j = 0; j < towrite.Blocks[i].Files.Count; j++) { //We write INDEXES //need to set datablockoffset if (towrite.Blocks[i].Files[j].DataBlock != null) { towrite.Blocks[i].Files[j].DataBlockOffset = B_offset(towrite, i, j); } else towrite.Blocks[i].Files[j].DataBlockOffset = 0; // writer.Write(towrite.Blocks[i].Files[j].DataBlockOffset); //ToDo writer.Write(towrite.Blocks[i].Files[j].HeadLength); //Fixed? writer.Write(towrite.Blocks[i].Files[j].CompressedSize); //Ok writer.Write(towrite.Blocks[i].Files[j].DecompressedSize); //Ok writer.Write(towrite.Blocks[i].Files[j].FileHash); //Wrong writer.Write(towrite.Blocks[i].Files[j].CRC); //Wrong writer.Write(towrite.Blocks[i].Files[j].Flag); //Ok // K_Setvalue(1); } for (int j = 0; j < towrite.Blocks[i].Files.Count; j++) { //We write DATA if (towrite.Blocks[i].Files[j].DataBlock != null) { writer.Write(towrite.Blocks[i].Files[j].DataBlock.Flag); //Fixed writer.Write(towrite.Blocks[i].Files[j].DataBlock.DataOffset); //Fixed writer.Write(towrite.Blocks[i].Files[j].DataBlock.DateTime); //Ok writer.Write(towrite.Blocks[i].Files[j].DataBlock.Data); //Ok } K_Setvalue(1); } } } } }
//K end #region worker private void Worker_DoWork(object sender, DoWorkEventArgs e) { if (e.Argument is string[]) { List<R_MythicPackageIndex> toblock = new List<R_MythicPackageIndex>(); string[] files = (string[])e.Argument; bool error = false; for (int k = 0; (k < files.Length) && !error; k++) //Should read ALL files in folder { toblock.Add(R_MythicPackageIndex.Pack(files[k], ref error)); K_Setvalue(1); } if (error) e.Result = "An Error was encountered while working. See MessageBox"; else e.Result = toblock; } if (e.Argument is List<R_MythicPackageIndex>) { List<R_MythicPackageIndex> indexes= (List<R_MythicPackageIndex>)e.Argument; //Now we should create Blocks of 100 elements List<R_MythicPackageBlock> blocks = new List<R_MythicPackageBlock>(); int i = 0; for (int k = 0; k < indexes.Count; ) { blocks.Add(R_MythicPackageBlock.Pack(indexes, k, ref i));//Creates block struct k = i; K_Setvalue(1); } //Now we have all blocks, let's do the header. R_MythicPackageHeader package = new R_MythicPackageHeader(); package = R_MythicPackageHeader.Create(blocks); e.Result = package; } else if (e.Argument is R_MythicPackageHeader) { R_MythicPackageHeader towrite = (R_MythicPackageHeader)e.Argument; //We should now write down .uop format using package string name = ((Path.GetFileName(FolderName)).Insert((Path.GetFileName(FolderName)).Length,".uop")); //Where to write uop //Choose writing method //write1(towrite, name); //write2(towrite, name); write3(towrite, name); e.Result = true; } }