private void WriteIntAtPosition(int value, int writePosition) { var oldPosition = UW.BaseStream.Position; UW.BaseStream.Position = writePosition; UW.Write(value); UW.BaseStream.Position = oldPosition; }
private void SerializeDependsTable(int exportCount) { WriteIntAtPosition((int)UW.BaseStream.Position, DependsOffsetPosition); for (int i = 0; i < exportCount; i++) { UW.Write(0); } }
private void initHeader() { UW.BaseStream.Position = 0; //Tag UW.Write(UnrealPackage.Signature); //File Version var version = (int)(DummyFileVersion & 0x0000FFFFU) | DummyLicenseeVersion << 16; UW.Write(version); //Total HeaderSize will be calculated later UW.Write(0); //Group name UW.WriteString("None"); //Package flags UW.Write(DummyPackageFlag); //Name / Import / Export count and offsets UW.Write(0); UW.Write(1); UW.Write(2); UW.Write(3); UW.Write(4); UW.Write(5); //DependsOffset / ImportExportGuidsOffset / ImportGuidsCount / ExportGuidsCount / ThumbnailTableOffset UW.Write(0); UW.Write(0); UW.Write(0); UW.Write(0); UW.Write(0); //guid (this might work?..) UW.Write(Guid.Parse(package.GUID).ToByteArray(), 0, 16); //Generations package.Generations.Serialize(this); //EngineVersion UW.Write(DummyEngineVersion); //CookerVersion UW.Write(DummyCookerVersion); //CompressionFlags UW.Write(DummyCompression); //compressedChunks UW.Write(DummyCompressedChunksData); //Unknown5 UW.Write(DummyUnknown5); //UnknownStringArray UW.Write(DummyUnknownStringArray); //UnknownTypeArray UW.Write(DummyUnknownTypeArray); }
private void SerializeExportSerialData(List <DummyExportTableItem> exportsToSerialize) { int noneIndex = package.Names.FindIndex((n) => n.Name == "None"); foreach (var dummyExport in exportsToSerialize) { var exportObject = dummyExport.original; var dummyClass = dummyFactory.Create(exportObject.ClassName); if (dummyClass != null) { dummyClass.Write(this, package); } else { //We just need the netindex and a None FName package.Stream.Position = exportObject.SerialOffset; //NetIndex UW.Write(package.Stream.ReadInt32()); //None index and count UW.Write(noneIndex); UW.Write(0); } } }
public void Serialize() { initHeader(); //Serialize name table var nameOffset = UW.BaseStream.Position; WriteIntAtPosition(package.Names.Count(), NameCountPosition); WriteIntAtPosition((int)nameOffset, NameCountPosition + 4); foreach (var name in package.Names) { name.Serialize(this); } //Serialize imports table var importOffset = UW.BaseStream.Position; WriteIntAtPosition(package.Imports.Count(), ImportCountPosition); WriteIntAtPosition((int)importOffset, ImportCountPosition + 4); foreach (var import in package.Imports) { import.Serialize(this); } var exportsToSerialize = package.Exports; //var exportsToSerialize = new List<UExportTableItem>() { package.Exports[1], package.Exports[3] }; //WriteIntAtPosition(); var exportOffset = UW.BaseStream.Position; WriteIntAtPosition(exportsToSerialize.Count(), ExportCountPosition); WriteIntAtPosition((int)exportOffset, ExportCountPosition + 4); int footerNumbers = 8; int calculatedTotalHeaderSize = (int)(UW.BaseStream.Position + ExportTableItemSize * exportsToSerialize.Count()) + footerNumbers * 4; //24 = unknown footer data int serialOffset = calculatedTotalHeaderSize; foreach (var export in exportsToSerialize) { switch (export.ClassName) { case "Texture2D": DummyExportTableSerialize(export, serialOffset, MinimalTexture2D.serialSize); serialOffset += MinimalTexture2D.serialSize; break; default: DummyExportTableSerialize(export, serialOffset, DummySerialSize); serialOffset += DummySerialSize; break; } //export.Serialize( this ); } //unknown footer info WriteIntAtPosition((int)UW.BaseStream.Position, 49); WriteIntAtPosition((int)UW.BaseStream.Position, 53); WriteIntAtPosition((int)UW.BaseStream.Position, 65); for (int ii = 0; ii < footerNumbers; ii++) { UW.Write(0); } WriteIntAtPosition((int)UW.BaseStream.Position, TotalHeaderSizePosition); int noneIndex = package.Names.FindIndex((n) => n.Name == "None"); foreach (var exportObject in exportsToSerialize) { switch (exportObject.ClassName) { case "Texture2D": new MinimalTexture2D().Write(this, package); //MinimalTexture2D.Write(this, package); break; default: //We just need the netindex and a None FName package.Stream.Position = exportObject.SerialOffset; //NetIndex UW.Write(package.Stream.ReadInt32()); //None index and count UW.Write(noneIndex); UW.Write(0); break; } } //var stream = package.Stream; //// Serialize tables //var namesBuffer = new UObjectStream(stream); //foreach (var name in package.Names) //{ // name.Serialize(namesBuffer); //} //var importsBuffer = new UObjectStream(stream); //foreach (var import in package.Imports) //{ // import.Serialize(importsBuffer); //} //var exportsBuffer = new UObjectStream(stream); //foreach (var export in package.Exports) //{ // //export.Serialize( exportsBuffer ); //} //stream.Seek(0, SeekOrigin.Begin); //stream.Write(Signature); //// Serialize header //var version = (int)(Version & 0x0000FFFFU) | (LicenseeVersion << 16); //stream.Write(version); //var headerSizePosition = stream.Position; //if (Version >= VHeaderSize) //{ // stream.Write((int)HeaderSize); // if (Version >= VGroup) // { // stream.WriteString(Group); // } //} //stream.Write(PackageFlags); //_TablesData.NamesCount = (uint)Names.Count; //_TablesData.ExportsCount = (uint)Exports.Count; //_TablesData.ImportsCount = (uint)Imports.Count; //var tablesDataPosition = stream.Position; //_TablesData.Serialize(stream); //// TODO: Serialize Heritages //stream.Write(Guid.NewGuid().ToByteArray(), 0, 16); //Generations.Serialize(stream); //if (Version >= VEngineVersion) //{ // stream.Write(EngineVersion); // if (Version >= VCOOKEDPACKAGES) // { // stream.Write(CookerVersion); // if (Version >= VCompression) // { // if (IsCooked()) // { // stream.Write(CompressionFlags); // CompressedChunks.Serialize(stream); // } // } // } //} //// TODO: Unknown data //stream.Write((uint)0); //// Serialize objects //// Write tables //// names //Log.Info("Writing names at position " + stream.Position); //_TablesData.NamesOffset = (uint)stream.Position; //var namesBytes = namesBuffer.GetBuffer(); //stream.Write(namesBytes, 0, (int)namesBuffer.Length); //// imports //Log.Info("Writing imports at position " + stream.Position); //_TablesData.ImportsOffset = (uint)stream.Position; //var importsBytes = importsBuffer.GetBuffer(); //stream.Write(importsBytes, 0, (int)importsBuffer.Length); //// exports //Log.Info("Writing exports at position " + stream.Position); //// Serialize tables data again now that offsets are known. //var currentPosition = stream.Position; //stream.Seek(tablesDataPosition, SeekOrigin.Begin); //_TablesData.Serialize(stream); //stream.Seek(currentPosition, SeekOrigin.Begin); }