Exemplo n.º 1
0
        public static FObjectExport ReadEntry(IOMemoryStream ms, UassetFile f)
        {
            //Read in
            FObjectExport g = new FObjectExport();

            g.entryLocation = ms.position;
            g.id            = ms.ReadInt();
            g.unknown1      = ms.ReadInt();
            g.unknown2      = ms.ReadInt();
            g.unknown3      = ms.ReadInt();
            g.type          = ms.ReadNameTableEntry(f);
            g.unknown4      = ms.ReadInt();
            g.unknown5      = ms.ReadInt();
            g.LengthOffset  = (int)ms.position;
            g.dataLength    = ms.ReadInt();
            g.dataLocation  = ms.ReadInt();
            g.unknown6      = ms.ReadInt();
            g.unknown7      = ms.ReadInt();
            g.unknown8      = ms.ReadInt();
            g.unknown9      = ms.ReadInt();
            g.unknown10     = ms.ReadInt();
            g.unknown11     = ms.ReadInt();
            g.unknown12     = ms.ReadInt();
            g.unknown13     = ms.ReadInt();
            g.unknown14     = ms.ReadInt();
            g.unknown15     = ms.ReadInt();
            g.unknown16     = ms.ReadInt();
            g.unknown17     = ms.ReadInt();
            g.unknown18     = ms.ReadInt();
            g.unknown19     = ms.ReadInt();
            g.unknown20     = ms.ReadInt();
            g.unknown21     = ms.ReadInt();
            g.unknown22     = ms.ReadInt();

            long lastPos = ms.position;

            ms.position = g.dataLocation;
            g.data      = ms.ReadBytes(g.dataLength);
            ms.position = lastPos;

            g.uassetFile = f;

            return(g);
        }
Exemplo n.º 2
0
        public static UTexture2D GetTextureFromUAsset(UassetFile uassetFile)
        {
            /*if (uassetFile.UE4Version != UE4Version.UE4__4_14)
             *  throw new NotSupportedException($"Texture extraction from {uassetFile.UE4Version.ToString()} uasset files is not supported.");*/

            TKContext.LogInner("INFO", $"Attempting to get a texture from file {uassetFile.Filename}");

            try
            {
                FObjectExport export       = uassetFile.ExportsTable[0];
                EPixelFormat  ePixelFormat = EPixelFormat.PF_Unknown;

                int pfOffset = 0x0;

                // TODO: Simplify this mess.
                for (int i = 0; i < uassetFile.NamesTable.Length; i++)
                {
                    if (uassetFile.NamesTable[i].Name.ToUpper().StartsWith("PF_"))
                    {
                        if (!Enum.TryParse(uassetFile.NamesTable[i].Name, out ePixelFormat))
                        {
                            TKContext.LogError("Pixel Format is not supported.");
                            return(null);
                        }
                    }
                }

                UTexture2D uTexture2D = new UTexture2D();
                //uTexture2D.USerializedData = uSerializedData;
                uTexture2D.UassetFile = uassetFile;
                TKContext.LogInner("INFO", $"Attempting to find {ePixelFormat.ToString()}");
                pfOffset = ArrayExtensions.IndexOfPattern(export.data, Encoding.ASCII.GetBytes(ePixelFormat.ToString()));
                TKContext.LogInner("INFO", $"Pixel Format offset is 0x{pfOffset:X8}");

                if (pfOffset == int.MaxValue)
                {
                    TKContext.LogError("No texture was found.");
                    return(null);
                }

                uTexture2D.PFOffset = pfOffset;

                uTexture2D.PixelFormat  = ePixelFormat;
                uTexture2D.Height       = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, pfOffset - UASSET_RELATIVE_PF_HEIGHT, 4), 0);
                uTexture2D.Width        = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, pfOffset - UASSET_RELATIVE_PF_WIDTH, 4), 0);
                uTexture2D.UnknownValue = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, pfOffset + 0x8, 4), 0);

                TKContext.LogInner("INFO", $"Texture resolution is {uTexture2D.Width}x{uTexture2D.Height}");

                int[] offsets = ArrayExtensions.Locate(export.data, BitConverter.GetBytes(PF_SEPERATOR));

                uTexture2D.MipMapCount = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[0] - 0x4, 4), 0);
                uTexture2D.Mipmaps     = new List <FTexture2DMipMap>();

                TKContext.LogInner("INFO", $"Texture has {uTexture2D.MipMapCount} mipmaps");

                uTexture2D.FirstSeperatorOffset = offsets[0];

                for (int i = 0; i < uTexture2D.MipMapCount; i++)
                {
                    FTexture2DMipMap fTexture2DMipMap = new FTexture2DMipMap();

                    fTexture2DMipMap.UncompressedSize    = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_UNCOMPRESSED_SIZE_OFFSET, 4), 0);
                    fTexture2DMipMap.TextureUassetOffset = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_TEXTURE_START_OFFSET_OFFSET, 4), 0);
                    fTexture2DMipMap.UnknownValue        = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_UNKNOWN_OFFSET, 4), 0);
                    fTexture2DMipMap.Texture             = ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_TEXTURE_DATA, fTexture2DMipMap.UncompressedSize);
                    fTexture2DMipMap.Width  = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_TEXTURE_DATA + fTexture2DMipMap.UncompressedSize, 4), 0);
                    fTexture2DMipMap.Height = BitConverter.ToInt32(ArrayExtensions.GetBytesFromByteArray(export.data, offsets[i] + SEPERATOR_TEXTURE_DATA + fTexture2DMipMap.UncompressedSize + 0x4, 4), 0);

                    uTexture2D.Mipmaps.Add(fTexture2DMipMap);

                    TKContext.LogInner("INFO", fTexture2DMipMap.ToString());
                }

                return(uTexture2D);
            }
            catch (Exception ex)
            {
                TKContext.LogException(ex.ToString());
                return(null);
            }
        }
