static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse<Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } switch (options.Action) { case "toxml": { using (Stream stream = File.OpenRead(options.Source)) { Stream2File file = new Stream2File(stream); if (options.Output == null || options.Output == "") { options.Output = Path.ChangeExtension(options.Source, "xml"); } XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = "\t"; settings.NewLineChars = "\r\n"; using (XmlWriter xml = XmlWriter.Create(options.Output, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("AssetAssembler"); xml.WriteStartElement("AllocatorTypes"); foreach (var pair in file.AllocatorTypes) { xml.WriteStartElement("AllocatorType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // AllocatorTypes xml.WriteStartElement("ContainerTypes"); foreach (var pair in file.ContainerTypes) { xml.WriteStartElement("ContainerType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // ContainerTypes xml.WriteStartElement("PrimitiveTypes"); foreach (var pair in file.PrimitiveTypes) { xml.WriteStartElement("PrimitiveType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // PrimitiveTypes xml.WriteStartElement("Containers"); foreach (var container in file.Containers) { xml.WriteStartElement("Container"); xml.WriteAttributeString("Name", container.Name); xml.WriteAttributeString("Type", file.ContainerTypes[container.ContainerType]); xml.WriteAttributeString("Flags", container.Flags.ToString()); xml.WriteAttributeString("PackfileBaseOffset", container.PackfileBaseOffset.ToString()); xml.WriteAttributeString("CompressionType", container.CompressionType.ToString()); xml.WriteAttributeString("StubContainerParentName", container.StubContainerParentName); xml.WriteAttributeString("TotalCompressedPackfileReadSize", container.TotalCompressedPackfileReadSize.ToString()); if (container.AuxData.Length > 0) { xml.WriteStartElement("AuxData"); xml.WriteString(Convert.ToBase64String(container.AuxData, Base64FormattingOptions.None)); xml.WriteEndElement(); // AuxData } for (int i = 0; i < container.PrimitiveCount; i++) { var primitive = container.Primitives[i]; var sizes = container.PrimitiveSizes[i]; xml.WriteStartElement("Primitive"); xml.WriteAttributeString("Name", primitive.Name); xml.WriteAttributeString("Type", file.PrimitiveTypes[primitive.Data.Type]); xml.WriteAttributeString("Allocator", file.AllocatorTypes.ContainsKey(primitive.Data.Allocator) ? file.AllocatorTypes[primitive.Data.Allocator] : primitive.Data.Allocator.ToString()); xml.WriteAttributeString("Flags", primitive.Data.Flags.ToString()); xml.WriteAttributeString("ExtensionIndex", primitive.Data.ExtensionIndex.ToString()); xml.WriteAttributeString("CPUSize", primitive.Data.CPUSize.ToString()); xml.WriteAttributeString("GPUSize", primitive.Data.GPUSize.ToString()); xml.WriteAttributeString("AllocationGroup", primitive.Data.AllocationGroup.ToString()); xml.WriteAttributeString("WriteTimeCPUSize", sizes.CPUSize.ToString()); xml.WriteAttributeString("WriteTimeGPUSize", sizes.GPUSize.ToString()); xml.WriteEndElement(); // Primitive } xml.WriteEndElement(); // Container } xml.WriteEndElement(); // Containers xml.WriteEndElement(); // AssetAssembler xml.WriteEndDocument(); } } break; } case "toasm": { using (Stream stream = File.OpenRead(options.Source)) { XDocument xml = XDocument.Load(stream); Stream2File file = new Stream2File(); if (options.Output == null || options.Output == "") { options.Output = Path.ChangeExtension(options.Source, "asm_pc"); } Dictionary<string, byte> allocatorTypesLookup = new Dictionary<string, byte>(); Dictionary<string, byte> containerTypesLookup = new Dictionary<string, byte>(); Dictionary<string, byte> primitiveTypesLookup = new Dictionary<string, byte>(); foreach (var node in xml.Descendants("AllocatorType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; allocatorTypesLookup.Add(name, id); file.AllocatorTypes.Add(id, name); } foreach (var node in xml.Descendants("ContainerType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; containerTypesLookup.Add(name, id); file.ContainerTypes.Add(id, name); } foreach (var node in xml.Descendants("PrimitiveType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; primitiveTypesLookup.Add(name, id); file.PrimitiveTypes.Add(id, name); } foreach (var cNode in xml.Descendants("Container")) { Container container = new Container(); container.Name = cNode.Attribute("Name").Value; container.ContainerType = containerTypesLookup[cNode.Attribute("Type").Value]; container.Flags = (ContainerFlags)ushort.Parse(cNode.Attribute("Flags").Value); container.PackfileBaseOffset = uint.Parse(cNode.Attribute("PackfileBaseOffset").Value); container.CompressionType = byte.Parse(cNode.Attribute("CompressionType").Value); container.StubContainerParentName = cNode.Attribute("StubContainerParentName").Value; container.TotalCompressedPackfileReadSize = int.Parse(cNode.Attribute("TotalCompressedPackfileReadSize").Value); var auxData = cNode.Element("AuxData"); if (auxData != null) { container.AuxData = Convert.FromBase64String(auxData.Value); } else { container.AuxData = new byte[0]; } foreach (var pNode in cNode.Descendants("Primitive")) { Primitive p = new Primitive(); p.Name = pNode.Attribute("Name").Value; p.Data = new PrimitiveData(); p.Data.Type = primitiveTypesLookup[pNode.Attribute("Type").Value]; byte allocatorType = 0; if (byte.TryParse(pNode.Attribute("Allocator").Value, out allocatorType)) { p.Data.Allocator = allocatorType; } else { p.Data.Allocator = allocatorTypesLookup[pNode.Attribute("Allocator").Value]; } p.Data.Flags = byte.Parse(pNode.Attribute("Flags").Value); p.Data.ExtensionIndex = byte.Parse(pNode.Attribute("ExtensionIndex").Value); p.Data.CPUSize = uint.Parse(pNode.Attribute("CPUSize").Value); p.Data.GPUSize = uint.Parse(pNode.Attribute("GPUSize").Value); p.Data.AllocationGroup = byte.Parse(pNode.Attribute("AllocationGroup").Value); container.Primitives.Add(p); WriteTimeSizes size = new WriteTimeSizes(); size.CPUSize = uint.Parse(pNode.Attribute("WriteTimeCPUSize").Value); size.GPUSize = uint.Parse(pNode.Attribute("WriteTimeGPUSize").Value); container.PrimitiveSizes.Add(size); } container.PrimitiveCount = (ushort)container.Primitives.Count; file.Containers.Add(container); } file.Header.Signature = (uint)0xBEEFFEED; file.Header.Version = (ushort)0x000C; file.Header.NumContainers = (short)file.Containers.Count; using (Stream outputStream = File.Create(options.Output)) { file.Save(outputStream); } } break; } case "update": { Stream2File file = null; using (Stream stream = File.OpenRead(options.Source)) { file = new Stream2File(stream); string folder = Path.GetDirectoryName(options.Source); foreach (var container in file.Containers) { string str2File = Path.ChangeExtension(container.Name, ".str2_pc"); string filename = Path.Combine(folder, str2File); if (File.Exists(filename)) { Console.Write("Found {0}, updating... ", str2File); using (Stream str2Stream = File.OpenRead(filename)) { IPackfile packfile = Packfile.FromStream(str2Stream, true); packfile.Update(container); } Console.WriteLine("done."); } else { Console.WriteLine("Could not find {0}.", str2File); } } } using (Stream stream = File.Create(options.Source)) { file.Save(stream); } break; } case "clean": { Stream2File file = null; using (Stream stream = File.OpenRead(options.Source)) { file = new Stream2File(stream); string folder = Path.GetDirectoryName(options.Source); List<string> foundContainerNames = new List<string>(); List<Container> duplicates = new List<Container>(); foreach (var container in file.Containers) { if (!foundContainerNames.Contains(container.Name)) { foundContainerNames.Add(container.Name); } else { duplicates.Add(container); } } foreach (var container in duplicates) { file.Containers.Remove(container); } file.Header.NumContainers = (short)file.Containers.Count; } using (Stream stream = File.Create(options.Source)) { file.Save(stream); } break; } default: { Console.WriteLine("Unrecogised action!"); break; } } #if DEBUG Console.ReadLine(); #endif }
static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse <Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } switch (options.Action) { case "toxml": { using (Stream stream = File.OpenRead(options.Source)) { Stream2File file = new Stream2File(stream); if (options.Output == null || options.Output == "") { options.Output = Path.ChangeExtension(options.Source, "xml"); } XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = "\t"; settings.NewLineChars = "\r\n"; using (XmlWriter xml = XmlWriter.Create(options.Output, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("AssetAssembler"); xml.WriteStartElement("AllocatorTypes"); foreach (var pair in file.AllocatorTypes) { xml.WriteStartElement("AllocatorType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // AllocatorTypes xml.WriteStartElement("ContainerTypes"); foreach (var pair in file.ContainerTypes) { xml.WriteStartElement("ContainerType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // ContainerTypes xml.WriteStartElement("PrimitiveTypes"); foreach (var pair in file.PrimitiveTypes) { xml.WriteStartElement("PrimitiveType"); xml.WriteAttributeString("ID", pair.Key.ToString()); xml.WriteAttributeString("Name", pair.Value); xml.WriteEndElement(); } xml.WriteEndElement(); // PrimitiveTypes xml.WriteStartElement("Containers"); foreach (var container in file.Containers) { xml.WriteStartElement("Container"); xml.WriteAttributeString("Name", container.Name); xml.WriteAttributeString("Type", file.ContainerTypes[container.ContainerType]); xml.WriteAttributeString("Flags", container.Flags.ToString()); xml.WriteAttributeString("PackfileBaseOffset", container.PackfileBaseOffset.ToString()); xml.WriteAttributeString("CompressionType", container.CompressionType.ToString()); xml.WriteAttributeString("StubContainerParentName", container.StubContainerParentName); xml.WriteAttributeString("TotalCompressedPackfileReadSize", container.TotalCompressedPackfileReadSize.ToString()); if (container.AuxData.Length > 0) { xml.WriteStartElement("AuxData"); xml.WriteString(Convert.ToBase64String(container.AuxData, Base64FormattingOptions.None)); xml.WriteEndElement(); // AuxData } for (int i = 0; i < container.PrimitiveCount; i++) { var primitive = container.Primitives[i]; var sizes = container.PrimitiveSizes[i]; xml.WriteStartElement("Primitive"); xml.WriteAttributeString("Name", primitive.Name); xml.WriteAttributeString("Type", file.PrimitiveTypes[primitive.Data.Type]); xml.WriteAttributeString("Allocator", file.AllocatorTypes.ContainsKey(primitive.Data.Allocator) ? file.AllocatorTypes[primitive.Data.Allocator] : primitive.Data.Allocator.ToString()); xml.WriteAttributeString("Flags", primitive.Data.Flags.ToString()); xml.WriteAttributeString("ExtensionIndex", primitive.Data.ExtensionIndex.ToString()); xml.WriteAttributeString("CPUSize", primitive.Data.CPUSize.ToString()); xml.WriteAttributeString("GPUSize", primitive.Data.GPUSize.ToString()); xml.WriteAttributeString("AllocationGroup", primitive.Data.AllocationGroup.ToString()); xml.WriteAttributeString("WriteTimeCPUSize", sizes.CPUSize.ToString()); xml.WriteAttributeString("WriteTimeGPUSize", sizes.GPUSize.ToString()); xml.WriteEndElement(); // Primitive } xml.WriteEndElement(); // Container } xml.WriteEndElement(); // Containers xml.WriteEndElement(); // AssetAssembler xml.WriteEndDocument(); } } break; } case "toasm": { using (Stream stream = File.OpenRead(options.Source)) { XDocument xml = XDocument.Load(stream); Stream2File file = new Stream2File(); if (options.Output == null || options.Output == "") { options.Output = Path.ChangeExtension(options.Source, "asm_pc"); } Dictionary <string, byte> allocatorTypesLookup = new Dictionary <string, byte>(); Dictionary <string, byte> containerTypesLookup = new Dictionary <string, byte>(); Dictionary <string, byte> primitiveTypesLookup = new Dictionary <string, byte>(); foreach (var node in xml.Descendants("AllocatorType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; allocatorTypesLookup.Add(name, id); file.AllocatorTypes.Add(id, name); } foreach (var node in xml.Descendants("ContainerType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; containerTypesLookup.Add(name, id); file.ContainerTypes.Add(id, name); } foreach (var node in xml.Descendants("PrimitiveType")) { byte id = byte.Parse(node.Attribute("ID").Value); string name = node.Attribute("Name").Value; primitiveTypesLookup.Add(name, id); file.PrimitiveTypes.Add(id, name); } foreach (var cNode in xml.Descendants("Container")) { Container container = new Container(); container.Name = cNode.Attribute("Name").Value; container.ContainerType = containerTypesLookup[cNode.Attribute("Type").Value]; container.Flags = (ContainerFlags)ushort.Parse(cNode.Attribute("Flags").Value); container.PackfileBaseOffset = uint.Parse(cNode.Attribute("PackfileBaseOffset").Value); container.CompressionType = byte.Parse(cNode.Attribute("CompressionType").Value); container.StubContainerParentName = cNode.Attribute("StubContainerParentName").Value; container.TotalCompressedPackfileReadSize = int.Parse(cNode.Attribute("TotalCompressedPackfileReadSize").Value); var auxData = cNode.Element("AuxData"); if (auxData != null) { container.AuxData = Convert.FromBase64String(auxData.Value); } else { container.AuxData = new byte[0]; } foreach (var pNode in cNode.Descendants("Primitive")) { Primitive p = new Primitive(); p.Name = pNode.Attribute("Name").Value; p.Data = new PrimitiveData(); p.Data.Type = primitiveTypesLookup[pNode.Attribute("Type").Value]; byte allocatorType = 0; if (byte.TryParse(pNode.Attribute("Allocator").Value, out allocatorType)) { p.Data.Allocator = allocatorType; } else { p.Data.Allocator = allocatorTypesLookup[pNode.Attribute("Allocator").Value]; } p.Data.Flags = byte.Parse(pNode.Attribute("Flags").Value); p.Data.ExtensionIndex = byte.Parse(pNode.Attribute("ExtensionIndex").Value); p.Data.CPUSize = uint.Parse(pNode.Attribute("CPUSize").Value); p.Data.GPUSize = uint.Parse(pNode.Attribute("GPUSize").Value); p.Data.AllocationGroup = byte.Parse(pNode.Attribute("AllocationGroup").Value); container.Primitives.Add(p); WriteTimeSizes size = new WriteTimeSizes(); size.CPUSize = uint.Parse(pNode.Attribute("WriteTimeCPUSize").Value); size.GPUSize = uint.Parse(pNode.Attribute("WriteTimeGPUSize").Value); container.PrimitiveSizes.Add(size); } container.PrimitiveCount = (ushort)container.Primitives.Count; file.Containers.Add(container); } file.Header.Signature = (uint)0xBEEFFEED; file.Header.Version = (ushort)0x000C; file.Header.NumContainers = (short)file.Containers.Count; using (Stream outputStream = File.Create(options.Output)) { file.Save(outputStream); } } break; } case "update": { Stream2File file = null; using (Stream stream = File.OpenRead(options.Source)) { file = new Stream2File(stream); string folder = Path.GetDirectoryName(options.Source); foreach (var container in file.Containers) { string str2File = Path.ChangeExtension(container.Name, ".str2_pc"); string filename = Path.Combine(folder, str2File); if (File.Exists(filename)) { Console.Write("Found {0}, updating... ", str2File); using (Stream str2Stream = File.OpenRead(filename)) { IPackfile packfile = Packfile.FromStream(str2Stream, true); packfile.Update(container); } Console.WriteLine("done."); } else { Console.WriteLine("Could not find {0}.", str2File); } } } using (Stream stream = File.Create(options.Source)) { file.Save(stream); } break; } case "clean": { Stream2File file = null; using (Stream stream = File.OpenRead(options.Source)) { file = new Stream2File(stream); string folder = Path.GetDirectoryName(options.Source); List <string> foundContainerNames = new List <string>(); List <Container> duplicates = new List <Container>(); foreach (var container in file.Containers) { if (!foundContainerNames.Contains(container.Name)) { foundContainerNames.Add(container.Name); } else { duplicates.Add(container); } } foreach (var container in duplicates) { file.Containers.Remove(container); } file.Header.NumContainers = (short)file.Containers.Count; } using (Stream stream = File.Create(options.Source)) { file.Save(stream); } break; } default: { Console.WriteLine("Unrecogised action!"); break; } } #if DEBUG Console.ReadLine(); #endif }