// Methods public override void Load(Stream fileStream) { // BINA Header var reader = new BINAReader(fileStream); Header = reader.ReadHeader(); string sig = reader.ReadSignature(4); if (sig != Signature) { throw new InvalidSignatureException(Signature, sig); } var unknown1 = reader.ReadUInt32(); //Might be part of the Header according to Skyth's spec? if (unknown1 != 1) { Console.WriteLine($"Unknown1 does not equal 1 in this file! It's actually set to {unknown1}"); } var shapeCount = reader.ReadInt64(); var unknown2 = reader.ReadUInt64(); if (unknown2 != 24) { Console.WriteLine($"Unknown1 does not equal 24 in this file! It's actually set to {unknown1}"); } Console.WriteLine(unknown2); for (int i = 0; i < shapeCount; i++) { SvShape shape = new SvShape(); var shapeNameOffset = reader.ReadInt64(); long pos = reader.BaseStream.Position; reader.JumpTo(shapeNameOffset, false); shape.Name = reader.ReadNullTerminatedString(); reader.JumpTo(pos, true); shape.Unknown1 = reader.ReadUInt32(); shape.Size = reader.ReadVector3(); shape.Position = reader.ReadVector3(); shape.Rotation = reader.ReadQuaternion(); shape.BoundingBox.Minimum = reader.ReadVector3(); shape.BoundingBox.Maximum = reader.ReadVector3(); shape.Unknown2 = reader.ReadUInt32(); var sectorCount = reader.ReadInt64(); var sectorListOffset = reader.ReadInt64(); pos = reader.BaseStream.Position; reader.JumpTo(sectorListOffset, false); for (int s = 0; s < sectorCount; s++) { SvSector sector = new SvSector(); sector.SectorIndex = reader.Read(); sector.Visible = reader.ReadBoolean(); shape.Sectors.Add(sector); } reader.JumpTo(pos, true); SvShapes.Add(shape); } }
public override void Load(Stream fileStream) { // Read PACx Header var reader = new BINAReader(fileStream); Header.Read(reader); // Read Node Trees and compute Data Entry count var typeTree = new NodeTree(reader); var fileTrees = new NodeTree[typeTree.DataNodeIndices.Count]; int dataEntryCount = 0; Node dataNode; for (int i = 0; i < fileTrees.Length; ++i) { dataNode = typeTree.Nodes[typeTree.DataNodeIndices[i]]; reader.JumpTo((long)dataNode.Data); fileTrees[i] = new NodeTree(reader); dataEntryCount += fileTrees[i].DataNodeIndices.Count; } // Read Data Entries var dataEntries = new DataEntry[dataEntryCount]; int dataEntryIndex = -1; foreach (var fileTree in fileTrees) { for (int i = 0; i < fileTree.DataNodeIndices.Count; ++i) { dataNode = fileTree.Nodes[fileTree.DataNodeIndices[i]]; reader.JumpTo((long)dataNode.Data); dataEntries[++dataEntryIndex] = new DataEntry(reader); } } // Read Data int dataSize, bytesRead; foreach (var dataEntry in dataEntries) { if (dataEntry.DataType == DataEntryTypes.NotHere) { continue; } reader.JumpTo(dataEntry.DataOffset); dataSize = dataEntry.Data.Length; do { bytesRead = reader.Read(dataEntry.Data, 0, dataSize); if (bytesRead == 0) { throw new EndOfStreamException( "Could not read file data from PAC."); } dataSize -= bytesRead; }while (dataSize > 0); } // Get file names and add files to archive var builder = new StringBuilder(byte.MaxValue); dataEntryIndex = -1; foreach (var fileTree in fileTrees) { for (int i = 0; i < fileTree.DataNodeIndices.Count; ++i) { var dataEntry = dataEntries[++dataEntryIndex]; if (dataEntry.DataType == DataEntryTypes.NotHere) { continue; } dataNode = fileTree.Nodes[fileTree.DataNodeIndices[i]]; // Read extension reader.JumpTo(dataEntry.ExtensionOffset); builder.Append('.'); builder.Append(reader.ReadNullTerminatedString()); // Get full file name string pth; for (int i2 = dataNode.ParentIndex; i2 > 0;) { pth = fileTree.Nodes[i2].Name; i2 = fileTree.Nodes[i2].ParentIndex; if (string.IsNullOrEmpty(pth)) { continue; } builder.Insert(0, pth); } // Add to archive Data.Add(new ArchiveFile( builder.ToString(), dataEntry.Data)); builder.Clear(); } } }