Exemplo n.º 3
0
        public UassetFile(byte[] data, string fullPath)
        {
            Fullpath = fullPath;
            Filename = Path.GetFileNameWithoutExtension(Fullpath);

            //Create a stream
            stream = new IOMemoryStream(new MemoryStream(data), true);

            stream.position = 0;

            var signature = stream.ReadUInt();

            // Check for the file's signature.
            if (signature != UNREAL_ASSET_MAGIC)
            {
                TKContext.LogError("The file provided is not a valid uasset file.");
                return;
            }

            Version = stream.ReadUInt();

            stream.ReadBytes(0x10);
            UnkOffset = stream.ReadInt();
            stream.ReadInt();

            PackageGroup = Encoding.ASCII.GetString(stream.ReadBytes(0x4));

            stream.ReadBytes(0x1);

            PackageFlags = stream.ReadUInt();
            NamesCount   = stream.ReadInt();
            NamesOffset  = stream.ReadInt();

            stream.ReadBytes(0x8);

            ExportsCount  = stream.ReadInt();
            ExportsOffset = stream.ReadInt();

            ImportsCount  = stream.ReadInt();
            ImportsOffset = stream.ReadInt();

            stream.ReadBytes(0x8);

            UnkOffset2 = stream.ReadInt();

            stream.ReadBytes(0x1C);

            NamesCount2 = stream.ReadInt();

            stream.ReadBytes(0x2C);

            UnkOffset3      = stream.ReadInt();
            EndOfFileOffset = stream.ReadInt();

            stream.ReadBytes(0x10);
            UnkOffset4 = stream.ReadInt();

            stream.position = NamesOffset;

            NamesTable = stream.ReadFNameEntries(NamesCount, UE4Version.UE4__4_14);


            for (int i = 0; i < NamesCount; i++)
            {
                TKContext.DebugLog("UassetFile", $"Name Table Entry {i}", NamesTable[i].Name, ConsoleColor.Yellow);
            }

            TKContext.LogInner("INFO", $"Uasset names count is {NamesCount}");

            //Starts directly after the name table. Assume we're already there
            ImportsTable = new FObjectImport[ImportsCount];
            for (int i = 0; i < ImportsCount; i++)
            {
                FObjectImport h = FObjectImport.ReadEntry(stream, this);
                ImportsTable[i] = h;
                DebugDump($"FObjectImport {i} @ {h.startPos}", ConsoleColor.Blue, "cType", h.coreType, "u1", h.unknown1.ToString(), "oType", h.objectType, "u2", h.unknown2.ToString(), "i", h.index.ToString(), "name", h.name, "u4", h.unknown4.ToString());
            }

            TKContext.LogInner("INFO", $"Uasset import table size is {ImportsCount}");

            //Starts directly after the referenced GameObject table. Assume we're already there
            ExportsTable = new FObjectExport[ExportsCount];
            for (int i = 0; i < ExportsCount; i++)
            {
                ExportsTable[i] = FObjectExport.ReadEntry(stream, this);
                DebugDump($"FObjectExport {i} @ {ExportsTable[i].entryLocation}", ConsoleColor.Magenta, "id", ExportsTable[i].id.ToString(), "u2", ExportsTable[i].unknown2.ToString(),
                          "u3", ExportsTable[i].unknown3.ToString(), "type", ExportsTable[i].type, "u4", ExportsTable[i].unknown4.ToString(), "u5", ExportsTable[i].unknown5.ToString(),
                          "length", ExportsTable[i].dataLength.ToString(), "location", ExportsTable[i].dataLocation.ToString(), "u6", ExportsTable[i].unknown6.ToString(), "u7",
                          ExportsTable[i].unknown7.ToString(), "u8", ExportsTable[i].unknown8.ToString(), "u9", ExportsTable[i].unknown9.ToString(), "u10", ExportsTable[i].unknown10.ToString(), "u11", ExportsTable[i].unknown11.ToString(),
                          "u12", ExportsTable[i].unknown12.ToString(), "u13", ExportsTable[i].unknown13.ToString(), "u14", ExportsTable[i].unknown14.ToString(), "u15", ExportsTable[i].unknown15.ToString(),
                          "u16", ExportsTable[i].unknown16.ToString(), "u17", ExportsTable[i].unknown17.ToString(), "u18", ExportsTable[i].unknown18.ToString(), "u19", ExportsTable[i].unknown19.ToString(),
                          "u20", ExportsTable[i].unknown20.ToString(), "u21", ExportsTable[i].unknown21.ToString(), "u22", ExportsTable[i].unknown22.ToString());
            }

            TKContext.LogInner("INFO", $"Uasset export table size is {ExportsCount}");

            using (MemoryStream ms = new MemoryStream())
            {
                stream.position = 0;
                stream.ms.CopyTo(ms);
                stream.Close();

                FileData = ms.ToArray();
            }
        }