public static T From <T>(ExportEntry export) where T : ObjectBinary, new() { var t = new T { Export = export }; t.Serialize(new SerializingContainer2(export.GetReadOnlyBinaryStream(), export.FileRef, true, export.DataOffset + export.propsEnd())); return(t); }
public static byte[] ConvertTexture2D(ExportEntry export, MEGame newGame, List <int> offsets = null, StorageTypes newStorageType = StorageTypes.empty) { MemoryStream bin = export.GetReadOnlyBinaryStream(); if (bin.Length == 0) { return(bin.ToArray()); } var os = new MemoryStream(); if (export.Game != MEGame.ME3) { bin.Skip(16); } if (newGame != MEGame.ME3) { os.WriteZeros(16);//includes fileOffset, but that will be set during save } int mipCount = bin.ReadInt32(); long mipCountPosition = os.Position; os.WriteInt32(mipCount); List <Texture2DMipInfo> mips = Texture2D.GetTexture2DMipInfos(export, export.GetProperty <NameProperty>("TextureFileCacheName")?.Value); int offsetIdx = 0; int trueMipCount = 0; for (int i = 0; i < mipCount; i++) { var storageType = (StorageTypes)bin.ReadInt32(); int uncompressedSize = bin.ReadInt32(); int compressedSize = bin.ReadInt32(); int fileOffset = bin.ReadInt32(); byte[] texture; switch (storageType) { case StorageTypes.pccUnc: texture = bin.ReadToBuffer(uncompressedSize); break; case StorageTypes.pccLZO: case StorageTypes.pccZlib: texture = bin.ReadToBuffer(compressedSize); if (offsets != null) { texture = Array.Empty <byte>(); fileOffset = offsets[offsetIdx++]; compressedSize = offsets[offsetIdx] - fileOffset; if (newStorageType != StorageTypes.empty) { storageType = newStorageType; } } break; case StorageTypes.empty: texture = new byte[0]; break; default: if (export.Game != newGame) { storageType &= (StorageTypes) ~StorageFlags.externalFile; texture = Texture2D.GetTextureData(mips[i], export.Game, MEDirectories.GetDefaultGamePath(export.Game), false); //copy in external textures } else { texture = Array.Empty <byte>(); } break; } int width = bin.ReadInt32(); int height = bin.ReadInt32(); if (newGame == MEGame.UDK && storageType == StorageTypes.empty) { continue; } trueMipCount++; os.WriteInt32((int)storageType); os.WriteInt32(uncompressedSize); os.WriteInt32(compressedSize); os.WriteInt32(fileOffset);//fileOffset will be fixed during save os.WriteFromBuffer(texture); os.WriteInt32(width); os.WriteInt32(height); } long postMipPosition = os.Position; os.JumpTo(mipCountPosition); os.WriteInt32(trueMipCount); os.JumpTo(postMipPosition); int unk1 = 0; if (export.Game != MEGame.UDK) { unk1 = bin.ReadInt32(); } if (newGame != MEGame.UDK) { os.WriteInt32(unk1); } Guid textureGuid = export.Game != MEGame.ME1 ? bin.ReadGuid() : Guid.NewGuid(); if (newGame != MEGame.ME1) { os.WriteGuid(textureGuid); } if (export.Game == MEGame.UDK) { bin.Skip(32); } if (newGame == MEGame.UDK) { os.WriteZeros(4 * 8); } if (export.Game == MEGame.ME3) { bin.Skip(4); } if (newGame == MEGame.ME3) { os.WriteInt32(0); } if (export.ClassName == "LightMapTexture2D") { int lightMapFlags = 0; if (export.Game >= MEGame.ME3) { lightMapFlags = bin.ReadInt32(); } if (newGame >= MEGame.ME3) { os.WriteInt32(0);//LightMapFlags noflag } } return(os.ToArray()); }