/// <summary>
 /// The export.
 /// </summary>
 /// <param name="entry">
 /// The entry.
 /// </param>
 protected override void Export(ExportEntry entry)
 {
     if (entry.IsSingleton)
     {
         this.container.RegisterType(
             entry.InfType, entry.ImplType, entry.Name, new ContainerControlledLifetimeManager());
     }
     else
     {
         this.container.RegisterType(
             entry.InfType, entry.ImplType, entry.Name);
     }
 }
        void IStringSettingConvertible.Convert(string settingValue)
        {
            if (string.IsNullOrWhiteSpace(settingValue))
            {
                return;
            }

            XDocument doc = XDocument.Parse(settingValue);

            foreach (var exportE in doc.Root.Elements("Export"))
            {
                ExportEntry evm = new ExportEntry();
                evm.Name = exportE.Attribute("Name").Value;
                evm.IsEnabled = bool.Parse(exportE.Attribute("IsEnabled").Value);
                Exports.Add(evm);
            }
        }
        protected override void Export(ExportEntry entry)
        {
            IRegistrationBuilder<object, ConcreteReflectionActivatorData, SingleRegistrationStyle> regBuilder =
                this.builder.RegisterType(entry.ImplType);

            if (string.IsNullOrEmpty(entry.Name))
            {
                regBuilder.As(entry.InfType);
            }
            else
            {
                regBuilder.Named(entry.Name, entry.InfType);
            }

            if (entry.IsSingleton)
            {
                regBuilder.SingleInstance();
            }
        }
Example #4
0
 public void Save(string filePath = null)
 {
     try
     {
         DebugLog.PrintLn("Writing Header...", true);
         MemoryStream m = new MemoryStream();
         m.Write(BitConverter.GetBytes(Header.magic), 0, 4);
         m.Write(BitConverter.GetBytes(Header.ver1), 0, 2);
         m.Write(BitConverter.GetBytes(Header.ver2), 0, 2);
         m.Write(BitConverter.GetBytes(Header.HeaderLength), 0, 4);
         WriteUString(Header.Group, m);
         if (GeneralInfo.compressed)
         {
             m.Write(BitConverter.GetBytes(Header.Flags ^ 0x02000000), 0, 4);
         }
         else
         {
             m.Write(BitConverter.GetBytes(Header.Flags), 0, 4);
         }
         m.Write(BitConverter.GetBytes(Header.unk1), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk2), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk3), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk4), 0, 4);
         m.Write(Header.GUID, 0, 16);
         m.Write(BitConverter.GetBytes(Header.Generations.Count), 0, 4);
         foreach (Generation g in Header.Generations)
         {
             m.Write(BitConverter.GetBytes(g.ExportCount), 0, 4);
             m.Write(BitConverter.GetBytes(g.ImportCount), 0, 4);
             m.Write(BitConverter.GetBytes(g.NetObjCount), 0, 4);
         }
         m.Write(BitConverter.GetBytes(Header.EngineVersion), 0, 4);
         m.Write(BitConverter.GetBytes(Header.CookerVersion), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk5), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk6), 0, 4);
         m.Write(BitConverter.GetBytes(Header.CompressionFlag), 0, 4);
         m.Write(BitConverter.GetBytes(0), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk7), 0, 4);
         m.Write(BitConverter.GetBytes(Header.unk8), 0, 4);
         DebugLog.PrintLn("Writing Name Table...", true);
         Header.NameOffset = (uint)m.Position;
         Header.NameCount  = (uint)Names.Count;
         foreach (string s in Names)
         {
             WriteUString(s, m);
         }
         DebugLog.PrintLn("Writing Import Table...", true);
         Header.ImportOffset = (uint)m.Position;
         Header.ImportCount  = (uint)Imports.Count;
         foreach (ImportEntry e in Imports)
         {
             m.Write(BitConverter.GetBytes(e.idxPackage), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk1), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxClass), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk2), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxLink), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxName), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk3), 0, 4);
         }
         DebugLog.PrintLn("Writing Export Table...", true);
         Header.ExportOffset = (uint)m.Position;
         Header.ExportCount  = (uint)Exports.Count;
         for (int i = 0; i < Exports.Count; i++)
         {
             ExportEntry e = Exports[i];
             e._infooffset = (uint)m.Position;
             Exports[i]    = e;
             m.Write(BitConverter.GetBytes(e.idxClass), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxParent), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxLink), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxName), 0, 4);
             m.Write(BitConverter.GetBytes(e.Index), 0, 4);
             m.Write(BitConverter.GetBytes(e.idxArchetype), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk1), 0, 4);
             m.Write(BitConverter.GetBytes(e.ObjectFlags), 0, 4);
             m.Write(BitConverter.GetBytes(0), 0, 4);
             m.Write(BitConverter.GetBytes(0), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk2), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk3.Length), 0, 4);
             foreach (int j in e.Unk3)
             {
                 m.Write(BitConverter.GetBytes(j), 0, 4);
             }
             m.Write(BitConverter.GetBytes(e.Unk4), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk5), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk6), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk7), 0, 4);
             m.Write(BitConverter.GetBytes(e.Unk8), 0, 4);
         }
         DebugLog.PrintLn("Writing Free Zone...", true);
         int FreeZoneSize = (int)Header.FreeZoneEnd - (int)Header.FreeZoneStart;
         Header.FreeZoneStart = (uint)m.Position;
         m.Write(new byte[FreeZoneSize], 0, FreeZoneSize);
         Header.FreeZoneEnd = Header.HeaderLength = (uint)m.Position;
         DebugLog.PrintLn("Writing Export Data...", true);
         for (int i = 0; i < Exports.Count; i++)
         {
             ExportEntry e    = Exports[i];
             byte[]      buff = GetObjectData(i);
             e.Dataoffset = (int)m.Position;
             e.Datasize   = buff.Length;
             m.Write(buff, 0, buff.Length);
             long pos = m.Position;
             m.Seek(e._infooffset + 32, 0);
             m.Write(BitConverter.GetBytes(e.Datasize), 0, 4);
             m.Write(BitConverter.GetBytes(e.Dataoffset), 0, 4);
             m.Seek(pos, 0);
         }
         DebugLog.PrintLn("Updating Header...", true);
         m.Seek(8, 0);
         m.Write(BitConverter.GetBytes(Header.HeaderLength), 0, 4);
         m.Seek(24 + (Header.Group.Length + 1) * 2, 0);
         m.Write(BitConverter.GetBytes(Header.NameCount), 0, 4);
         m.Write(BitConverter.GetBytes(Header.NameOffset), 0, 4);
         m.Write(BitConverter.GetBytes(Header.ExportCount), 0, 4);
         m.Write(BitConverter.GetBytes(Header.ExportOffset), 0, 4);
         m.Write(BitConverter.GetBytes(Header.ImportCount), 0, 4);
         m.Write(BitConverter.GetBytes(Header.ImportOffset), 0, 4);
         m.Write(BitConverter.GetBytes(Header.FreeZoneStart), 0, 4);
         m.Write(BitConverter.GetBytes(Header.FreeZoneEnd), 0, 4);
         DebugLog.PrintLn("Done generating.", true);
         if (Source != null)
         {
             Source.Close();
         }
         if (filePath == null)
         {
             File.WriteAllBytes(GeneralInfo.filepath, m.ToArray());
         }
         else
         {
             File.WriteAllBytes(filePath, m.ToArray());
         }
         DebugLog.PrintLn("Done.", true);
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::SAVE ERROR:\n" + ex.Message);
     }
 }
Example #5
0
 private static bool CanRandomize(ExportEntry exp) => !exp.IsDefaultObject && exp.ObjectFlags.Has(UnrealFlags.EObjectFlags.ArchetypeObject) && exp.ClassName == "SFXSkeletalMeshActorMAT" && !exp.ObjectName.Name.Contains("Dead", StringComparison.InvariantCultureIgnoreCase);
 protected InterpTrack(ExportEntry export)
 {
     Export     = export;
     TrackTitle = export.GetProperty <StrProperty>("TrackTitle")?.Value ?? export.ObjectName.Instanced;
 }
Example #7
0
 protected UnContainer(ExportEntry self, int superIndex, byte[] bytecode)
     : base(self, bytecode)
 {
     _super = superIndex == 0 ? null : _self.FileRef.GetEntry(superIndex);
 }
Example #8
0
        private void ReadExports(MemoryTributary fs)
        {
            DebugOutput.PrintLn("Reading Exports...");
            fs.Seek(ExportOffset, SeekOrigin.Begin);
            Exports = new List<ExportEntry>();
            
            for (int i = 0; i < ExportCount; i++)
            {
                long start = fs.Position;
                ExportEntry exp = new ExportEntry();
                exp.pccRef = this;
                exp.infoOffset = (int)start;

                fs.Seek(40, SeekOrigin.Current);
                int count = fs.ReadValueS32();
                fs.Seek(4 + count * 12, SeekOrigin.Current);
                count = fs.ReadValueS32();
                fs.Seek(4 + count * 4, SeekOrigin.Current);
                fs.Seek(16, SeekOrigin.Current);
                long end = fs.Position;
                fs.Seek(start, SeekOrigin.Begin);
                exp.info = fs.ReadBytes((int)(end - start));
                Exports.Add(exp);
                fs.Seek(end, SeekOrigin.Begin);

                if (LastExport == null || exp.DataOffset > LastExport.DataOffset)
                    LastExport = exp;
            }
        }
Example #9
0
 public void CloneEntry(int uIndex)
 {
     if (uIndex > 0)
     {
         ExportEntry e = Exports[uIndex - 1];
         ExportEntry n = new ExportEntry();
         n.Data = CopyArray(GetObjectData(uIndex - 1));
         n.DataLoaded = true;
         n.Datasize = n.Data.Length;
         n.idxClass = e.idxClass;
         n.idxParent = e.idxParent;
         n.idxLink = e.idxLink;
         n.idxName = e.idxName;
         n.Index = GetBiggestIndex() + 1;
         n.idxArchetype = e.idxArchetype;
         n.Unk1 = e.Unk1;
         n.ObjectFlags = e.ObjectFlags;
         n.Unk2 = e.Unk2;
         n.Unk3 = new int[e.Unk3.Length];
         for (int i = 0; i < e.Unk3.Length; i++)
             n.Unk3[i] = e.Unk3[i];
         n.Unk2 = e.Unk4;
         n.Unk2 = e.Unk5;
         n.Unk2 = e.Unk6;
         n.Unk2 = e.Unk7;
         n.Unk2 = e.Unk8;
         Exports.Add(n);
         Header.ExportCount++;
     }
     else
     {
         ImportEntry e = Imports[-uIndex - 1];
         ImportEntry n = new ImportEntry();
         n.idxPackage = e.idxPackage;
         n.Unk1 = e.Unk1;
         n.idxClass = e.idxClass;
         n.Unk2 = e.Unk2;
         n.idxLink = e.idxLink;
         n.idxName = e.idxName;
         n.Unk3 = e.Unk3;
         Imports.Add(n);
         Header.ImportCount++;
     }
 }
