public static void ReadGOG(string inputPath, string outputPath, bool isRawExtract = false, bool outputInfo = false) { if (!File.Exists(inputPath)) { return; } using (BinaryReader reader = new BinaryReader(File.Open(inputPath, FileMode.Open))) { while (reader.BaseStream.Length - reader.BaseStream.Position >= 4) { var hdrStart = reader.ReadUInt32(); reader.BaseStream.Seek(-4, SeekOrigin.Current); //peek the current 4 bytes if (hdrStart == Magic) { Console.WriteLine("Found a CTPK in GOG"); var data = new byte[reader.BaseStream.Length - reader.BaseStream.Position]; long resetTo = reader.BaseStream.Position + 1; reader.Read(data, 0, data.Length); reader.BaseStream.Seek(resetTo, SeekOrigin.Begin); Ctpk it = Read(data, inputPath, outputPath, isRawExtract, outputInfo); Console.WriteLine("Total CTPK bytes: {0}", it.Size); } else { reader.ReadByte(); //yup } } } }
public static Ctpk Create(string folder) { Ctpk file = new Ctpk(); // Look for all xml definition files in the folder var files = Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories); foreach (var xmlFilename in files) { CTPKEntry entry = CTPKEntry.FromFile(xmlFilename, folder); file._entries.Add(entry); } for (int i = 0; i < file._entries.Count; i++) { file._entries[i].BitmapSizeOffset = (uint)((file._entries.Count + 1)*8 + (i*8)); } var outputFilename = folder + ".ctpk"; using (BinaryWriter writer = new BinaryWriter(File.Open(outputFilename, FileMode.Create))) { file.Write(writer); } Console.WriteLine("Finished! Saved to {0}", outputFilename); return file; }
public static Ctpk Create(string inputPath, string outputPath) { if (!Directory.Exists(inputPath)) { return(null); } Ctpk file = new Ctpk(); // Look for all xml definition files in the folder var files = Directory.GetFiles(inputPath, "*.xml", SearchOption.AllDirectories); foreach (var xmlFilename in files) { CTPKEntry entry = CTPKEntry.FromFile(xmlFilename, inputPath); file._entries.Add(entry); } for (int i = 0; i < file._entries.Count; i++) { file._entries[i].BitmapSizeOffset = (uint)((file._entries.Count + 1) * 8 + i); } using (BinaryWriter writer = new BinaryWriter(File.Open(outputPath, FileMode.Create))) { file.Write(writer); } Console.WriteLine("Finished! Saved to {0}", outputPath); return(file); }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("usage: {0} input.ctpk/input_folder", AppDomain.CurrentDomain.FriendlyName); Environment.Exit(0); } if (Directory.Exists(args[0])) { Ctpk.Create(args[0]); } else if (File.Exists(args[0])) { Ctpk.Read(args[0]); } else { Console.WriteLine("Could not find path or file '{0}'", args[0]); } }
public static Ctpk Read(byte[] data, string filename) { Ctpk file = new Ctpk(); using(MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid CTPK file."); } Console.WriteLine(); file.Version = reader.ReadUInt16(); Console.WriteLine("CTPK Version \t\t{0}\t:{0:X}", file.Version); file.NumberOfTextures = reader.ReadUInt16(); Console.WriteLine("Number of textures \t{0}\t:{0:X}", file.NumberOfTextures); file.TextureSectionOffset = reader.ReadUInt32(); Console.WriteLine("Texture section offset \t{0}\t:{0:X}", file.TextureSectionOffset); file.TextureSectionSize = reader.ReadUInt32(); Console.WriteLine("Texture section size \t{0}\t:{0:X}", file.TextureSectionSize); file.HashSectionOffset = reader.ReadUInt32(); Console.WriteLine("Hash section offset \t{0}\t:{0:X}", file.HashSectionOffset); file.TextureInfoSection = reader.ReadUInt32(); Console.WriteLine("Texture \t\t{0}\t:{0:X}", file.TextureInfoSection); // Section 1 + 3 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); Console.WriteLine(); Console.WriteLine("Extracting texture {0}...", i + 1); CTPKEntry entry = CTPKEntry.Read(reader); file._entries.Add(entry); } // Section 2 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info = reader.ReadUInt32(); } // Section 4 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].FilenameHash = reader.ReadUInt32(); } // Section 5 reader.BaseStream.Seek(file.TextureInfoSection, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info2 = reader.ReadUInt32(); } // Section 6 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(file.TextureSectionOffset + file._entries[i].TextureOffset, SeekOrigin.Begin); file._entries[i].TextureRawData = new byte[file._entries[i].TextureSize]; reader.Read(file._entries[i].TextureRawData, 0, (int)file._entries[i].TextureSize); } string basePath = Path.GetDirectoryName(filename); string baseFilename = Path.GetFileNameWithoutExtension(filename); if (!String.IsNullOrWhiteSpace(basePath)) { baseFilename = Path.Combine(basePath, baseFilename); } for (int i = 0; i < file.NumberOfTextures; i++) { Console.WriteLine("Converting {0}...", file._entries[i].InternalFilePath); file._entries[i].ToFile(baseFilename); } } return file; }
public static Ctpk Read(byte[] data, string inputPath, string outputPath, bool isRawExtract = false) { Ctpk file = new Ctpk(); using (MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid CTPK file."); } file.Version = reader.ReadUInt16(); file.NumberOfTextures = reader.ReadUInt16(); file.TextureSectionOffset = reader.ReadUInt32(); file.TextureSectionSize = reader.ReadUInt32(); file.HashSectionOffset = reader.ReadUInt32(); file.TextureInfoSection = reader.ReadUInt32(); // Section 1 + 3 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); CTPKEntry entry = CTPKEntry.Read(reader); entry.FileIndexA = file._entries.Count; file._entries.Add(entry); } // Section 2 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info = reader.ReadUInt32(); } // Section 4 reader.BaseStream.Seek(file.HashSectionOffset, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].FilenameHash = reader.ReadUInt32(); int idx = reader.ReadInt32(); if (idx < file._entries.Count) { file._entries[idx].FileIndexB = i; } else { Console.WriteLine("ERROR(?): Found hash entry without a matching file entry"); } } // Section 5 reader.BaseStream.Seek(file.TextureInfoSection, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info2 = reader.ReadUInt32(); } // Section 6 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(file.TextureSectionOffset + file._entries[i].TextureOffset, SeekOrigin.Begin); file._entries[i].TextureRawData = new byte[file._entries[i].TextureSize]; reader.Read(file._entries[i].TextureRawData, 0, (int)file._entries[i].TextureSize); } for (int i = 0; i < file.NumberOfTextures; i++) { Console.WriteLine("Converting {0}...", file._entries[i].InternalFilePath); file._entries[i].ToFile(outputPath, isRawExtract); } } return(file); }
public static Ctpk Create(string inputPath, string outputPath, string _patchPath) { if (!Directory.Exists(inputPath)) { return(null); } string _goodInPath = makePathGood(inputPath); string _goodPatchPath = _patchPath != null?makePathGood(_patchPath) : null; Ctpk file = new Ctpk(); // Look for all xml definition files in the folder string[] _xmlFiles = Directory.GetFiles(_goodInPath, "*.xml", SearchOption.AllDirectories); string[] _xmlOverrides = new string[_xmlFiles.Length]; string[] _pngFiles = new string[_xmlFiles.Length]; Array.Clear(_pngFiles, 0, _pngFiles.Length); Array.Clear(_xmlOverrides, 0, _xmlOverrides.Length); if (_goodPatchPath != null) { string[] patchFiles = Directory.GetFiles(_goodPatchPath, "*", SearchOption.AllDirectories); // Merge patchFiles into files for (int j = 0; j < patchFiles.Length; ++j) { string _choppedName = Path.GetFileNameWithoutExtension(patchFiles[j]); int i; for (i = 0; i < _xmlFiles.Length; ++i) { if (Path.GetFileNameWithoutExtension(_xmlFiles[i]) == _choppedName) { if (Path.GetExtension(patchFiles[j]) == ".xml") { _xmlOverrides[i] = patchFiles[j]; } else { _pngFiles[i] = patchFiles[j]; } break; } } if (i == _xmlFiles.Length) { Console.WriteLine("Base path is " + _goodInPath); for (i = 0; i < _xmlFiles.Length; ++i) { Console.WriteLine(String.Format("{0} ({1})", _xmlFiles[i], Path.GetFileNameWithoutExtension(_xmlFiles[i]))); } throw new Exception(String.Format("Could not find replacement for {0} ({3}) from {1} to put in {2}", patchFiles[j], _goodPatchPath, _goodInPath, _choppedName)); } } } for (int i = 0; i < _xmlFiles.Length; ++i) { CTPKEntry entry; if (_xmlOverrides[i] != null) { entry = CTPKEntry.FromFile(_xmlOverrides[i], _goodInPath, _pngFiles[i]); if (entry == null) { entry = CTPKEntry.FromFile(_xmlFiles[i], _goodInPath, _pngFiles[i]); } } else { entry = CTPKEntry.FromFile(_xmlFiles[i], _goodInPath, _pngFiles[i]); } if (entry == null) { throw new Exception("failed to create ctpkentry"); } file._entries.Add(entry); } for (int i = 0; i < file._entries.Count; i++) { file._entries[i].BitmapSizeOffset = (uint)((file._entries.Count + 1) * 8 + i); } using (BinaryWriter writer = new BinaryWriter(File.Open(outputPath, FileMode.Create))) { file.Write(writer); } Console.WriteLine("Finished! Saved to {0}", outputPath); return(file); }
static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("need args"); return(1); } string patchPath = null; for (int i = 0; i < args.Length; i += 2) { switch (args[i][0]) { case 'x': InputFile = args[i + 1]; break; case 'r': InputFileRaw = args[i + 1]; break; case 'c': InputFolder = args[i + 1]; break; case 'o': OutputPath = args[i + 1]; break; case 'p': patchPath = args[i + 1]; break; default: Console.WriteLine("Bad argument 0 " + args[i][0]); break; } } string inputPath = null, outputPath = null; bool isExtract = false, isRawExtract = false, isCreate = false; if (!String.IsNullOrWhiteSpace(InputFileRaw)) { inputPath = InputFileRaw; isRawExtract = true; isExtract = true; } else if (!String.IsNullOrWhiteSpace(InputFile)) { inputPath = InputFile; isExtract = true; } else if (!String.IsNullOrWhiteSpace(InputFolder)) { inputPath = InputFolder; isCreate = true; } if (!String.IsNullOrWhiteSpace(OutputPath)) { outputPath = OutputPath; } else { if (isCreate) { outputPath = inputPath + ".ctpk"; } else { string basePath = Path.GetDirectoryName(inputPath); string baseFilename = Path.GetFileNameWithoutExtension(inputPath); if (!String.IsNullOrWhiteSpace(basePath)) { baseFilename = Path.Combine(basePath, baseFilename); } outputPath = baseFilename; } } if (isCreate) { Ctpk.Create(inputPath, outputPath, patchPath); } else if (isExtract) { Ctpk.Read(inputPath, outputPath, isRawExtract); } else { Console.WriteLine("Could not find path or file '{0}'", args[0]); } return(0); }
static void Main(string[] args) { var config = new Config(); var settings = new CommandLine.ParserSettings(true, true, false, Console.Error); var parser = new CommandLine.Parser(settings); string inputPath = null, outputPath = null; bool isExtract = false, isRawExtract = false, isCreate = false; if (args.Length == 0) { // Don't try to parse zero arguments or else it results in an exception Console.WriteLine(config.GetUsage()); Environment.Exit(-1); } if (parser.ParseArguments(args, config)) { if (!String.IsNullOrWhiteSpace(config.InputFileRaw)) { inputPath = config.InputFileRaw; isRawExtract = true; isExtract = true; } else if (!String.IsNullOrWhiteSpace(config.InputFile)) { inputPath = config.InputFile; isExtract = true; } else if (!String.IsNullOrWhiteSpace(config.InputFolder)) { inputPath = config.InputFolder; isCreate = true; } if (!String.IsNullOrWhiteSpace(config.OutputPath)) { outputPath = config.OutputPath; } else { if (isCreate) { outputPath = inputPath + ".ctpk"; } else { string basePath = Path.GetDirectoryName(inputPath); string baseFilename = Path.GetFileNameWithoutExtension(inputPath); if (!String.IsNullOrWhiteSpace(basePath)) { baseFilename = Path.Combine(basePath, baseFilename); } outputPath = baseFilename; } } } if (isCreate) { Ctpk.Create(inputPath, outputPath); } else if (isExtract) { Ctpk.Read(inputPath, outputPath, isRawExtract); } else { Console.WriteLine("Could not find path or file '{0}'", args[0]); } }
public static Ctpk Read(byte[] data, string filename) { Ctpk file = new Ctpk(); using (MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid CTPK file."); } file.Version = reader.ReadUInt16(); file.NumberOfTextures = reader.ReadUInt16(); file.TextureSectionOffset = reader.ReadUInt32(); file.TextureSectionSize = reader.ReadUInt32(); file.HashSectionOffset = reader.ReadUInt32(); file.TextureInfoSection = reader.ReadUInt32(); // Section 1 + 3 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); CTPKEntry entry = CTPKEntry.Read(reader); file._entries.Add(entry); } // Section 2 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info = reader.ReadUInt32(); } // Section 4 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].FilenameHash = reader.ReadUInt32(); } // Section 5 reader.BaseStream.Seek(file.TextureInfoSection, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info2 = reader.ReadUInt32(); } // Section 6 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(file.TextureSectionOffset + file._entries[i].TextureOffset, SeekOrigin.Begin); file._entries[i].TextureRawData = new byte[file._entries[i].TextureSize]; reader.Read(file._entries[i].TextureRawData, 0, (int)file._entries[i].TextureSize); } string basePath = Path.GetDirectoryName(filename); string baseFilename = Path.GetFileNameWithoutExtension(filename); if (!String.IsNullOrWhiteSpace(basePath)) { baseFilename = Path.Combine(basePath, baseFilename); } for (int i = 0; i < file.NumberOfTextures; i++) { Console.WriteLine("Converting {0}...", file._entries[i].InternalFilePath); file._entries[i].ToFile(baseFilename); } } return(file); }