Example #1
0
        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());
        }