Example #10
0
        public static PropertyInfo getPropertyInfo(string className, string propName, bool inStruct = false, ClassInfo nonVanillaClassInfo = null, bool reSearch = true, ExportEntry containingExport = null)
        {
            if (className.StartsWith("Default__"))
            {
                className = className.Substring(9);
            }
            Dictionary <string, ClassInfo> temp = inStruct ? Structs : Classes;
            bool infoExists = temp.TryGetValue(className, out ClassInfo info);

            if (!infoExists && nonVanillaClassInfo != null)
            {
                info       = nonVanillaClassInfo;
                infoExists = true;
            }
            if (infoExists) //|| (temp = !inStruct ? Structs : Classes).ContainsKey(className))
            {
                //look in class properties
                if (info.properties.TryGetValue(propName, out var propInfo))
                {
                    return(propInfo);
                }
                //look in structs

                foreach (PropertyInfo p in info.properties.Values())
                {
                    if ((p.Type == PropertyType.StructProperty || p.Type == PropertyType.ArrayProperty) && reSearch)
                    {
                        PropertyInfo val = getPropertyInfo(p.Reference, propName, true, nonVanillaClassInfo, reSearch: false);
                        if (val != null)
                        {
                            return(val);
                        }
                    }
                }
                //look in base class
                if (temp.ContainsKey(info.baseClass))
                {
                    PropertyInfo val = getPropertyInfo(info.baseClass, propName, inStruct, nonVanillaClassInfo, reSearch: true);
                    if (val != null)
                    {
                        return(val);
                    }
                }
                else
                {
                    //Baseclass may be modified as well...
                    if (containingExport != null && containingExport.idxSuperClass > 0)
                    {
                        //Class parent is in this file. Generate class parent info and attempt refetch
                        ExportEntry parentExport = containingExport.FileRef.getUExport(containingExport.idxSuperClass);
                        return(getPropertyInfo(parentExport.SuperClassName, propName, inStruct, generateClassInfo(parentExport), reSearch: true, parentExport));
                    }
                }
            }

            //if (reSearch)
            //{
            //    PropertyInfo reAttempt = getPropertyInfo(className, propName, !inStruct, nonVanillaClassInfo, reSearch: false);
            //    return reAttempt; //will be null if not found.
            //}
            return(null);
        }
        //public List<TextureParam> Textures = new List<TextureParam>();

        //public struct TextureParam
        //{
        //    public int TexIndex;
        //    public string Desc;
        //}

        public MaterialInstanceConstant(ExportEntry export, PackageCache assetCache = null)
        {
            Export = export;
            ReadMaterial(export, assetCache);
        }
Example #12
0
        public override void LoadExport(ExportEntry exportEntry)
        {
            CurrentLoadedExport = exportEntry;
            var props = exportEntry.GetProperties();
            List <ParticleSystemNode> rootNodes = new List <ParticleSystemNode>();

            var emitters = props.GetProp <ArrayProperty <ObjectProperty> >("Emitters");

            foreach (var emitter in emitters)
            {
                if (emitter.Value != 0)
                {
                    if (CurrentLoadedExport.FileRef.IsUExport(emitter.Value))
                    {
                        var                emitterExport = CurrentLoadedExport.FileRef.GetUExport(emitter.Value);
                        var                emitterName   = emitterExport.GetProperty <NameProperty>("EmitterName");
                        string             header        = emitterName?.Value.Name ?? "Emitter";
                        ParticleSystemNode p             = new ParticleSystemNode {
                            Entry = emitterExport, Header = $"{emitterExport.UIndex} {header}"
                        };
                        rootNodes.Add(p);
                        var emitterLODs = emitterExport.GetProperty <ArrayProperty <ObjectProperty> >("LODLevels");
                        int lodNumber   = 0;
                        if (emitterLODs != null)
                        {
                            foreach (var lod in emitterLODs)
                            {
                                var lodExport            = CurrentLoadedExport.FileRef.GetUExport(lod.Value);
                                ParticleSystemNode psLod = new ParticleSystemNode
                                {
                                    Entry  = lodExport,
                                    Header = $"LOD {lodNumber}: {lodExport.UIndex} {lodExport.InstancedFullPath}"
                                };
                                p.Children.Add(psLod);

                                {
                                    var requiredModule = (ExportEntry)lodExport.GetProperty <ObjectProperty>("RequiredModule")?.ResolveToEntry(CurrentLoadedExport.FileRef);
                                    if (requiredModule != null)
                                    {
                                        ParticleSystemNode reqModule = new ParticleSystemNode
                                        {
                                            Entry  = requiredModule,
                                            Header =
                                                $"Required Module: {requiredModule.UIndex} {requiredModule.InstancedFullPath}"
                                        };
                                        psLod.Children.Add(reqModule);

                                        var materialEntry = requiredModule.GetProperty <ObjectProperty>("Material")?.ResolveToEntry(CurrentLoadedExport.FileRef);
                                        if (materialEntry != null)
                                        {
                                            ParticleSystemNode matNode = new ParticleSystemNode
                                            {
                                                Entry  = materialEntry,
                                                Header = $"Material: {materialEntry.UIndex} {materialEntry.InstancedFullPath}"
                                            };
                                            reqModule.Children.Add(matNode);
                                        }
                                    }
                                }

                                var typeDataExport = (ExportEntry)lodExport.GetProperty <ObjectProperty>("TypeDataModule")?.ResolveToEntry(CurrentLoadedExport.FileRef);
                                if (typeDataExport != null)
                                {
                                    ParticleSystemNode typeModuleNode = new ParticleSystemNode {
                                        Entry = typeDataExport, Header = $"Type Data Module: {typeDataExport.UIndex} {typeDataExport.InstancedFullPath}"
                                    };
                                    psLod.Children.Add(typeModuleNode);

                                    var meshes = typeDataExport.GetProperty <ArrayProperty <ObjectProperty> >("m_Meshes");
                                    if (meshes != null)
                                    {
                                        int meshIndex = 0;
                                        foreach (var mesh in meshes)
                                        {
                                            var meshExp = mesh.ResolveToEntry(CurrentLoadedExport.FileRef);
                                            if (meshExp != null)
                                            {
                                                ParticleSystemNode meshNode = new ParticleSystemNode {
                                                    Entry = meshExp, Header = $"Mesh {meshIndex}: {meshExp.UIndex} {meshExp.InstancedFullPath}"
                                                };
                                                typeModuleNode.Children.Add(meshNode);
                                            }

                                            meshIndex++;
                                        }
                                    }
                                }

                                var modules = lodExport.GetProperty <ArrayProperty <ObjectProperty> >("Modules");
                                if (modules != null)
                                {
                                    int modIndex = 0;
                                    foreach (var module in modules)
                                    {
                                        var moduleExp = module.ResolveToEntry(CurrentLoadedExport.FileRef);
                                        if (moduleExp != null)
                                        {
                                            ParticleSystemNode moduleNode = new ParticleSystemNode {
                                                Entry = moduleExp, Header = $"Module {modIndex}: {moduleExp.UIndex} {moduleExp.InstancedFullPath}"
                                            };
                                            psLod.Children.Add(moduleNode);
                                            GenerateNode(moduleNode);
                                        }

                                        modIndex++;
                                    }
                                }

                                lodNumber++;
                            }
                        }
                    }
                }
            }

            ParticleNodes.ReplaceAll(rootNodes);
        }
Example #13
0
        public static ArrayType getArrayType(string className, string propName, bool inStruct = false, ExportEntry export = null)
        {
            PropertyInfo p = getPropertyInfo(className, propName, inStruct, containingExport: export)
                             ?? getPropertyInfo(className, propName, !inStruct, containingExport: export);

            if (p == null && export != null)
            {
                if (export.ClassName != "Class" && export.idxClass > 0)
                {
                    export = export.FileRef.Exports[export.idxClass - 1]; //make sure you get actual class
                }
                if (export.ClassName == "Class")
                {
                    ClassInfo currentInfo = generateClassInfo(export);
                    currentInfo.baseClass = export.SuperClassName;
                    p = getPropertyInfo(className, propName, inStruct, currentInfo, containingExport: export)
                        ?? getPropertyInfo(className, propName, !inStruct, currentInfo, containingExport: export);
                }
            }
            return(getArrayType(p));
        }
Example #14
0
        //Random distributions "Op"
        //
        // 0 = NONE
        // 1 = Random
        // 2 = Extremes (ends)
        // 3 = Random (range) take random within range

        public override bool CanParse(ExportEntry exportEntry) =>
        !exportEntry.IsDefaultObject && exportEntry.ClassName == "ParticleSystem";
