示例#1
0
        FObjectImport[] SerializeImportMap()
        {
            if (PackageFileSummary.ImportCount > 0)
            {
                Loader.BaseStream.Position = PackageFileSummary.ImportOffset;

                var OutImportMap = new FObjectImport[PackageFileSummary.ImportCount];
                for (int ImportMapIdx = 0; ImportMapIdx < PackageFileSummary.ImportCount; ++ImportMapIdx)
                {
                    OutImportMap[ImportMapIdx] = new FObjectImport(this);
                }
                return(OutImportMap);
            }
            return(Array.Empty <FObjectImport>());
        }
示例#2
0
文件: UAsset.cs 项目: kthulhu/UE4View
        public UAsset(byte[] data, int version) : base(data)
        {
            Version = version;
            ReadSummary();

            Seek(Summary.NameOffset);
            foreach (var i in Enumerable.Range(0, Summary.NameCount))
            {
                var entry = new FNameEntrySerialized();
                entry.Serialize(this);
                NameMap.Add(entry.Name);
            }
            Seek(Summary.GatherableTextDataOffset);
            foreach (var i in Enumerable.Range(0, Summary.GatherableTextDataCount))
            {
                Debugger.Break();
                // check whether it reads stuff properly
                var gatherable = new FGatherableTextData();
                gatherable.Serialize(this);
                GatherableTextDataMap.Add(gatherable);
            }
            Seek(Summary.ImportOffset);
            foreach (var i in Enumerable.Range(0, Summary.ImportCount))
            {
                var imp = new FObjectImport();
                imp.Serialize(this);
                ImportMap.Add(imp);
            }
            Seek(Summary.ExportOffset);
            foreach (var i in Enumerable.Range(0, Summary.ExportCount))
            {
                var exp = new FObjectExport();
                exp.Serialize(this);
                ExportMap.Add(exp);
            }
            Seek(Summary.StringAssetReferencesOffset);
            foreach (var i in Enumerable.Range(0, Summary.StringAssetReferencesCount))
            {
                StringAssetReferences.Add(ToFString());
            }

            // TODO: Fixup import, fixup exports, match exports with exporter object
        }
 public void DeserializePropertyTagValue(IAssetConverter converter)
 {
     using (BinaryReader br = new BinaryReader(converter.GetExportStream(), Encoding.UTF8, true))
     {
         int tableIndex = br.ReadInt32();
         if (tableIndex < 0)
         {
             FObjectImport import = converter.GetImportMap()[tableIndex * -1 - 1];
             this.Value = new FName($"{import.ObjectName.Name} : {import.ClassPackage.Name}/{import.ClassName.Name}")
             {
                 NameCount = import.ObjectName.NameCount
             };
         }
         else if (tableIndex > 0)
         {
             this.Value = converter.GetExportMap()[tableIndex - 1].ObjectName;
         }
         else
         {
             this.Value = new FName("UObject");
         }
     }
 }