Example #15
0
        /// <summary>
        ///     PCCObject class constructor. It also load namelist, importlist and exportinfo (not exportdata) from pcc file
        /// </summary>
        /// <param name="pccFilePath">full path + file name of desired pcc file.</param>
        public PCCObject(string pccFilePath, bool fullFileInMemory = false)
        {
            Loaded = true;
            pccFileName = Path.GetFullPath(pccFilePath);
            using (FileStream pccStream = File.OpenRead(pccFileName))
            {
                Names   = new List<string>();
                Imports = new List<ImportEntry>();
                Exports = new List<ExportEntry>();

                pccStream.Read(header, 0, header.Length);
                if (magic != ZBlock.magic &&
                    magic.Swap() != ZBlock.magic)
                {
                    throw new FormatException("not a pcc file");
                }

                // BitConverter isn't working?!?!
                if (magic == 0x9E2A83C1)
                    BitConverter.IsLittleEndian = true;
                else
                    BitConverter.IsLittleEndian = true;

                if (lowVers != 684 && highVers != 194)
                {
                    throw new FormatException("unsupported version");
                }

                Stream listsStream;

                if (bCompressed)
                {
                    // seeks the blocks info position
                    pccStream.Seek(idxOffsets + 60, SeekOrigin.Begin);
                    int generator = pccStream.ReadValueS32();
                    pccStream.Seek((generator * 12) + 20, SeekOrigin.Current);

                    int blockCount = pccStream.ReadValueS32();
                    blockList = new List<Block>();

                    // creating the Block list
                    for (int i = 0; i < blockCount; i++)
                    {
                        Block temp = new Block();
                        temp.uncOffset = pccStream.ReadValueS32();
                        temp.uncSize = pccStream.ReadValueS32();
                        temp.cprOffset = pccStream.ReadValueS32();
                        temp.cprSize = pccStream.ReadValueS32();
                        blockList.Add(temp);
                    }

                    // correcting the header, in case there's need to be saved
                    Buffer.BlockCopy(BitConverter.GetBytes((int)0), 0, header, header.Length - 12, sizeof(int));
                    pccStream.Read(header, header.Length - 8, 8);
                    headerEnd = (int)pccStream.Position;

                    // copying the extraNamesList
                    int extraNamesLenght = blockList[0].cprOffset - headerEnd;
                    if (extraNamesLenght > 0)
                    {
                        extraNamesList = new byte[extraNamesLenght];
                        pccStream.Read(extraNamesList, 0, extraNamesLenght);
                        //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin");
                        //fileStream.Write(extraNamesList, 0, extraNamesLenght);
                        //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8"));
                    }

                    // decompress first block that holds infos about names, imports and exports
                    pccStream.Seek(blockList[0].cprOffset, SeekOrigin.Begin);
                    byte[] uncBlock = ZBlock.Decompress(pccStream, blockList[0].cprSize);

                    // write decompressed block inside temporary stream
                    listsStream = new MemoryStream();
                    listsStream.Seek(blockList[0].uncOffset, SeekOrigin.Begin);
                    listsStream.Write(uncBlock, 0, uncBlock.Length);
                }
                else
                {
                    listsStream = pccStream;
                    headerEnd = (int)NameOffset;

                    // copying the extraNamesList
                    int extraNamesLenght = headerEnd - headerSize;
                    if (extraNamesLenght > 0)
                    {
                        extraNamesList = new byte[extraNamesLenght];
                        listsStream.Seek(headerSize, SeekOrigin.Begin);
                        listsStream.Read(extraNamesList, 0, extraNamesLenght);
                        //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin");
                        //fileStream.Write(extraNamesList, 0, extraNamesLenght);
                        //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8"));
                    }
                }

                /*if(bExtraNamesList)
                {
                    int extraNamesListSize = namesOffset - headerEnd;
                    extraNamesList = new byte[extraNamesListSize];
                    pccStream.Seek(headerEnd, SeekOrigin.Begin);
                    pccStream.Read(extraNamesList, 0, extraNamesList.Length);
                }*/

                // fill names list
                listsStream.Seek(NameOffset, SeekOrigin.Begin);
                for (int i = 0; i < NameCount; i++)
                {
                    long currOffset = listsStream.Position;
                    int strLength = listsStream.ReadValueS32();
                    string str = listsStream.ReadString(strLength * -2, true, Encoding.Unicode);
                    //Debug.WriteLine("Read name "+i+" "+str+" length: " + strLength+", offset: "+currOffset);
                    Names.Add(str);
                }
                //Debug.WriteLine("Names done. Current offset: "+listsStream.Position);
                //Debug.WriteLine("Import Offset: " + ImportOffset);

                // fill import list
                Console.Out.WriteLine("IMPORT OFFSET: " + ImportOffset);
                listsStream.Seek(ImportOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[ImportEntry.byteSize];
                for (int i = 0; i < ImportCount; i++)
                {

                    long offset = listsStream.Position;
                    ImportEntry e = new ImportEntry(this, listsStream);
                    Imports.Add(e);
                    //Debug.WriteLine("Read import " + i + " " + e.ObjectName + ", offset: " + offset);
                }

                Debug.WriteLine("Imports done. Current offset: " + listsStream.Position);
                Debug.WriteLine("Export Offset: " + ExportOffset);

                // fill export list (only the headers, not the data)
                listsStream.Seek(ExportOffset, SeekOrigin.Begin);
                Console.Out.WriteLine("Export OFFSET: " + ImportOffset);
                for (int i = 0; i < ExportCount; i++)
                {
                    uint expInfoOffset = (uint)listsStream.Position;

                    listsStream.Seek(44, SeekOrigin.Current);
                    int count = listsStream.ReadValueS32();
                    listsStream.Seek(-48, SeekOrigin.Current);

                    int expInfoSize = 68 + (count * 4);
                    buffer = new byte[expInfoSize];

                    listsStream.Read(buffer, 0, buffer.Length);
                    ExportEntry e = new ExportEntry(this, buffer, expInfoOffset);
                    //Debug.WriteLine("Read export " + i + " " + e.ObjectName + ", offset: " + expInfoOffset+ ", size: "+expInfoSize);

                    Exports.Add(e);
                }
            }
            Debug.WriteLine(getMetadataString());
        }
Example #16
0
        /// <summary>
        ///     given export data offset, the function recovers it from the file.
        /// </summary>
        /// <param name="offset">offset position of desired export data</param>
        private void getData(int offset, ExportEntry exp = null)
        {
            byte[] buffer;
            if (bCompressed)
            {
                Block selected = blockList.Find(block => block.uncOffset <= offset && block.uncOffset + block.uncSize > offset);
                byte[] uncBlock;

                using (FileStream pccStream = File.OpenRead(pccFileName))
                {
                    pccStream.Seek(selected.cprOffset, SeekOrigin.Begin);
                    uncBlock = ZBlock.Decompress(pccStream, selected.cprSize);

                    // the selected block has been read
                    selected.bRead = true;
                }

                // fill all the exports data extracted from the uncBlock
                foreach (ExportEntry expInfo in Exports)
                {
                    if (expInfo.DataOffset >= selected.uncOffset && expInfo.DataOffset + expInfo.DataSize <= selected.uncOffset + selected.uncSize)
                    {
                        buffer = new byte[expInfo.DataSize];
                        Buffer.BlockCopy(uncBlock, expInfo.DataOffset - selected.uncOffset, buffer, 0, expInfo.DataSize);
                        expInfo.Data = buffer;
                    }
                }
            }
            else
            {
                ExportEntry expSelect;
                if (exp == null)
                {
                    int expIndex = Exports.FindIndex(export => export.DataOffset <= offset && export.DataOffset + export.DataSize > offset);
                    expSelect = Exports[expIndex];
                }
                else
                {
                    expSelect = exp;
                }
                using (FileStream pccStream = File.OpenRead(pccFileName))
                {
                    buffer = new byte[expSelect.DataSize];
                    pccStream.Seek(expSelect.DataOffset, SeekOrigin.Begin);
                    pccStream.Read(buffer, 0, buffer.Length);
                    expSelect.Data = buffer;
                }
            }
        }
Example #17
0
 public virtual void Dispose()
 {
     g      = null;
     pcc    = null;
     export = null;
 }
Example #18
0
        private static PropertyInfo getProperty(ExportEntry entry)
        {
            IMEPackage pcc = entry.FileRef;

            string       reference = null;
            PropertyType type;

            switch (entry.ClassName)
            {
            case "IntProperty":
                type = PropertyType.IntProperty;
                break;

            case "StringRefProperty":
                type = PropertyType.StringRefProperty;
                break;

            case "FloatProperty":
                type = PropertyType.FloatProperty;
                break;

            case "BoolProperty":
                type = PropertyType.BoolProperty;
                break;

            case "StrProperty":
                type = PropertyType.StrProperty;
                break;

            case "NameProperty":
                type = PropertyType.NameProperty;
                break;

            case "DelegateProperty":
                type = PropertyType.DelegateProperty;
                break;

            case "ClassProperty":
            case "ObjectProperty":
            case "ComponentProperty":
                type      = PropertyType.ObjectProperty;
                reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                break;

            case "StructProperty":
                type      = PropertyType.StructProperty;
                reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                break;

            case "BioMask4Property":
            case "ByteProperty":
                type      = PropertyType.ByteProperty;
                reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                break;

            case "ArrayProperty":
                type = PropertyType.ArrayProperty;
                PropertyInfo arrayTypeProp = getProperty(pcc.getUExport(BitConverter.ToInt32(entry.Data, 44)));
                if (arrayTypeProp != null)
                {
                    switch (arrayTypeProp.Type)
                    {
                    case PropertyType.ObjectProperty:
                    case PropertyType.StructProperty:
                    case PropertyType.ArrayProperty:
                        reference = arrayTypeProp.Reference;
                        break;

                    case PropertyType.ByteProperty:
                        //if (arrayTypeProp.reference == "")
                        if (arrayTypeProp.Reference == "Class")
                        {
                            reference = arrayTypeProp.Type.ToString();
                        }
                        else
                        {
                            reference = arrayTypeProp.Reference;
                        }
                        break;

                    case PropertyType.IntProperty:
                    case PropertyType.FloatProperty:
                    case PropertyType.NameProperty:
                    case PropertyType.BoolProperty:
                    case PropertyType.StrProperty:
                    case PropertyType.StringRefProperty:
                    case PropertyType.DelegateProperty:
                        reference = arrayTypeProp.Type.ToString();
                        break;

                    case PropertyType.None:
                    case PropertyType.Unknown:
                    default:
                        Debugger.Break();
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }
                break;

            case "InterfaceProperty":
            default:
                return(null);
            }

            bool transient = ((UnrealFlags.EPropertyFlags)BitConverter.ToUInt64(entry.Data, 24)).HasFlag(UnrealFlags.EPropertyFlags.Transient);

            return(new PropertyInfo(type, reference, transient));
        }
Example #19
0
 /// <summary>
 ///     given export data offset, the function recovers it from the file.
 /// </summary>
 /// <param name="offset">offset position of desired export data</param>
 private void getData(int offset, ExportEntry exp = null)
 {
     byte[] buffer;
     ExportEntry expSelect;
     if (exp == null)
     {
         int expIndex = Exports.FindIndex(export => export.DataOffset <= offset && export.DataOffset + export.DataSize > offset);
         expSelect = Exports[expIndex];
     }
     else
     {
         expSelect = exp;
     }
     using (FileStream udkStream = File.OpenRead(FileName))
     {
         buffer = new byte[expSelect.DataSize];
         udkStream.Seek(expSelect.DataOffset, SeekOrigin.Begin);
         udkStream.Read(buffer, 0, buffer.Length);
         expSelect.Data = buffer;
     }
 }
Example #20
0
 /// <summary>
 /// Add an export entry.
 /// </summary>
 /// <param name="entry">
 /// An entry to add.
 /// </param>
 protected void Add(ExportEntry entry)
 {
     this.exportEntries.Add(entry);
 }
        public static PropertyCollection GetSequenceObjectDefaults(IMEPackage pcc, ClassInfo info)
        {
            MEGame             game     = pcc.Game;
            PropertyCollection defaults = new PropertyCollection();

            if (info.ClassName == "Sequence")
            {
                defaults.Add(new ArrayProperty <ObjectProperty>("SequenceObjects"));
            }
            else if (!info.IsA(SequenceVariableName, game))
            {
                ArrayProperty <StructProperty> varLinksProp   = null;
                ArrayProperty <StructProperty> outLinksProp   = null;
                ArrayProperty <StructProperty> eventLinksProp = null;
                ArrayProperty <StructProperty> inLinksProp    = null;
                Dictionary <string, ClassInfo> classes        = UnrealObjectInfo.GetClasses(game);
                try
                {
                    ClassInfo classInfo = info;
                    while (classInfo != null && (varLinksProp is null || outLinksProp is null || eventLinksProp is null || game == MEGame.ME1 && inLinksProp is null))
                    {
                        string filepath   = Path.Combine(MEDirectories.GetBioGamePath(game), classInfo.pccPath);
                        Stream loadStream = null;
                        if (File.Exists(classInfo.pccPath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(classInfo.pccPath));
                        }
                        else if (classInfo.pccPath == UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName)
                        {
                            loadStream = Utilities.GetCustomAppResourceStream(game);
                        }
                        else if (File.Exists(filepath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                        }
                        else if (game == MEGame.ME1)
                        {
                            filepath = Path.Combine(ME1Directory.DefaultGamePath, classInfo.pccPath); //for files from ME1 DLC
                            if (File.Exists(filepath))
                            {
                                loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                            }
                        }
                        if (loadStream != null)
                        {
                            using IMEPackage importPCC = MEPackageHandler.OpenMEPackageFromStream(loadStream);
                            ExportEntry classExport   = importPCC.GetUExport(classInfo.exportIndex);
                            UClass      classBin      = ObjectBinary.From <UClass>(classExport);
                            ExportEntry classDefaults = importPCC.GetUExport(classBin.Defaults);

                            foreach (var prop in classDefaults.GetProperties())
                            {
                                if (varLinksProp == null && prop.Name == "VariableLinks" && prop is ArrayProperty <StructProperty> vlp)
                                {
                                    varLinksProp = vlp;
                                    //relink ExpectedType
                                    foreach (StructProperty varLink in varLinksProp)
                                    {
                                        if (varLink.GetProp <ObjectProperty>("ExpectedType") is ObjectProperty expectedTypeProp &&
                                            importPCC.TryGetEntry(expectedTypeProp.Value, out IEntry expectedVar) &&
                                            EntryImporterExtended.EnsureClassIsInFile(pcc, expectedVar.ObjectName) is IEntry portedExpectedVar)
                                        {
                                            expectedTypeProp.Value = portedExpectedVar.UIndex;
                                        }
                                    }
                                }
                                if (outLinksProp == null && prop.Name == "OutputLinks" && prop is ArrayProperty <StructProperty> olp)
                                {
                                    outLinksProp = olp;
                                }

                                if (eventLinksProp == null && prop.Name == "EventLinks" && prop is ArrayProperty <StructProperty> elp)
                                {
                                    eventLinksProp = elp;
                                    //relink ExpectedType
                                    foreach (StructProperty eventLink in eventLinksProp)
                                    {
                                        if (eventLink.GetProp <ObjectProperty>("ExpectedType") is ObjectProperty expectedTypeProp &&
                                            importPCC.TryGetEntry(expectedTypeProp.Value, out IEntry expectedVar) &&
                                            EntryImporterExtended.EnsureClassIsInFile(pcc, expectedVar.ObjectName) is IEntry portedExpectedVar)
                                        {
                                            expectedTypeProp.Value = portedExpectedVar.UIndex;
                                        }
                                    }
                                }

                                if (game == MEGame.ME1 && inLinksProp is null && prop.Name == "InputLinks" && prop is ArrayProperty <StructProperty> ilp)
                                {
                                    inLinksProp = ilp;
                                }
                            }
                        }
                        classes.TryGetValue(classInfo.baseClass, out classInfo);
                    }
                }
                catch
                {
                    // ignored
                }
                if (varLinksProp != null)
                {
                    defaults.Add(varLinksProp);
                }
                if (outLinksProp != null)
                {
                    defaults.Add(outLinksProp);
                }
                if (eventLinksProp != null)
                {
                    defaults.Add(eventLinksProp);
                }
                if (inLinksProp != null)
                {
                    defaults.Add(inLinksProp);
                }

                //remove links if empty
                if (defaults.GetProp <ArrayProperty <StructProperty> >("OutputLinks") is { } outLinks&& outLinks.IsEmpty())
                {
                    defaults.Remove(outLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("VariableLinks") is { } varLinks&& varLinks.IsEmpty())
                {
                    defaults.Remove(varLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("EventLinks") is { } eventLinks&& eventLinks.IsEmpty())
                {
                    defaults.Remove(eventLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("InputLinks") is { } inputLinks&& inputLinks.IsEmpty())
                {
                    defaults.Remove(inputLinks);
                }
            }

            int objInstanceVersion = UnrealObjectInfo.getSequenceObjectInfo(game, info.ClassName)?.ObjInstanceVersion ?? 1;

            defaults.Add(new IntProperty(objInstanceVersion, "ObjInstanceVersion"));

            return(defaults);
        }
        private static void RepointAllVariableReferencesToNode(ExportEntry targetNode, ExportEntry newNode, List <ExportEntry> exceptions = null)
        {
            var sequence        = targetNode.FileRef.GetUExport(targetNode.GetProperty <ObjectProperty>("ParentSequence").Value);
            var sequenceObjects = sequence.GetProperty <ArrayProperty <ObjectProperty> >("SequenceObjects");

            foreach (var seqObjRef in sequenceObjects)
            {
                var saveProps     = false;
                var seqObj        = targetNode.FileRef.GetUExport(seqObjRef.Value);
                var props         = seqObj.GetProperties();
                var variableLinks = props.GetProp <ArrayProperty <StructProperty> >("VariableLinks");
                if (variableLinks != null)
                {
                    foreach (var variableLink in variableLinks)
                    {
                        var linkedVars = variableLink.GetProp <ArrayProperty <ObjectProperty> >("LinkedVariables");
                        if (linkedVars != null)
                        {
                            foreach (var linkedVar in linkedVars)
                            {
                                if (linkedVar.Value == targetNode.UIndex)
                                {
                                    linkedVar.Value = newNode.UIndex; //repoint
                                    saveProps       = true;
                                }
                            }
                        }
                    }
                }

                if (saveProps)
                {
                    seqObj.WriteProperties(props);
                }
            }
        }
 /// <summary>
 /// Export an entry for import later.
 /// </summary>
 /// <param name="entry">
 /// The entry to export.
 /// </param>
 protected abstract void Export(ExportEntry entry);
 internal static void SetLocation(ExportEntry bioPawn, Vector3 position)
 {
     SetLocation(bioPawn, position.X, position.Y, position.Z);
 }
 private static bool CanRandomize(ExportEntry export) => !export.IsDefaultObject &&
 (export.ClassName == @"SpotLightComponent" ||
  export.ClassName == @"PointLightComponent" ||
  export.ClassName == @"DirectionalLightComponent" ||
  export.ClassName == @"SkyLightComponent");
Example #26
0
        public ExportEntry cloneExport(int exportid, string newPackageName, string newObjectName)
        {
            ExportEntry cloneObj = Exports[exportid-1];

            ExportEntry exp = new ExportEntry();
            exp.pccRef = this;

            exp.Info = cloneObj.Info;

            listsStream.Seek(ExportDataEnd, SeekOrigin.Begin);
            exp.DataSize = cloneObj.DataSize;
            exp.DataOffset = (int)listsStream.Position;
            exp.ClassName = cloneObj.ClassName;

            byte[] data = cloneObj.Data;

            listsStream.Seek(ExportDataEnd, SeekOrigin.Begin);
            listsStream.WriteBytes(data);
            exp.exportid = Exports.Count()+1;

            exp.setPackageName(newPackageName);
            exp.setObjectName(newObjectName);

            LastExport = exp;
            Exports.Add(exp);
            return exp;
        }
 public InterpTrackMove(ExportEntry export) : base(export)
 {
 }
 public override bool CanParse(ExportEntry exportEntry)
 {
     return((exportEntry.ClassName == "Function" || exportEntry.ClassName == "State") && exportEntry.FileRef.Game != MEGame.UDK);
 }
Example #29
0
 protected UnBytecodeOwner(ExportEntry self, byte[] bytecode)
 {
     _self     = self;
     _bytecode = bytecode;
 }
Example #30
0
        public static ObjectBinary From(ExportEntry export)
        {
            if (export.IsDefaultObject)
            {
                //DefaultObjects don't have binary
                return(null);
            }
            string className = export.ClassName;

            if (export.IsA("BioPawn"))
            {
                //way, waaay too many subclasses of BioPawn to put in the switch statement, so we take care of it here
                className = "BioPawn";
            }
            switch (className)
            {
            case "AnimSequence":
                return(From <AnimSequence>(export));

            case "BioStage":
                return(From <BioStage>(export));

            case "Level":
                return(From <Level>(export));

            case "World":
                return(From <World>(export));

            case "Model":
                return(From <Model>(export));

            case "Polys":
                return(From <Polys>(export));

            case "DecalMaterial":
            case "Material":
                return(From <Material>(export));

            case "MaterialInstanceConstant":
            case "MaterialInstanceTimeVarying":
                if (export.GetProperty <BoolProperty>("bHasStaticPermutationResource")?.Value == true)
                {
                    return(From <MaterialInstance>(export));
                }
                return(Array.Empty <byte>());

            case "FracturedStaticMesh":
                return(From <FracturedStaticMesh>(export));

            case "StaticMesh":
                return(From <StaticMesh>(export));

            case "SkeletalMesh":
            case "BioSocketSupermodel":
                return(From <SkeletalMesh>(export));

            case "CoverMeshComponent":
            case "InteractiveFoliageComponent":
            case "SplineMeshComponent":
            case "FracturedStaticMeshComponent":
            case "StaticMeshComponent":
                return(From <StaticMeshComponent>(export));

            case "DecalComponent":
                return(From <DecalComponent>(export));

            case "Terrain":
                return(From <Terrain>(export));

            case "TerrainComponent":
                return(From <TerrainComponent>(export));

            case "FluidSurfaceComponent":
                return(From <FluidSurfaceComponent>(export));

            case "ModelComponent":
                return(From <ModelComponent>(export));

            case "BioDynamicAnimSet":
                return(From <BioDynamicAnimSet>(export));

            case "BioPawn":
                return(From <BioPawn>(export));

            case "PrefabInstance":
                return(From <PrefabInstance>(export));

            case "Class":
                return(From <UClass>(export));

            case "State":
                return(From <UState>(export));

            case "Function":
                return(From <UFunction>(export));

            case "Enum":
                return(From <UEnum>(export));

            case "Const":
                return(From <UConst>(export));

            case "ScriptStruct":
                return(From <UScriptStruct>(export));

            case "IntProperty":
                return(From <UIntProperty>(export));

            case "BoolProperty":
                return(From <UBoolProperty>(export));

            case "FloatProperty":
                return(From <UFloatProperty>(export));

            case "NameProperty":
                return(From <UNameProperty>(export));

            case "StrProperty":
                return(From <UStrProperty>(export));

            case "StringRefProperty":
                return(From <UStringRefProperty>(export));

            case "ByteProperty":
                return(From <UByteProperty>(export));

            case "ObjectProperty":
                return(From <UObjectProperty>(export));

            case "ComponentProperty":
                return(From <UComponentProperty>(export));

            case "InterfaceProperty":
                return(From <UInterfaceProperty>(export));

            case "ArrayProperty":
                return(From <UArrayProperty>(export));

            case "StructProperty":
                return(From <UStructProperty>(export));

            case "BioMask4Property":
                return(From <UBioMask4Property>(export));

            case "MapProperty":
                return(From <UMapProperty>(export));

            case "ClassProperty":
                return(From <UClassProperty>(export));

            case "DelegateProperty":
                return(From <UDelegateProperty>(export));

            case "ShaderCache":
                return(From <ShaderCache>(export));

            case "StaticMeshCollectionActor":
                return(From <StaticMeshCollectionActor>(export));

            case "StaticLightCollectionActor":
                return(From <StaticLightCollectionActor>(export));

            case "WwiseEvent":
                return(From <WwiseEvent>(export));

            case "WwiseStream":
                return(From <WwiseStream>(export));

            case "WwiseBank":
                return(From <WwiseBank>(export));

            case "BioGestureRuntimeData":
                return(From <BioGestureRuntimeData>(export));

            case "LightMapTexture2D":
                return(From <LightMapTexture2D>(export));

            case "Texture2D":
            case "ShadowMapTexture2D":
            case "TerrainWeightMapTexture":
            case "TextureFlipBook":
                return(From <UTexture2D>(export));

            case "GuidCache":
                return(From <GuidCache>(export));

            case "FaceFXAnimSet":
                return(From <FaceFXAnimSet>(export));

            case "Bio2DA":
            case "Bio2DANumberedRows":
                return(From <Bio2DABinary>(export));

            case "BioMorphFace":
                return(From <BioMorphFace>(export));

            case "MorphTarget":
                return(From <MorphTarget>(export));

            case "SFXMorphFaceFrontEndDataSource":
                return(From <SFXMorphFaceFrontEndDataSource>(export));

            case "PhysicsAssetInstance":
                return(From <PhysicsAssetInstance>(export));

            case "DirectionalLightComponent":
            case "PointLightComponent":
            case "SkyLightComponent":
            case "SphericalHarmonicLightComponent":
            case "SpotLightComponent":
            case "DominantSpotLightComponent":
            case "DominantPointLightComponent":
            case "DominantDirectionalLightComponent":
                return(From <LightComponent>(export));

            case "ShadowMap1D":
                return(From <ShadowMap1D>(export));

            case "BioTlkFileSet":
                return(From <BioTlkFileSet>(export));

            case "RB_BodySetup":
                return(From <RB_BodySetup>(export));

            case "BrushComponent":
                return(From <BrushComponent>(export));

            case "ForceFeedbackWaveform":
                return(From <ForceFeedbackWaveform>(export));

            case "SoundCue":
                return(From <SoundCue>(export));

            case "SoundNodeWave":
                return(From <SoundNodeWave>(export));

            case "ObjectRedirector":
                return(From <ObjectRedirector>(export));

            case "TextureMovie":
                return(From <TextureMovie>(export));

            default:
                return(null);
            }
        }
Example #31
0
 private void ReadExportTable()
 {
     try
     {
         DebugLog.PrintLn("Reading Export Table...");
         Exports = new List <ExportEntry>();
         if (GeneralInfo.compressed)
         {
             UncompressRange(Header._offsetCompFlagEnd + 0xC, Header.HeaderLength - (Header._offsetCompFlagEnd + 0xC));
             Header.DeCompBuffer.Seek(Header.ExportOffset, 0);
             for (int i = 0; i < Header.ExportCount; i++)
             {
                 ExportEntry e = new ExportEntry();
                 e.idxClass     = ReadInt(Header.DeCompBuffer);
                 e.idxParent    = ReadInt(Header.DeCompBuffer);
                 e.idxLink      = ReadInt(Header.DeCompBuffer);
                 e.idxName      = ReadInt(Header.DeCompBuffer);
                 e.Index        = ReadInt(Header.DeCompBuffer);
                 e.idxArchetype = ReadInt(Header.DeCompBuffer);
                 e.Unk1         = ReadInt(Header.DeCompBuffer);
                 e.ObjectFlags  = ReadInt(Header.DeCompBuffer);
                 e.Datasize     = ReadInt(Header.DeCompBuffer);
                 e.Dataoffset   = ReadInt(Header.DeCompBuffer);
                 long pos = Header.DeCompBuffer.Position;
                 if (!GeneralInfo.loadfull)
                 {
                     e.DataLoaded = false;
                 }
                 else
                 {
                     e.Data       = GetObjectData(e.Dataoffset, e.Datasize);
                     e.DataLoaded = true;
                 }
                 Header.DeCompBuffer.Seek(pos, 0);
                 e.Unk2 = ReadInt(Header.DeCompBuffer);
                 int count = ReadInt(Header.DeCompBuffer);
                 e.Unk3 = new int[count];
                 for (int j = 0; j < count; j++)
                 {
                     e.Unk3[j] = ReadInt(Header.DeCompBuffer);
                 }
                 e.Unk4 = ReadInt(Header.DeCompBuffer);
                 e.Unk5 = ReadInt(Header.DeCompBuffer);
                 e.Unk6 = ReadInt(Header.DeCompBuffer);
                 e.Unk7 = ReadInt(Header.DeCompBuffer);
                 e.Unk8 = ReadInt(Header.DeCompBuffer);
                 Exports.Add(e);
             }
         }
         else
         {
             Source.Seek(Header.ExportOffset, 0);
             for (int i = 0; i < Header.ExportCount; i++)
             {
                 ExportEntry e = new ExportEntry();
                 e.idxClass     = ReadInt(Source);
                 e.idxParent    = ReadInt(Source);
                 e.idxLink      = ReadInt(Source);
                 e.idxName      = ReadInt(Source);
                 e.Index        = ReadInt(Source);
                 e.idxArchetype = ReadInt(Source);
                 e.Unk1         = ReadInt(Source);
                 e.ObjectFlags  = ReadInt(Source);
                 e.Datasize     = ReadInt(Source);
                 e.Dataoffset   = ReadInt(Source);
                 long pos = Source.Position;
                 if (!GeneralInfo.loadfull)
                 {
                     e.DataLoaded = false;
                 }
                 else
                 {
                     e.Data       = GetObjectData(e.Dataoffset, e.Datasize);
                     e.DataLoaded = true;
                 }
                 Source.Seek(pos, 0);
                 e.Unk2 = ReadInt(Source);
                 int count = ReadInt(Source);
                 e.Unk3 = new int[count];
                 for (int j = 0; j < count; j++)
                 {
                     e.Unk3[j] = ReadInt(Source);
                 }
                 e.Unk4 = ReadInt(Source);
                 e.Unk5 = ReadInt(Source);
                 e.Unk6 = ReadInt(Source);
                 e.Unk7 = ReadInt(Source);
                 e.Unk8 = ReadInt(Source);
                 Exports.Add(e);
             }
         }
         DebugLog.PrintLn("Done.");
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::READEXPORTTABLE ERROR:\n" + ex.Message);
     }
 }
Example #32
0
        public static void CreateReachSpec(ExportEntry startNode, bool createTwoWay, ExportEntry destinationNode, string reachSpecClass, ReachSpecSize size, PropertyCollection externalGUIDProperties = null)
        {
            IMEPackage  Pcc = startNode.FileRef;
            ExportEntry reachSpectoClone = Pcc.Exports.FirstOrDefault(x => x.ClassName == "ReachSpec");

            if (externalGUIDProperties != null) //EXTERNAL
            {
                //external node

                //Debug.WriteLine("Num Exports: " + pcc.Exports.Count);
                if (reachSpectoClone != null)
                {
                    ExportEntry outgoingSpec = reachSpectoClone.Clone();
                    Pcc.AddExport(outgoingSpec);

                    IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type.

                    outgoingSpec.Class      = reachSpecClassImp;
                    outgoingSpec.ObjectName = reachSpecClassImp.ObjectName;

                    var            properties            = outgoingSpec.GetProperties();
                    ObjectProperty outgoingSpecStartProp = properties.GetProp <ObjectProperty>("Start");                                                                   //START
                    StructProperty outgoingEndStructProp = properties.GetProp <StructProperty>("End");                                                                     //Embeds END
                    ObjectProperty outgoingSpecEndProp   = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END
                    outgoingSpecStartProp.Value = startNode.UIndex;
                    outgoingSpecEndProp.Value   = 0;
                    var endGuid = outgoingEndStructProp.GetProp <StructProperty>("Guid");
                    endGuid.Properties = externalGUIDProperties; //set the other guid values to our guid values

                    //Add to source node prop
                    ArrayProperty <ObjectProperty> PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList");
                    PathList.Add(new ObjectProperty(outgoingSpec.UIndex));
                    startNode.WriteProperty(PathList);
                    outgoingSpec.WriteProperties(properties);


                    //Write Spec Size
                    SharedPathfinding.SetReachSpecSize(outgoingSpec, size.SpecRadius, size.SpecHeight);

                    //Reindex reachspecs.
                    SharedPathfinding.ReindexMatchingObjects(outgoingSpec);
                }
            }
            else
            {
                //Debug.WriteLine("Source Node: " + startNode.Index);

                //Debug.WriteLine("Num Exports: " + pcc.Exports.Count);
                //int outgoingSpec = pcc.ExportCount;
                //int incomingSpec = pcc.ExportCount + 1;


                if (reachSpectoClone != null)
                {
                    ExportEntry outgoingSpec = reachSpectoClone.Clone();
                    Pcc.AddExport(outgoingSpec);
                    ExportEntry incomingSpec = null;
                    if (createTwoWay)
                    {
                        incomingSpec = reachSpectoClone.Clone();
                        Pcc.AddExport(incomingSpec);
                    }

                    IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type.

                    outgoingSpec.Class      = reachSpecClassImp;
                    outgoingSpec.ObjectName = reachSpecClassImp.ObjectName;

                    var outgoingSpecProperties = outgoingSpec.GetProperties();
                    if (reachSpecClass == "Engine.SlotToSlotReachSpec")
                    {
                        outgoingSpecProperties.Add(new ByteProperty(1, "SpecDirection")); //We might need to find a way to support this edit
                    }

                    //Debug.WriteLine("Outgoing UIndex: " + outgoingSpecExp.UIndex);

                    ObjectProperty outgoingSpecStartProp = outgoingSpecProperties.GetProp <ObjectProperty>("Start");                                                       //START
                    StructProperty outgoingEndStructProp = outgoingSpecProperties.GetProp <StructProperty>("End");                                                         //Embeds END
                    ObjectProperty outgoingSpecEndProp   = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END
                    outgoingSpecStartProp.Value = startNode.UIndex;
                    outgoingSpecEndProp.Value   = destinationNode.UIndex;

                    //Add to source node prop
                    var PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList");
                    PathList.Add(new ObjectProperty(outgoingSpec.UIndex));
                    startNode.WriteProperty(PathList);

                    //Write Spec Size
                    SetReachSpecSize(outgoingSpecProperties, size.SpecRadius, size.SpecHeight);
                    outgoingSpec.WriteProperties(outgoingSpecProperties);

                    if (createTwoWay)
                    {
                        incomingSpec.Class      = reachSpecClassImp;
                        incomingSpec.ObjectName = reachSpecClassImp.ObjectName;
                        var incomingSpecProperties = incomingSpec.GetProperties();
                        if (reachSpecClass == "Engine.SlotToSlotReachSpec")
                        {
                            incomingSpecProperties.Add(new ByteProperty(2, "SpecDirection"));
                        }

                        ObjectProperty incomingSpecStartProp = incomingSpecProperties.GetProp <ObjectProperty>("Start");                                                       //START
                        StructProperty incomingEndStructProp = incomingSpecProperties.GetProp <StructProperty>("End");                                                         //Embeds END
                        ObjectProperty incomingSpecEndProp   = incomingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(incomingSpec)); //END

                        incomingSpecStartProp.Value = destinationNode.UIndex;                                                                                                  //Uindex
                        incomingSpecEndProp.Value   = startNode.UIndex;


                        //Add reachspec to destination node's path list (returning)
                        var DestPathList = destinationNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList");
                        DestPathList.Add(new ObjectProperty(incomingSpec.UIndex));
                        destinationNode.WriteProperty(DestPathList);

                        //destNode.WriteProperty(DestPathList);
                        SetReachSpecSize(incomingSpecProperties, size.SpecRadius, size.SpecHeight);

                        incomingSpec.WriteProperties(incomingSpecProperties);
                    }

                    //Reindex reachspecs.
                    SharedPathfinding.ReindexMatchingObjects(outgoingSpec);
                }
            }
        }
Example #33
0
        public static bool RandomizeBasicGestures(ExportEntry export, RandomizationOption option)
        {
            if (!CanRandomize(export))
            {
                return(false);
            }
            if (export.GetProperty <ObjectProperty>("SkeletalMeshComponent")?.ResolveToEntry(export.FileRef) is ExportEntry smc)
            {
                //Debug.WriteLine($"Installing new lite animations for {export.InstancedFullPath}");
                var animsets         = smc.GetProperty <ArrayProperty <ObjectProperty> >("AnimSets");
                var animTreeTemplate = smc.GetProperty <ObjectProperty>("AnimTreeTemplate")?.ResolveToEntry(export.FileRef) as ExportEntry;
                if (animsets != null && animTreeTemplate != null)
                {
                    int numAnimationsSupported = 0;
                    foreach (var animsetO in animsets)
                    {
                        var animset   = animsetO.ResolveToEntry(export.FileRef) as ExportEntry;
                        var sequences = animset.GetProperty <ArrayProperty <ObjectProperty> >("Sequences");
                        numAnimationsSupported += sequences.Count;
                    }

                    smc.RemoveProperty("AnimSets"); // We want to force new animations. we'll waste a bit of memory doing this but oh well
                    List <RBioEvtSysTrackGesture.Gesture> installedGestures = new List <RBioEvtSysTrackGesture.Gesture>();
                    var animationPackagesCache = new MERPackageCache();
                    while (numAnimationsSupported > 0)
                    {
                        // should we make sure they're unique?
                        var randGest = RBioEvtSysTrackGesture.InstallRandomFilteredGestureAsset(export.FileRef, 2, smaKeywords, null, null, true);
                        InstallDynamicAnimSetRefForSkeletalMesh(smc, randGest);
                        installedGestures.Add(randGest);
                        numAnimationsSupported--;
                    }
                    animationPackagesCache.ReleasePackages();
                    var isSubfile = PackageTools.IsLevelSubfile(Path.GetFileName(export.FileRef.FilePath));
                    if (isSubfile)
                    {
                        var newName = export.ObjectName + "_MER";
                        export.ObjectName = new NameReference(newName, ThreadSafeRandom.Next(25685462));
                    }

                    // Update the anim tree to use the new animations
                    // Too lazy to properly trace to find nodes. Just take children of this node that are AnimNodeSequences

                    // Add blend times to nodes so they 'blend' together a bit more, look a bit less jank
                    SetupChildrenBlend(animTreeTemplate);


                    // If the animtree has 'DebugPostLoad' flag, it means MER already is using this for something else
                    // We need to generate a new tree so the animations work properly
                    if (animTreeTemplate.ObjectFlags.Has(UnrealFlags.EObjectFlags.DebugPostLoad))
                    {
                        animTreeTemplate            = EntryCloner.CloneTree(animTreeTemplate, true);
                        animTreeTemplate.ObjectName = export.FileRef.GetNextIndexedName("MER_AnimTree"); // New name
                        smc.WriteProperty(new ObjectProperty(animTreeTemplate, "AnimTreeTemplate"));     // Write the template back
                    }
                    else if (isSubfile)
                    {
                        // if it's a subfile it won't be used as an import
                        // Let's rename this object
                        animTreeTemplate.ObjectName = new NameReference("MER_AnimTree", ThreadSafeRandom.Next(200000000)); // New name
                    }


                    var animNodeSequences = export.FileRef.Exports.Where(x => x.idxLink == animTreeTemplate.UIndex && x.IsA("AnimNodeSequence")).ToList();
                    for (int i = 0; i < installedGestures.Count; i++)
                    {
                        var installedG = installedGestures[i];
                        var ans        = animNodeSequences[i];
                        ans.WriteProperty(new NameProperty(installedG.GestureAnim, "AnimSeqName"));
                    }
                    animTreeTemplate.ObjectFlags |= UnrealFlags.EObjectFlags.DebugPostLoad; // Set as used
                    return(true);
                }
            }
            return(false);
        }
Example #34
0
 /// <summary>
 /// Gets the end name of a ReachSpec for property parsing. ME1 uses Nav, while ME2 and above use Actor.
 /// </summary>
 /// <param name="export">export used to determine which game is being parsed</param>
 /// <returns>Actor for ME2/ME3, Nav for ME1</returns>
 public static string GetReachSpecEndName(ExportEntry export) => export.FileRef.Game < MEGame.ME3 && export.FileRef.Platform != MEPackage.GamePlatform.PS3 ? "Nav" : "Actor";
Example #35
0
        /// <summary>
        ///     UDKFile class constructor. It also load namelist, importlist and exportinfo (not exportdata) from udk file
        /// </summary>
        /// <param name="udkFilePath">full path + file name of desired udk file.</param>
        public UDKFile(string udkFilePath, bool fullFileInMemory = false)
        {
            Loaded = true;
            FileName = Path.GetFullPath(udkFilePath);
            using (FileStream udkStream = File.OpenRead(FileName))
            {
                Names = new List<NameEntry>();
                Imports = new List<ImportEntry>();
                Exports = new List<ExportEntry>();

                udkStream.Read(header, 0, header.Length);

                //unsure about magic number. for now just let it try anything
                if (magic != 2653586369)
                {
                    //throw new FormatException("not a udk file");
                }

                //again, unsure of what versions ought to be supported
                if (lowVers != 684 && highVers != 0)
                {
                    //throw new FormatException("unsupported version");
                }

                Stream listsStream;
                listsStream = udkStream;
                headerEnd = NameOffset;

                // fill names list
                listsStream.Seek(NameOffset, SeekOrigin.Begin);
                for (int i = 0; i < NameCount; i++)
                {
                    long currOffset = listsStream.Position;
                    int strLength = listsStream.ReadValueS32();
                    NameEntry n = new NameEntry();
                    if (strLength < 0)
                    {
                        n.name = listsStream.ReadString(strLength * -2, true, Encoding.Unicode); 
                    }
                    else
                    {
                        n.name = listsStream.ReadString(strLength, true, Encoding.ASCII);
                    }
                    n.unk = listsStream.ReadValueS32();
                    n.flags = listsStream.ReadValueS32();
                    Names.Add(n);
                }
                //Debug.WriteLine("Names done. Current offset: "+listsStream.Position);
                //Debug.WriteLine("Import Offset: " + ImportOffset);

                // fill import list
                //Console.Out.WriteLine("IMPORT OFFSET: " + ImportOffset);
                listsStream.Seek(ImportOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[ImportEntry.byteSize];
                for (int i = 0; i < ImportCount; i++)
                {

                    long offset = listsStream.Position;
                    ImportEntry e = new ImportEntry(this, listsStream);
                    Imports.Add(e);
                    //Debug.WriteLine("Read import " + i + " " + e.ObjectName + ", offset: " + offset);
                };

                // fill export list (only the headers, not the data)
                listsStream.Seek(ExportOffset, SeekOrigin.Begin);
                //Console.Out.WriteLine("Export OFFSET: " + ImportOffset);
                for (int i = 0; i < ExportCount; i++)
                {
                    uint expInfoOffset = (uint)listsStream.Position;

                    listsStream.Seek(44, SeekOrigin.Current);
                    int count = listsStream.ReadValueS32();
                    listsStream.Seek(-48, SeekOrigin.Current);

                    int expInfoSize = 68 + (count * 4);
                    buffer = new byte[expInfoSize];

                    listsStream.Read(buffer, 0, buffer.Length);
                    ExportEntry e = new ExportEntry(this, buffer, expInfoOffset);
                    //Debug.WriteLine("Read export " + i + " " + e.ObjectName + ", offset: " + expInfoOffset+ ", size: "+expInfoSize); 
                    Exports.Add(e);
                }
            }
            Debug.WriteLine(getMetadataString());
        }
Example #36
0
        public static void SetCollectionActorLocation(ExportEntry component, float x, float y, float z, List <ExportEntry> collectionitems = null, ExportEntry collectionactor = null)
        {
            if (collectionactor == null)
            {
                if (!(component.HasParent && component.Parent.ClassName.Contains("CollectionActor")))
                {
                    return;
                }
                collectionactor = (ExportEntry)component.Parent;
            }

            collectionitems ??= GetCollectionItems(collectionactor);

            if (collectionitems?.Count > 0)
            {
                var idx = collectionitems.FindIndex(o => o != null && o.UIndex == component.UIndex);
                if (idx >= 0)
                {
                    var binData = (StaticCollectionActor)ObjectBinary.From(collectionactor);

                    Matrix m = binData.LocalToWorldTransforms[idx];
                    m.TranslationVector = new Vector3(x, y, z);
                    binData.LocalToWorldTransforms[idx] = m;

                    collectionactor.WriteBinary(binData);
                }
            }
        }
Example #37
0
        public void addExport(ExportEntry exportEntry)
        {
            if (exportEntry.udkRef != this)
                throw new Exception("you cannot add a new export entry from another udk file, it has invalid references!");

            exportEntry.hasChanged = true;

            //changing data offset in order to append it at the end of the file
            int maxOffset = Exports.Max(entry => entry.DataOffset);
            ExportEntry lastExport = Exports.Find(export => export.DataOffset == maxOffset);
            int lastOffset = lastExport.DataOffset + lastExport.Data.Length;
            exportEntry.DataOffset = lastOffset;

            Exports.Add(exportEntry);
            ExportCount = Exports.Count;
        }
 private bool CanRandomize(ExportEntry export) => export.ClassName == @"BioWaypointSet";
        private void ReadMaterial(ExportEntry export, PackageCache assetCache = null)
        {
            if (export.ClassName == "Material")
            {
                var parsedMaterial = ObjectBinary.From <Material>(export);
                StaticParameterSet = (StaticParameterSet)parsedMaterial.SM3MaterialResource.ID;
                foreach (var v in parsedMaterial.SM3MaterialResource.UniformExpressionTextures)
                {
                    IEntry tex = export.FileRef.GetEntry(v.value);
                    if (tex != null)
                    {
                        Textures.Add(tex);
                    }
                }
            }
            else if (export.ClassName == "RvrEffectsMaterialUser")
            {
                var props = export.GetProperties();
                if (export.GetProperty <ObjectProperty>("m_pBaseMaterial") is ObjectProperty baseProp)
                {
                    // This is an instance... maybe?
                    if (baseProp.Value > 0)
                    {
                        // Local export
                        ReadMaterial(export.FileRef.GetUExport(baseProp.Value));
                    }
                    else
                    {
                        ImportEntry ie            = export.FileRef.GetImport(baseProp.Value);
                        var         externalEntry = EntryImporter.ResolveImport(ie, null, assetCache);
                        if (externalEntry != null)
                        {
                            ReadMaterial(externalEntry);
                        }
                    }
                }
            }
            else if (export.ClassName == "MaterialInstanceConstant")
            {
                if (ObjectBinary.From(export) is MaterialInstance matInstBin)
                {
                    StaticParameterSet = matInstBin.SM3StaticParameterSet;
                }
                //Read Local
                if (export.GetProperty <ArrayProperty <StructProperty> >("TextureParameterValues") is ArrayProperty <StructProperty> textureparams)
                {
                    foreach (var param in textureparams)
                    {
                        var paramValue = param.GetProp <ObjectProperty>("ParameterValue");
                        var texntry    = export.FileRef.GetEntry(paramValue.Value);
                        if (texntry?.ClassName == "Texture2D" && !Textures.Contains(texntry))
                        {
                            Textures.Add(texntry);
                        }
                    }
                }

                if (export.GetProperty <ArrayProperty <ObjectProperty> >("ReferencedTextures") is ArrayProperty <ObjectProperty> textures)
                {
                    foreach (var obj in textures)
                    {
                        var texntry = export.FileRef.GetEntry(obj.Value);
                        if (texntry.ClassName == "Texture2D" && !Textures.Contains(texntry))
                        {
                            Textures.Add(texntry);
                        }
                    }
                }

                //Read parent
                if (export.GetProperty <ObjectProperty>("Parent") is ObjectProperty parentObjProp)
                {
                    // This is an instance... maybe?
                    if (parentObjProp.Value > 0)
                    {
                        // Local export
                        ReadMaterial(export.FileRef.GetUExport(parentObjProp.Value));
                    }
                    else
                    {
                        ImportEntry ie            = export.FileRef.GetImport(parentObjProp.Value);
                        var         externalEntry = ModelPreview.FindExternalAsset(ie, null, null);
                        if (externalEntry != null)
                        {
                            ReadMaterial(externalEntry);
                        }
                    }
                }
            }
        }
Example #40
0
        private static bool CanRandomize(ExportEntry export, out int shiftDirection, out float min, out float max)
        {
            min            = -7;
            max            = 7;
            shiftDirection = -1;
            if (export.IsDefaultObject || export.ClassName != "MorphTarget")
            {
                return(false);
            }

            // Check and setup shift directions.
            var name = export.ObjectName.Name;

            if (name.Contains("eye"))
            {
                shiftDirection = SetupShiftDir("eye");
                min            = -1;
                max            = 5;
                return(true);
            }
            if (name.Contains("jaw"))
            {
                shiftDirection = SetupShiftDir("jaw");
                if (shiftDirection == 0)
                {
                    // in/out
                    min = -5f;
                    max = 20;
                }
                else
                {
                    // up down left right
                    min = -1f;
                    max = 20f;
                }
                return(true);
            }
            if (name.Contains("mouth"))
            {
                shiftDirection = SetupShiftDir("mouth");
                if (shiftDirection == 0)
                {
                    // in/out
                    min = -5f;
                    max = 20;
                }
                else
                {
                    // up down left right
                    min = -5f;
                    max = 5f;
                }
                return(true);
            }
            if (name.Contains("nose"))
            {
                shiftDirection = SetupShiftDir("nose");
                if (shiftDirection == 0)
                {
                    // in/out
                    min = -15f;
                    max = 15;
                }
                else
                {
                    // up down
                    min = -2f;
                    max = 10f;
                }

                return(true);
            }

            // Leave disabled. Doesn't seem to do anything useful
            //if (name.Contains("teeth"))
            //{
            //    shiftDirection = SetupShiftDir("teeth");
            //    min = -5;
            //    max = 5;
            //    return true;
            //}
            Debug.WriteLine($"Ignored thing {name}");
            return(false);
        }
Example #41
0
        public bool SaveToFile(bool forceZlib = false)
        {
            if (forceZlib && compressionType != CompressionType.Zlib)
            {
                modified = true;
            }

            if (packageFile.Length == 0 || !modified)
            {
                return(false);
            }

            MemoryStream tempOutput = new MemoryStream();

            List <ExportEntry> sortedExports = exportsTable.OrderBy(s => s.dataOffset).ToList();

            if (!compressed)
            {
                packageFile.SeekBegin();
                tempOutput.WriteFromStream(packageFile, sortedExports[0].dataOffset);
            }
            else
            {
                packageData.SeekBegin();
                tempOutput.WriteFromStream(packageData, packageData.Length);
            }

            for (int i = 0; i < exportsCount; i++)
            {
                ExportEntry export = sortedExports[i];
                uint        dataLeft;
                tempOutput.JumpTo(export.dataOffset);
                if (i + 1 == exportsCount)
                {
                    dataLeft = exportsEndOffset - export.dataOffset - export.dataSize;
                }
                else
                {
                    dataLeft = sortedExports[i + 1].dataOffset - export.dataOffset - export.dataSize;
                }
                if (export.updatedData)
                {
                    string exportFile = packagePath + "-exports\\exportId-" + export.id;
                    using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read))
                    {
                        tempOutput.WriteFromStream(fs, fs.Length);
                    }
                    export.updatedData = false;
                }
                else if (export.newData != null)
                {
                    tempOutput.WriteFromBuffer(export.newData);
                }
                else
                {
                    getData(export.dataOffset, export.dataSize, tempOutput);
                }
                tempOutput.WriteZeros(dataLeft);
            }

            if (exportsOffset > sortedExports[0].dataOffset)
            {
                if (compressed) // allowed only uncompressed
                {
                    throw new Exception();
                }
                exportsOffset = (uint)tempOutput.Position;
                saveExports(tempOutput);
                exportsEndOffset = (uint)tempOutput.Position;
            }
            else
            {
                tempOutput.JumpTo(exportsOffset);
                saveExports(tempOutput);
            }

            tempOutput.JumpTo(exportsEndOffset);
            if (namesOffset > sortedExports[0].dataOffset)
            {
                if (compressed) // allowed only uncompressed
                {
                    throw new Exception();
                }
                namesOffset = (uint)tempOutput.Position;
                saveNames(tempOutput, true);
            }
            else
            {
                saveNames(tempOutput);
            }

            if (importsOffset > sortedExports[0].dataOffset)
            {
                if (compressed) // allowed only uncompressed
                {
                    throw new Exception();
                }
                importsOffset = (uint)tempOutput.Position;
                saveImports(tempOutput, true);
            }
            else
            {
                saveImports(tempOutput);
            }

            if (namesOffset > sortedExports[0].dataOffset ||
                importsOffset > sortedExports[0].dataOffset ||
                exportsOffset > sortedExports[0].dataOffset)
            {
                tempOutput.SeekBegin();
                tempOutput.Write(packageHeader, 0, packageHeader.Length);
            }
            packageFile.Close();
            if (!memoryMode && Directory.Exists(packagePath + "-exports"))
            {
                Directory.Delete(packagePath + "-exports", true);
            }

            string filename = packageFile.Name;

            using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                if (fs == null)
                {
                    throw new Exception("Failed to write to file: " + filename);
                }

                if (!compressed)
                {
                    tempOutput.SeekBegin();
                    fs.WriteFromStream(tempOutput, tempOutput.Length);
                }
                else
                {
                    if (chunks == null)
                    {
                        chunks = new List <Chunk>();
                    }
                    chunks.Clear();
                    Chunk chunk = new Chunk();
                    chunk.uncomprSize   = sortedExports[0].dataOffset - (uint)dataOffset;
                    chunk.uncomprOffset = (uint)dataOffset;
                    for (int i = 0; i < exportsCount; i++)
                    {
                        ExportEntry export = sortedExports[i];
                        uint        dataSize;
                        if (i + 1 == exportsCount)
                        {
                            dataSize = exportsEndOffset - export.dataOffset;
                        }
                        else
                        {
                            dataSize = sortedExports[i + 1].dataOffset - export.dataOffset;
                        }
                        if (chunk.uncomprSize + dataSize > maxChunkSize)
                        {
                            uint offset = chunk.uncomprOffset + chunk.uncomprSize;
                            chunks.Add(chunk);
                            chunk               = new Chunk();
                            chunk.uncomprSize   = dataSize;
                            chunk.uncomprOffset = offset;
                        }
                        else
                        {
                            chunk.uncomprSize += dataSize;
                        }
                    }
                    chunks.Add(chunk);

                    if (forceZlib)
                    {
                        compressionType = CompressionType.Zlib; // override compression type to Zlib
                    }
                    fs.Write(packageHeader, 0, packageHeader.Length);
                    fs.WriteUInt32((uint)compressionType);
                    fs.WriteUInt32((uint)chunks.Count);
                    uint chunksTableOffset = (uint)fs.Position;
                    fs.Skip(SizeOfChunk * chunks.Count); // skip chunks table - filled later
                    fs.WriteUInt32(someTag);
                    if (version == packageFileVersionME2)
                    {
                        fs.WriteUInt32(0); // const 0
                    }
                    saveExtraNames(fs);

                    for (int c = 0; c < chunks.Count; c++)
                    {
                        chunk             = chunks[c];
                        chunk.comprOffset = (uint)fs.Position;
                        chunk.comprSize   = 0; // filled later

                        uint dataBlockLeft = chunk.uncomprSize;
                        uint newNumBlocks  = (chunk.uncomprSize + maxBlockSize - 1) / maxBlockSize;
                        // skip blocks header and table - filled later
                        fs.Seek(SizeOfChunk + SizeOfChunkBlock * newNumBlocks, SeekOrigin.Current);

                        tempOutput.JumpTo(chunk.uncomprOffset);

                        chunk.blocks = new List <ChunkBlock>();
                        for (int b = 0; b < newNumBlocks; b++)
                        {
                            ChunkBlock block = new ChunkBlock();
                            block.uncomprSize        = Math.Min(maxBlockSize, dataBlockLeft);
                            dataBlockLeft           -= block.uncomprSize;
                            block.uncompressedBuffer = tempOutput.ReadToBuffer(block.uncomprSize);
                            chunk.blocks.Add(block);
                        }

                        if (compressionType == CompressionType.LZO)
                        {
                            for (int b = 0; b < newNumBlocks; b++)
                            {
                                ChunkBlock block = chunk.blocks[b];
                                block.compressedBuffer = LZO2Helper.LZO2.Compress(block.uncompressedBuffer);
                                if (block.compressedBuffer.Length == 0)
                                {
                                    throw new Exception("Compression failed!");
                                }
                                block.comprSize = (uint)block.compressedBuffer.Length;
                                chunk.blocks[b] = block;
                            }
                        }
                        else
                        {
                            Parallel.For(0, chunk.blocks.Count, b =>
                            {
                                ChunkBlock block = chunk.blocks[b];
                                if (compressionType == CompressionType.Zlib)
                                {
                                    block.compressedBuffer = ZlibHelper.Zlib.Compress(block.uncompressedBuffer);
                                }
                                else
                                {
                                    throw new Exception("Compression type not expected!");
                                }
                                if (block.compressedBuffer.Length == 0)
                                {
                                    throw new Exception("Compression failed!");
                                }
                                block.comprSize = (uint)block.compressedBuffer.Length;
                                chunk.blocks[b] = block;
                            });
                        }

                        for (int b = 0; b < newNumBlocks; b++)
                        {
                            ChunkBlock block = chunk.blocks[b];
                            fs.Write(block.compressedBuffer, 0, (int)block.comprSize);
                            chunk.comprSize += block.comprSize;
                        }
                        chunks[c] = chunk;
                    }

                    for (int c = 0; c < chunks.Count; c++)
                    {
                        chunk = chunks[c];
                        fs.JumpTo(chunksTableOffset + c * SizeOfChunk); // jump to chunks table
                        fs.WriteUInt32(chunk.uncomprOffset);
                        fs.WriteUInt32(chunk.uncomprSize);
                        fs.WriteUInt32(chunk.comprOffset);
                        fs.WriteUInt32(chunk.comprSize + SizeOfChunk + SizeOfChunkBlock * (uint)chunk.blocks.Count);
                        fs.JumpTo(chunk.comprOffset); // jump to blocks header
                        fs.WriteUInt32(packageTag);
                        fs.WriteUInt32(maxBlockSize);
                        fs.WriteUInt32(chunk.comprSize);
                        fs.WriteUInt32(chunk.uncomprSize);
                        foreach (ChunkBlock block in chunk.blocks)
                        {
                            fs.WriteUInt32(block.comprSize);
                            fs.WriteUInt32(block.uncomprSize);
                        }
                    }
                    for (int c = 0; c < chunks.Count; c++)
                    {
                        chunk = chunks[c];
                        chunk.blocks.Clear();
                        chunk.blocks = null;
                    }
                    chunks.Clear();
                    chunks = null;
                }
            }

            tempOutput.Close();
            tempOutput.Dispose();

            return(true);
        }
Example #42
0
 public static void ReadExports()
 {
     int pos = header.ExportOffset;
     exportlist = new List<ExportEntry>();
     int unkc;
     for (int i = 0; i < header.ExportCount; i++)
     {
         ExportEntry e = new ExportEntry();
         e.Class = GetInt(pos);
         e.Link = GetInt(pos + 8);
         e.Name = GetInt(pos + 12);
         e.DataSize = GetInt(pos + 36);
         e.DataOffset = GetInt(pos + 40);
         e.Offset = pos;
         unkc = GetInt(pos + 44);
         pos += 0x44 + unkc * 12;
         exportlist.Add(e);
     }
 }
Example #43
0
 private void ReadExports(FileStream fs)
 {
     fs.Seek(ExportOffset, SeekOrigin.Begin);
     int pos = ExportOffset;
     Exports = new List<ExportEntry>();
     for (int i = 0; i < ExportCount; i++)
     {
         int start = pos;
         int clas = ReadInt32(fs, pos);
         pos += 8;
         int link = ReadInt32(fs, pos);
         pos += 4;
         int name = ReadInt32(fs, pos);
         pos += 16;
         int flags = ReadInt32(fs, pos);
         pos += 4;
         int size = ReadInt32(fs, pos);
         pos += 4;
         int offset = ReadInt32(fs, pos);
         pos += 8;
         int count = ReadInt32(fs, pos);
         pos += 24 + count * 4;
         int len = pos - start;
         byte[] buff = new byte[len];
         fs.Seek(start, SeekOrigin.Begin);
         for (int j = 0; j < len; j++)
             buff[j] = (byte)fs.ReadByte();
         byte[] buff2 = new byte[size];
         fs.Seek(offset, SeekOrigin.Begin);
         for (int j = 0; j < size; j++)
             buff2[j] = (byte)fs.ReadByte();
         byte[] buff3 = new byte[size];
         for (int j = 0; j < size; j++)
             buff3[j] = buff2[j];
         ExportEntry e = new ExportEntry();
         e.clas = clas;
         e.link = link;
         e.name = name;
         e.flags = flags;
         e.size = size;
         e.offset = offset;
         e.raw = buff;
         e.data = buff2;
         e.olddata = buff3;
         e.IsChanged = false;
         Exports.Add(e);
     }
 }
Example #44
0
 public static void CreateOutputLink(ExportEntry source, string outLinkDescription, ExportEntry destExport, int inputIndex = 0)
 {
     if (source.GetProperty <ArrayProperty <StructProperty> >("OutputLinks") is { } outLinksProp)
     {
         foreach (var prop in outLinksProp)
         {
             if (prop.GetProp <StrProperty>("LinkDesc") == outLinkDescription)
             {
                 var linksProp = prop.GetProp <ArrayProperty <StructProperty> >("Links");
                 linksProp.Add(new StructProperty("SeqOpOutputInputLink", false,
                                                  new ObjectProperty(destExport, "LinkedOp"),
                                                  new IntProperty(inputIndex, "InputLinkIdx")));
                 source.WriteProperty(outLinksProp);
                 return;
             }
         }
     }
 }
Example #45
0
 public static void CreateVariableLink(ExportEntry src, string linkDescription, ExportEntry dest)
 {
     if (src.GetProperty <ArrayProperty <StructProperty> >("VariableLinks") is { } varLinksProp)
     {
         foreach (var prop in varLinksProp)
         {
             if (prop.GetProp <StrProperty>("LinkDesc") == linkDescription)
             {
                 prop.GetProp <ArrayProperty <ObjectProperty> >("LinkedVariables").Add(new ObjectProperty(dest));
                 src.WriteProperty(varLinksProp);
             }
         }
     }
 }
Example #46
0
 private void ReadExportTable()
 {
     try
     {
         DebugLog.PrintLn("Reading Export Table...");
         Exports = new List<ExportEntry>();
         if (GeneralInfo.compressed)
         {
             UncompressRange(Header._offsetCompFlagEnd + 0xC, Header.HeaderLength - (Header._offsetCompFlagEnd + 0xC));
             Header.DeCompBuffer.Seek(Header.ExportOffset, 0);
             for (int i = 0; i < Header.ExportCount; i++)
             {
                 ExportEntry e = new ExportEntry();
                 e.idxClass = ReadInt(Header.DeCompBuffer);
                 e.idxParent = ReadInt(Header.DeCompBuffer);
                 e.idxLink = ReadInt(Header.DeCompBuffer);
                 e.idxName = ReadInt(Header.DeCompBuffer);
                 e.Index = ReadInt(Header.DeCompBuffer);
                 e.idxArchetype = ReadInt(Header.DeCompBuffer);
                 e.Unk1 = ReadInt(Header.DeCompBuffer);
                 e.ObjectFlags = ReadInt(Header.DeCompBuffer);
                 e.Datasize = ReadInt(Header.DeCompBuffer);
                 e.Dataoffset = ReadInt(Header.DeCompBuffer);
                 long pos = Header.DeCompBuffer.Position;
                 if (!GeneralInfo.loadfull)
                     e.DataLoaded = false;
                 else
                 {
                     e.Data = GetObjectData(e.Dataoffset, e.Datasize);
                     e.DataLoaded = true;
                 }
                 Header.DeCompBuffer.Seek(pos, 0);
                 e.Unk2 = ReadInt(Header.DeCompBuffer);
                 int count = ReadInt(Header.DeCompBuffer);
                 e.Unk3 = new int[count];
                 for (int j = 0; j < count; j++)
                     e.Unk3[j] = ReadInt(Header.DeCompBuffer);
                 e.Unk4 = ReadInt(Header.DeCompBuffer);
                 e.Unk5 = ReadInt(Header.DeCompBuffer);
                 e.Unk6 = ReadInt(Header.DeCompBuffer);
                 e.Unk7 = ReadInt(Header.DeCompBuffer);
                 e.Unk8 = ReadInt(Header.DeCompBuffer);
                 Exports.Add(e);
             }
         }
         else
         {
             Source.Seek(Header.ExportOffset, 0);
             for (int i = 0; i < Header.ExportCount; i++)
             {
                 ExportEntry e = new ExportEntry();
                 e.idxClass = ReadInt(Source);
                 e.idxParent = ReadInt(Source);
                 e.idxLink = ReadInt(Source);
                 e.idxName = ReadInt(Source);
                 e.Index = ReadInt(Source);
                 e.idxArchetype = ReadInt(Source);
                 e.Unk1 = ReadInt(Source);
                 e.ObjectFlags = ReadInt(Source);
                 e.Datasize = ReadInt(Source);
                 e.Dataoffset = ReadInt(Source);
                 long pos = Source.Position;
                 if (!GeneralInfo.loadfull)
                     e.DataLoaded = false;
                 else
                 {
                     e.Data = GetObjectData(e.Dataoffset, e.Datasize);
                     e.DataLoaded = true;
                 }
                 Source.Seek(pos, 0);
                 e.Unk2 = ReadInt(Source);
                 int count = ReadInt(Source);
                 e.Unk3 = new int[count];
                 for (int j = 0; j < count; j++)
                     e.Unk3[j] = ReadInt(Source);
                 e.Unk4 = ReadInt(Source);
                 e.Unk5 = ReadInt(Source);
                 e.Unk6 = ReadInt(Source);
                 e.Unk7 = ReadInt(Source);
                 e.Unk8 = ReadInt(Source);
                 Exports.Add(e);
             }
         }
         DebugLog.PrintLn("Done.");
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::READEXPORTTABLE ERROR:\n" + ex.Message);
     }
 }