示例#4
0
        public Package(FArchive uasset, FArchive?uexp, Lazy <FArchive?>?ubulk = null, Lazy <FArchive?>?uptnl = null, IFileProvider?provider = null, TypeMappings?mappings = null, bool useLazySerialization = true)
            : base(uasset.Name.SubstringBeforeLast(".uasset"), provider, mappings)
        {
            // We clone the version container because it can be modified with package specific versions when reading the summary
            uasset.Versions = (VersionContainer)uasset.Versions.Clone();
            var uassetAr = new FAssetArchive(uasset, this);

            Summary = new FPackageFileSummary(uassetAr);

            uassetAr.SeekAbsolute(Summary.NameOffset, SeekOrigin.Begin);
            NameMap = new FNameEntrySerialized[Summary.NameCount];
            uassetAr.ReadArray(NameMap, () => new FNameEntrySerialized(uassetAr));

            uassetAr.SeekAbsolute(Summary.ImportOffset, SeekOrigin.Begin);
            ImportMap = new FObjectImport[Summary.ImportCount];
            uassetAr.ReadArray(ImportMap, () => new FObjectImport(uassetAr));

            uassetAr.SeekAbsolute(Summary.ExportOffset, SeekOrigin.Begin);
            ExportMap = new FObjectExport[Summary.ExportCount]; // we need this to get its final size in some case
            uassetAr.ReadArray(ExportMap, () => new FObjectExport(uassetAr));

            FAssetArchive uexpAr = uexp != null ? new FAssetArchive(uexp, this, (int)uassetAr.Length) : uassetAr;  // allows embedded uexp data

            if (ubulk != null)
            {
                //var offset = (int) (Summary.TotalHeaderSize + ExportMap.Sum(export => export.SerialSize));
                var offset = Summary.BulkDataStartOffset;
                uexpAr.AddPayload(PayloadType.UBULK, offset, ubulk);
            }

            if (uptnl != null)
            {
                var offset = Summary.BulkDataStartOffset;
                uexpAr.AddPayload(PayloadType.UPTNL, offset, uptnl);
            }

            if (useLazySerialization)
            {
                foreach (var export in ExportMap)
                {
                    export.ExportObject = new Lazy <UObject>(() =>
                    {
                        // Create
                        var obj      = ConstructObject(ResolvePackageIndex(export.ClassIndex)?.Object?.Value as UStruct);
                        obj.Name     = export.ObjectName.Text;
                        obj.Outer    = (ResolvePackageIndex(export.OuterIndex) as ResolvedExportObject)?.Object.Value ?? this;
                        obj.Super    = ResolvePackageIndex(export.SuperIndex) as ResolvedExportObject;
                        obj.Template = ResolvePackageIndex(export.TemplateIndex) as ResolvedExportObject;
                        obj.Flags   |= (EObjectFlags)export.ObjectFlags; // We give loaded objects the RF_WasLoaded flag in ConstructObject, so don't remove it again in here

                        // Serialize
                        uexpAr.SeekAbsolute(export.SerialOffset, SeekOrigin.Begin);
                        DeserializeObject(obj, uexpAr, export.SerialSize);
                        // TODO right place ???
                        obj.Flags |= EObjectFlags.RF_LoadCompleted;
                        obj.PostLoad();
                        return(obj);
                    });
                }
            }
            else
            {
                var newObjNames = new List <string>();
                foreach (var export in ExportMap)
                {
                    if (export.ExportObject == null)
                    {
                        var obj = ConstructObject(ResolvePackageIndex(export.ClassIndex)?.Object?.Value as UStruct);
                        obj.Name     = export.ObjectName.Text;
                        obj.Super    = ResolvePackageIndex(export.SuperIndex) as ResolvedExportObject;
                        obj.Template = ResolvePackageIndex(export.TemplateIndex) as ResolvedExportObject;
                        obj.Flags   |= (EObjectFlags)export.ObjectFlags; // We give loaded objects the RF_WasLoaded flag in ConstructObject, so don't remove it again in here

                        export.ExportObject = new Lazy <UObject>(obj);
                        newObjNames.Add(export.ObjectName.Text);
                    }
                }

                foreach (var export in ExportMap)
                {
                    if (newObjNames.Contains(export.ObjectName.Text))
                    {
                        var obj = export.ExportObject.Value;

                        uexpAr.SeekAbsolute(export.SerialOffset, SeekOrigin.Begin);
                        DeserializeObject(obj, uexpAr, export.SerialSize);
                    }
                }

                foreach (var export in ExportMap)
                {
                    if (newObjNames.Contains(export.ObjectName.Text))
                    {
                        var obj = export.ExportObject.Value;
                        obj.Outer = (ResolvePackageIndex(export.OuterIndex) as ResolvedExportObject)?.Object.Value ?? this;
                    }
                }

                foreach (var export in ExportMap)
                {
                    if (newObjNames.Contains(export.ObjectName.Text))
                    {
                        var obj = export.ExportObject.Value;

                        obj.Flags |= EObjectFlags.RF_LoadCompleted;
                        obj.PostLoad();
                    }
                }
            }
        }
示例#5
0
        public Package(FArchive uasset, FArchive uexp, Lazy <FArchive?>?ubulk = null, Lazy <FArchive?>?uptnl = null, IFileProvider?provider = null, TypeMappings?mappings = null)
            : base(uasset.Name.SubstringBeforeLast(".uasset"), provider, mappings)
        {
            var uassetAr = new FAssetArchive(uasset, this);

            Summary = new FPackageFileSummary(uassetAr);
            if (Summary.Tag != PackageMagic)
            {
                throw new ParserException(uassetAr, $"Invalid uasset magic: {Summary.Tag} != {PackageMagic}");
            }

            uassetAr.Seek(Summary.NameOffset, SeekOrigin.Begin);
            NameMap = new FNameEntrySerialized[Summary.NameCount];
            uassetAr.ReadArray(NameMap, () => new FNameEntrySerialized(uassetAr));

            uassetAr.Seek(Summary.ImportOffset, SeekOrigin.Begin);
            ImportMap = new FObjectImport[Summary.ImportCount];
            uassetAr.ReadArray(ImportMap, () => new FObjectImport(uassetAr));

            uassetAr.Seek(Summary.ExportOffset, SeekOrigin.Begin);
            ExportMap = new FObjectExport[Summary.ExportCount]; // we need this to get its final size in some case
            uassetAr.ReadArray(ExportMap, () => new FObjectExport(uassetAr));

            var uexpAr = new FAssetArchive(uexp, this, Summary.TotalHeaderSize);

            if (ubulk != null)
            {
                //var offset = (int) (Summary.TotalHeaderSize + ExportMap.Sum(export => export.SerialSize));
                var offset = Summary.BulkDataStartOffset;
                uexpAr.AddPayload(PayloadType.UBULK, offset, ubulk);
            }

            if (uptnl != null)
            {
                var offset = Summary.BulkDataStartOffset;
                uexpAr.AddPayload(PayloadType.UPTNL, offset, uptnl);
            }

            foreach (var it in ExportMap)
            {
                if (ResolvePackageIndex(it.ClassIndex)?.Object?.Value is not UStruct uStruct)
                {
                    continue;
                }
                var export = ConstructObject(uStruct);
                export.Name     = it.ObjectName.Text;
                export.Outer    = (ResolvePackageIndex(it.OuterIndex) as ResolvedExportObject)?.Object?.Value ?? this;
                export.Template = ResolvePackageIndex(it.TemplateIndex) as ResolvedExportObject;
                export.Flags    = (int)it.ObjectFlags;
                it.ExportType   = export.GetType();
                it.ExportObject = new Lazy <UObject>(() =>
                {
                    uexpAr.SeekAbsolute(it.RealSerialOffset, SeekOrigin.Begin);
                    var validPos = uexpAr.Position + it.SerialSize;
                    try
                    {
                        export.Deserialize(uexpAr, validPos);
#if DEBUG
                        if (validPos != uexpAr.Position)
                        {
                            Log.Warning("Did not read {0} correctly, {1} bytes remaining", export.ExportType, validPos - uexpAr.Position);
                        }
                        else
                        {
                            Log.Debug("Successfully read {0} at {1} with size {2}", export.ExportType, it.RealSerialOffset, it.SerialSize);
                        }
#endif

                        // TODO right place ???
                        export.PostLoad();
                    }
                    catch (Exception e)
                    {
                        Log.Error(e, "Could not read {0} correctly", export.ExportType);
                    }

                    return(export);
                });
            }
        }
示例#6
0
 public ResolvedScriptObject(int index, Package package) : base(package, index)
 {
     _import = package.ImportMap[index];
 }
示例#7
0
 public ResolvedImportObject(FObjectImport import, Package package) : base(package)
 {
     _import = import;
 }