private static Type getType(PCCObject pcc, int type)
        {
            switch (pcc.getNameEntry(type))
            {
            case "None": return(Type.None);

            case "StructProperty": return(Type.StructProperty);

            case "IntProperty": return(Type.IntProperty);

            case "FloatProperty": return(Type.FloatProperty);

            case "ObjectProperty": return(Type.ObjectProperty);

            case "NameProperty": return(Type.NameProperty);

            case "BoolProperty": return(Type.BoolProperty);

            case "ByteProperty": return(Type.ByteProperty);

            case "ArrayProperty": return(Type.ArrayProperty);

            case "DelegateProperty": return(Type.DelegateProperty);

            case "StrProperty": return(Type.StrProperty);

            case "StringRefProperty": return(Type.StringRefProperty);

            default:
                return(Type.Unknown);
            }
        }
Esempio n. 2
0
 public ExportEntry(PCCObject pccFile, byte[] importData, uint exportOffset)
 {
     pccRef     = pccFile;
     header     = (byte[])importData.Clone();
     offset     = exportOffset;
     hasChanged = false;
 }
        private static ClassInfo generateClassInfo(int index, PCCObject pcc)
        {
            ClassInfo info = new ClassInfo();

            info.baseClass   = pcc.Exports[index].ClassParent;
            info.exportIndex = index;
            info.pccPath     = new string(pcc.pccFileName.Skip(pcc.pccFileName.LastIndexOf("BIOGame") + 8).ToArray());
            foreach (PCCObject.ExportEntry entry in pcc.Exports)
            {
                if (entry.idxLink - 1 == index && entry.ClassName != "ScriptStruct" && entry.ClassName != "Enum" &&
                    entry.ClassName != "Function" && entry.ClassName != "Const" && entry.ClassName != "State")
                {
                    //Skip if property is transient (only used during execution, will never be in game files)
                    if ((BitConverter.ToUInt64(entry.Data, 24) & 0x0000000000002000) == 0 && !info.properties.ContainsKey(entry.ObjectName))
                    {
                        PropertyInfo p = getProperty(pcc, entry);
                        if (p != null)
                        {
                            info.properties.Add(entry.ObjectName, p);
                        }
                    }
                }
            }
            return(info);
        }
Esempio n. 4
0
 public Function(byte[] raw, PCCObject Pcc)
 {
     pcc = Pcc;
     memory = raw;
     memsize = raw.Length;
     flagint = GetFlagInt();
     nativeindex = GetNatIdx();
     Deserialize();
 }
 public Function(byte[] raw, PCCObject Pcc)
 {
     pcc         = Pcc;
     memory      = raw;
     memsize     = raw.Length;
     flagint     = GetFlagInt();
     nativeindex = GetNatIdx();
     Deserialize();
 }
        public static Property getPropOrNull(PCCObject pcc, PCCObject.ExportEntry export, string propName)
        {
            List <Property> props = getPropList(pcc, export);

            foreach (Property prop in props)
            {
                if (pcc.getNameEntry(prop.Name) == propName)
                {
                    return(prop);
                }
            }
            return(null);
        }
        public static Property getPropOrNull(PCCObject pcc, byte[] data, int start, string propName)
        {
            List <Property> props = ReadProp(pcc, data, 0);

            foreach (Property prop in props)
            {
                if (pcc.getNameEntry(prop.Name) == propName)
                {
                    return(prop);
                }
            }
            return(null);
        }
Esempio n. 8
0
        public SFXEnum(PCCObject pcc, byte[] data)
        {
            this.pcc = pcc;
            this.data = data;
            numItems = BitConverter.ToInt32(data, 20);

            int i = 0;
            while (i < numItems)
            {
                int nameindex = BitConverter.ToInt32(data, i * 8 + 24);
                i++;
                names.Add(pcc.Names[nameindex]);
            }
        }
        public SFXEnum(PCCObject pcc, byte[] data)
        {
            this.pcc  = pcc;
            this.data = data;
            numItems  = BitConverter.ToInt32(data, 20);

            int i = 0;

            while (i < numItems)
            {
                int nameindex = BitConverter.ToInt32(data, i * 8 + 24);
                i++;
                names.Add(pcc.Names[nameindex]);
            }
        }
        //call this method to regenerate ME3ObjectInfo.json
        //Takes a long time (~5 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo()
        {
            PCCObject pcc;
            string    path = TransplanterLib.GamePath;

            string[] files = Directory.GetFiles(path, "*.pcc", SearchOption.AllDirectories);
            string   objectName;
            int      length = files.Length;

            for (int i = 0; i < length; i++)
            {
                if (files[i].ToLower().EndsWith(".pcc"))
                {
                    pcc = new PCCObject(files[i]);
                    for (int j = 0; j < pcc.Exports.Count; j++)
                    {
                        if (pcc.Exports[j].ClassName == "Enum")
                        {
                            generateEnumValues(j, pcc);
                        }
                        else if (pcc.Exports[j].ClassName == "Class")
                        {
                            objectName = pcc.Exports[j].ObjectName;
                            if (!Classes.ContainsKey(objectName))
                            {
                                Classes.Add(objectName, generateClassInfo(j, pcc));
                            }
                            if ((objectName.Contains("SeqAct") || objectName.Contains("SeqCond") || objectName.Contains("SequenceLatentAction") ||
                                 objectName == "SequenceOp" || objectName == "SequenceAction" || objectName == "SequenceCondition") && !SequenceObjects.ContainsKey(objectName))
                            {
                                SequenceObjects.Add(objectName, generateSequenceObjectInfo(j, pcc));
                            }
                        }
                        else if (pcc.Exports[j].ClassName == "ScriptStruct")
                        {
                            objectName = pcc.Exports[j].ObjectName;
                            if (!Structs.ContainsKey(objectName))
                            {
                                Structs.Add(objectName, generateClassInfo(j, pcc));
                            }
                        }
                    }
                }
                System.Diagnostics.Debug.WriteLine($"{i} of {length} processed");
            }
            File.WriteAllText(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase) + "//ME3ObjectInfo.json",
                              JsonConvert.SerializeObject(new { SequenceObjects = SequenceObjects, Classes = Classes, Structs = Structs, Enums = Enums }));
        }
        public static string PropertyToText(Property p, PCCObject pcc)
        {
            string s = "";

            s  = "Name: " + pcc.Names[p.Name];
            s += " | Type: " + TypeToString((int)p.TypeVal);
            s += " | Size: " + p.Value.len.ToString();
            switch (p.TypeVal)
            {
            case Type.StructProperty:
                s += " \"" + pcc.getNameEntry(p.Value.IntValue) + "\" with " + p.Value.Array.Count.ToString() + " bytes";
                break;

            case Type.IntProperty:
            case Type.ObjectProperty:
            case Type.BoolProperty:
            case Type.StringRefProperty:
                s += " Value: " + p.Value.IntValue.ToString();
                break;

            case Type.FloatProperty:
                byte[] buff = BitConverter.GetBytes(p.Value.IntValue);
                float  f    = BitConverter.ToSingle(buff, 0);
                s += " | Value: " + f.ToString();
                break;

            case Type.NameProperty:
                s += " " + pcc.Names[p.Value.IntValue];
                break;

            case Type.ByteProperty:
                s += " | Value: \"" + p.Value.StringValue + "\" with \"" + pcc.getNameEntry(p.Value.IntValue) + "\"";
                break;

            case Type.ArrayProperty:
                s += " bytes";     //Value: " + p.Value.Array.Count.ToString() + " Elements";
                break;

            case Type.StrProperty:
                if (p.Value.StringValue.Length == 0)
                {
                    break;
                }
                s += " Value: " + p.Value.StringValue.Substring(0, p.Value.StringValue.Length - 1);
                break;
            }
            return(s);
        }
        private static void generateEnumValues(int index, PCCObject pcc)
        {
            string enumName = pcc.Exports[index].ObjectName;

            if (!Enums.ContainsKey(enumName))
            {
                List <string> values = new List <string>();
                byte[]        buff   = pcc.Exports[index].Data;
                //subtract 1 so that we don't get the MAX value, which is an implementation detail
                int count = BitConverter.ToInt32(buff, 20) - 1;
                for (int i = 0; i < count; i++)
                {
                    values.Add(pcc.Names[BitConverter.ToInt32(buff, 24 + i * 8)]);
                }
                Enums.Add(enumName, values);
            }
        }
        public static int detectStart(PCCObject pcc, byte[] raw, long flags)
        {
            if ((flags & (long)UnrealFlags.EObjectFlags.HasStack) != 0)
            {
                return(30);
            }
            int result = 8;
            int test1  = BitConverter.ToInt32(raw, 4);
            int test2  = BitConverter.ToInt32(raw, 8);

            if (pcc.isName(test1) && test2 == 0)
            {
                result = 4;
            }
            if (pcc.isName(test1) && pcc.isName(test2) && test2 != 0)
            {
                result = 8;
            }
            return(result);
        }
        /// <summary>
        /// Replaces the data for an export with the data for a SWF (GFX) file.
        /// </summary>
        /// <param name="ent">Export Entry to update data for</param>
        /// <param name="swf_path">SWF file to use as new data. This technically will work with any file.</param>
        static void replace_swf_file(PCCObject.ExportEntry ent, string swf_path)
        {
            byte[] swf_file = File.ReadAllBytes(swf_path);
            byte[] header = copyByteChunk(ent.Data, 0, 20);
            byte[] number1 = System.BitConverter.GetBytes(swf_file.Length + 4);
            byte[] filler = copyByteChunk(ent.Data, 24, 4);
            byte[] number2 = System.BitConverter.GetBytes(swf_file.Length);

            int originalSize = System.BitConverter.ToInt32(ent.Data, 28);

            byte[] bytefooter = copyByteChunk(ent.Data, 32 + originalSize, ent.Data.Length - 32 - originalSize);

            MemoryStream m = new MemoryStream();
            //updating array metadata, length, datasize
            for (int i = 0; i < header.Length; i++)
                m.WriteByte(header[i]);

            for (int i = 0; i < number1.Length; i++)
                m.WriteByte(number1[i]);

            for (int i = 0; i < filler.Length; i++)
                m.WriteByte(filler[i]);

            for (int i = 0; i < number2.Length; i++)
                m.WriteByte(number2[i]);

            //set swf binary data
            for (int i = 0; i < swf_file.Length; i++)
                m.WriteByte(swf_file[i]);

            //write remaining footer data that was there originally
            for (int i = 0; i < bytefooter.Length; i++)
                m.WriteByte(bytefooter[i]);
            byte[] newdata = m.ToArray();
            Console.WriteLine("newdata size vs old: " + newdata.Length + " vs " + ent.Data.Length);
            ent.Data = m.ToArray();
            Console.WriteLine("Export has changed: " + ent.hasChanged);
            // ent.DataSize = ent.Data.Length;
        }
        private static PropertyValue ReadValue(PCCObject pcc, byte[] raw, int start, int type)
        {
            PropertyValue v = new PropertyValue();

            switch (pcc.Names[type])
            {
            case "IntProperty":
            case "FloatProperty":
            case "ObjectProperty":
            case "StringRefProperty":
                v.IntValue = BitConverter.ToInt32(raw, start);
                v.len      = 4;
                break;

            case "NameProperty":
                v.IntValue = BitConverter.ToInt32(raw, start);
                var nameRef = new NameReference();
                nameRef.index = v.IntValue;
                nameRef.count = BitConverter.ToInt32(raw, start + 4);
                nameRef.Name  = pcc.getNameEntry(nameRef.index);
                if (nameRef.count > 0)
                {
                    nameRef.Name += "_" + (nameRef.count - 1);
                }
                v.NameValue = nameRef;
                v.len       = 8;
                break;

            case "BoolProperty":
                if (start < raw.Length)
                {
                    v.IntValue = raw[start];
                }
                v.len = 1;
                break;
            }
            return(v);
        }
        private static SequenceObjectInfo generateSequenceObjectInfo(int i, PCCObject pcc)
        {
            SequenceObjectInfo info = new SequenceObjectInfo();

            PropertyReader.Property inputLinks = PropertyReader.getPropOrNull(pcc, pcc.Exports[i + 1], "InputLinks");
            if (inputLinks != null)
            {
                int    pos    = 28;
                byte[] global = inputLinks.raw;
                int    count  = BitConverter.ToInt32(global, 24);
                for (int j = 0; j < count; j++)
                {
                    List <PropertyReader.Property> p2 = PropertyReader.ReadProp(pcc, global, pos);

                    info.inputLinks.Add(p2[0].Value.StringValue);
                    for (int k = 0; k < p2.Count(); k++)
                    {
                        pos += p2[k].raw.Length;
                    }
                }
            }
            return(info);
        }
        public static CustomProperty PropertyToGrid(Property p, PCCObject pcc)
        {
            string         cat = p.TypeVal.ToString();
            CustomProperty pg;
            NameProp       pp;

            switch (p.TypeVal)
            {
            case Type.BoolProperty:
                pg = new CustomProperty(pcc.Names[p.Name], cat, (p.Value.IntValue == 1), typeof(bool), false, true);
                break;

            case Type.FloatProperty:
                byte[] buff = BitConverter.GetBytes(p.Value.IntValue);
                float  f    = BitConverter.ToSingle(buff, 0);
                pg = new CustomProperty(pcc.Names[p.Name], cat, f, typeof(float), false, true);
                break;

            case Type.ByteProperty:
                if (p.Size != 8)
                {
                    pg = new CustomProperty(pcc.Names[p.Name], cat, (byte)p.Value.IntValue, typeof(byte), false, true);
                }
                else
                {
                    pp           = new NameProp();
                    pp.name      = pcc.getNameEntry(p.Value.IntValue);
                    pp.nameindex = p.Value.IntValue;
                    pg           = new CustomProperty(pcc.Names[p.Name], cat, pp, typeof(NameProp), false, true);
                }
                break;

            case Type.NameProperty:
                pp           = new NameProp();
                pp.name      = pcc.getNameEntry(p.Value.IntValue);
                pp.nameindex = p.Value.IntValue;
                pg           = new CustomProperty(pcc.Names[p.Name], cat, pp, typeof(NameProp), false, true);
                break;

            case Type.ObjectProperty:
                ObjectProp ppo = new ObjectProp();
                ppo.objectName = pcc.getObjectName(p.Value.IntValue);
                ppo.index      = p.Value.IntValue;
                pg             = new CustomProperty(pcc.Names[p.Name], cat, ppo, typeof(ObjectProp), false, true);
                break;

            case Type.StrProperty:
                pg = new CustomProperty(pcc.Names[p.Name], cat, p.Value.StringValue, typeof(string), false, true);
                break;

            case Type.ArrayProperty:
                pg = new CustomProperty(pcc.Names[p.Name], cat, BitConverter.ToInt32(p.raw, 24) + " elements", typeof(string), false, true);
                break;

            case Type.StructProperty:
                string structType = pcc.getNameEntry(p.Value.IntValue);
                if (structType == "Color")
                {
                    ColorProp cp = new ColorProp();
                    cp.name      = structType;
                    cp.nameindex = p.Value.IntValue;
                    System.Drawing.Color color = System.Drawing.Color.FromArgb(BitConverter.ToInt32(p.raw, 32));
                    cp.Alpha = color.A;
                    cp.Red   = color.R;
                    cp.Green = color.G;
                    cp.Blue  = color.B;
                    pg       = new CustomProperty(pcc.Names[p.Name], cat, cp, typeof(ColorProp), false, true);
                }
                else if (structType == "Vector")
                {
                    VectorProp vp = new VectorProp();
                    vp.name      = structType;
                    vp.nameindex = p.Value.IntValue;
                    vp.X         = BitConverter.ToSingle(p.raw, 32);
                    vp.Y         = BitConverter.ToSingle(p.raw, 36);
                    vp.Z         = BitConverter.ToSingle(p.raw, 40);
                    pg           = new CustomProperty(pcc.Names[p.Name], cat, vp, typeof(VectorProp), false, true);
                }
                else if (structType == "Rotator")
                {
                    RotatorProp rp = new RotatorProp();
                    rp.name      = structType;
                    rp.nameindex = p.Value.IntValue;
                    rp.Pitch     = (float)BitConverter.ToInt32(p.raw, 32) * 360f / 65536f;
                    rp.Yaw       = (float)BitConverter.ToInt32(p.raw, 36) * 360f / 65536f;
                    rp.Roll      = (float)BitConverter.ToInt32(p.raw, 40) * 360f / 65536f;
                    pg           = new CustomProperty(pcc.Names[p.Name], cat, rp, typeof(RotatorProp), false, true);
                }
                else if (structType == "LinearColor")
                {
                    LinearColorProp lcp = new LinearColorProp();
                    lcp.name      = structType;
                    lcp.nameindex = p.Value.IntValue;
                    lcp.Red       = BitConverter.ToSingle(p.raw, 32);
                    lcp.Green     = BitConverter.ToSingle(p.raw, 36);
                    lcp.Blue      = BitConverter.ToSingle(p.raw, 40);
                    lcp.Alpha     = BitConverter.ToSingle(p.raw, 44);
                    pg            = new CustomProperty(pcc.Names[p.Name], cat, lcp, typeof(VectorProp), false, true);
                }
                else
                {
                    StructProp ppp = new StructProp();
                    ppp.name      = structType;
                    ppp.nameindex = p.Value.IntValue;
                    byte[] buf = new byte[p.Value.Array.Count()];
                    for (int i = 0; i < p.Value.Array.Count(); i++)
                    {
                        buf[i] = (byte)p.Value.Array[i].IntValue;
                    }
                    List <int> buf2 = new List <int>();
                    for (int i = 0; i < p.Value.Array.Count() / 4; i++)
                    {
                        buf2.Add(BitConverter.ToInt32(buf, i * 4));
                    }
                    ppp.data = buf2.ToArray();
                    pg       = new CustomProperty(pcc.Names[p.Name], cat, ppp, typeof(StructProp), false, true);
                }
                break;

            default:
                pg = new CustomProperty(pcc.Names[p.Name], cat, p.Value.IntValue, typeof(int), false, true);
                break;
            }
            return(pg);
        }
        public static List <Property> getPropList(PCCObject pcc, PCCObject.ExportEntry export)
        {
            int start = detectStart(pcc, export.Data, export.ObjectFlags);

            return(ReadProp(pcc, export.Data, start));
        }
        public static void ImportImmutableProperty(PCCObject pcc, PCCObject importpcc, Property p, string className, System.IO.MemoryStream m, bool inStruct = false)
        {
            string name = importpcc.getNameEntry(p.Name);
            int idxname = pcc.FindNameOrAdd(name);
            if (name == "None")
                return;
            string type = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 8));
            int idxtype = pcc.FindNameOrAdd(type);
            string name2;
            int idxname2;
            int size, count, pos;
            List<Property> Props;
            switch (type)
            {
                case "IntProperty":
                case "FloatProperty":
                case "ObjectProperty":
                case "StringRefProperty":
                    m.Write(BitConverter.GetBytes(p.Value.IntValue), 0, 4);
                    break;
                case "NameProperty":
                    m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                    //preserve index or whatever the second part of a namereference is
                    m.Write(p.raw, 28, 4);
                    break;
                case "BoolProperty":
                    m.WriteByte((byte)p.Value.IntValue);
                    break;
                case "BioMask4Property":
                    m.WriteByte((byte)p.Value.IntValue);
                    break;
                case "ByteProperty":
                    name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                    idxname2 = pcc.FindNameOrAdd(name2);
                    if (p.Size == 8)
                    {
                        m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                        m.Write(new byte[4], 0, 4);
                    }
                    else
                    {
                        m.WriteByte(p.raw[32]);
                    }
                    break;
                case "StrProperty":
                    name2 = p.Value.StringValue;
                    m.Write(BitConverter.GetBytes(-name2.Length), 0, 4);
                    foreach (char c in name2)
                    {
                        m.WriteByte((byte)c);
                        m.WriteByte(0);
                    }
                    break;
                case "StructProperty":
                    size = BitConverter.ToInt32(p.raw, 16);
                    name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                    idxname2 = pcc.FindNameOrAdd(name2);
                    pos = 32;
                    Props = new List<Property>();
                    try
                    {
                        Props = ReadProp(importpcc, p.raw, pos);
                    }
                    catch (Exception)
                    {
                    }
                    if (Props.Count == 0 || Props[0].TypeVal == Type.Unknown)
                    {
                        for (int i = 0; i < size; i++)
                            m.WriteByte(p.raw[32 + i]);
                    }
                    else
                    {
                        foreach (Property pp in Props)
                            ImportImmutableProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                    break;
                case "ArrayProperty":
                    size = BitConverter.ToInt32(p.raw, 16);
                    count = BitConverter.ToInt32(p.raw, 24);
                    UnrealObjectInfo.ArrayType arrayType = UnrealObjectInfo.getArrayType(className, importpcc.getNameEntry(p.Name), inStruct);
                    pos = 28;
                    List<Property> AllProps = new List<Property>();

                    if (arrayType == UnrealObjectInfo.ArrayType.Struct)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            Props = new List<Property>();
                            try
                            {
                                Props = ReadProp(importpcc, p.raw, pos);
                            }
                            catch (Exception)
                            {
                            }
                            AllProps.AddRange(Props);
                            if (Props.Count != 0)
                            {
                                pos = Props[Props.Count - 1].offend;
                            }
                        }
                    }
                    m.Write(BitConverter.GetBytes(count), 0, 4);
                    if (AllProps.Count != 0)
                    {
                        foreach (Property pp in AllProps)
                            ImportImmutableProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                    else if (arrayType == UnrealObjectInfo.ArrayType.Name)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            string s = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28 + i * 8));
                            m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(s)), 0, 4);
                            //preserve index or whatever the second part of a namereference is
                            m.Write(p.raw, 32 + i * 8, 4);
                        }
                    }
                    else
                    {
                        m.Write(p.raw, 28, size - 4);
                    }
                    break;
                default:
                case "DelegateProperty":
                    throw new NotImplementedException(type);
            }
        }
Esempio n. 20
0
 public ImportEntry(PCCObject pccFile, Stream importData)
 {
     pccRef = pccFile;
     header = new byte[ImportEntry.byteSize];
     importData.Read(header, 0, header.Length);
 }
        public static void dumpModMakerWeaponDynamicSQL(string filepath)
        {
            string[] files = Directory.GetFiles(filepath,"*.pcc");
            foreach (String path in files)
            {
                string fname = Path.GetFileName(path);
                if (!fname.StartsWith("SFXWeapon_")) continue;
                string module = "UNDEFINED";
                string pathstr = "UNDEFINED";
                if (path.ToUpper().Contains("\\DLC\\DLC_CON_"))
                {
                    string dlcid = path.Substring(path.IndexOf("\\DLC\\DLC_CON_") + 13);
                    int endindex = dlcid.IndexOf("\\");
                    dlcid = dlcid.Substring(0, endindex).ToUpper();


                    switch (dlcid)
                    {
                        case "MP1":
                            module = "RESURGENCE";
                            pathstr = "/BIOGame/DLC/DLC_CON_MP1/CookedPCConsole/" + Path.GetFileName(path);
                            break;
                        case "MP2":
                            module = "REBELLION";
                            pathstr = "/BIOGame/DLC/DLC_CON_MP2/CookedPCConsole/" + Path.GetFileName(path);
                            break;
                        case "MP3":
                            module = "EARTH";
                            pathstr = "/BIOGame/DLC/DLC_CON_MP3/CookedPCConsole/" + Path.GetFileName(path);
                            break;
                        case "MP4":
                            module = "RETALIATION";
                            pathstr = "/BIOGame/DLC/DLC_CON_MP4/CookedPCConsole/" + Path.GetFileName(path);
                            break;
                        case "MP5":
                            module = "RECKONING";
                            pathstr = "/BIOGame/DLC/DLC_CON_MP5/CookedPCConsole/" + Path.GetFileName(path);
                            break;
                    }
                }

                PCCObject pcc = new PCCObject(path);
                try
                {
                    string savepath = Path.GetFileNameWithoutExtension(path) + ".sql";
                    using (StreamWriter stringoutput = new StreamWriter(Directory.GetParent(path) + "\\"+ savepath))
                    {
                        Console.WriteLine("outputting to " + Directory.GetParent(path) + savepath);
                        int numDone = 1;
                        int numTotal = pcc.Exports.Count;
                        int lastProgress = 0;
                        writeVerboseLine("Enumerating exports");
                        Boolean needsFlush = false;
                        int index = 0;
                        foreach (PCCObject.ExportEntry exp in pcc.Exports)
                        {
                            index++;
                            //filter
                            switch (exp.ObjectName)
                            {
                                case "AnimNodeSequence":
                                case "BioAnimNodeSequenceMirror":
                                    continue;
                            }

                            if (exp.PackageFullName.StartsWith("EffectsMaterials"))
                            {
                                continue;
                            }

                            if (exp.PackageFullName.ToUpper().StartsWith("BIOG"))
                            {
                                continue;
                            }

                            if (exp.PackageFullName.ToUpper().StartsWith("BIOVFX"))
                            {
                                continue;
                            }

                            if (exp.PackageFullName.ToUpper().StartsWith("WWISE"))
                            {
                                continue;
                            }

                            if (exp.PackageFullName.ToUpper().StartsWith("GUI_SF"))
                            {
                                continue;
                            }

                            if (!exp.ObjectName.Contains("Default__SFXWeapon"))
                            {
                                continue;
                            }
                            if (!exp.ObjectName.Contains(Path.GetFileNameWithoutExtension(path)))
                            {
                                continue;
                            }


                            List<PropertyReader.Property> p;
                            Console.WriteLine("Reading props from export: " + exp.PackageFullName + "." + exp.ObjectName);
                            string catname = exp.ObjectName.Substring(19);
                            p = PropertyReader.getPropList(pcc, exp);
                            string[] lockoutpropnames = { "Damage", "StatBarDamage" };
                            if (p.Count > 0)
                            {
                                Boolean isfirst = true;
                                foreach (Property pr in p)
                                {
                                    if (pr.TypeVal == PropertyReader.Type.StructProperty)
                                    {
                                        //int idx = BitConverter.ToInt32(exp.Data, pr.offsetval + 24);
                                        string structtype = pcc.getNameEntry(pr.Value.IntValue);
                                        //Console.Write(pcc.getNameEntry(pr.Name) + " - " + structtype);
                                        switch (structtype)
                                        {
                                            case "ScaledFloat":
                                                //Console.WriteLine("prop offset: " + (pr.offsetval + 0x38).ToString("X8"));
                                                double x = BitConverter.ToSingle(exp.Data, pr.offsetval + 4 + 0x1C);
                                                double y = BitConverter.ToSingle(exp.Data, pr.offsetval + 4 + 0x1C * 2);
                                                //Console.WriteLine(" " + x.ToString("0.0######") + " to " + y.ToString("0.0######"));

                                                stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'" + catname + " - " + pcc.getNameEntry(pr.Name) + " Level 1'," +
                                            "'Defines " + pcc.getNameEntry(pr.Name) + " per pellet for " + catname + ".', 'HINT', '" + module + "', '" + pathstr + "', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                            "0x" + (pr.offsetval + 4 + 0x1C + exp.DataOffset).ToString("X8") + ",3,null,null,null," + x.ToString("0.0####") + ",null,null,null,null,null,null,0,null,1001, 0);");

                                                stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'" + catname + " - " + pcc.getNameEntry(pr.Name) + " Level 10'," +
                                            "'Defines " + pcc.getNameEntry(pr.Name) + " per pellet for " + catname + ".', 'HINT', '" + module + "', '" + pathstr + "', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                            "0x" + (pr.offsetval + 4 + 0x1C * 2 + exp.DataOffset).ToString("X8") + ",3,null,null,null," + y.ToString("0.0####") + ",null,null,null,null,null,null,0,null,1001, 0);");
                                                break;
                                        }
                                    }

                                    continue;
                                    if (pr.TypeVal == PropertyReader.Type.FloatProperty)
                                    {
                                        if (isfirst)
                                        {
                                            stringoutput.WriteLine(" -- EXPORT #" + index + " " + exp.PackageFullName + "." + exp.ObjectName);
                                            isfirst = false;
                                        }
                                        Console.WriteLine("FLOAT PROPERTY: " + pcc.getNameEntry(pr.Name) + " at 0x" + (pr.offsetval + exp.DataOffset).ToString("X8"));
                                        byte[] ibuff = BitConverter.GetBytes(pr.Value.IntValue);
                                        float f = BitConverter.ToSingle(ibuff, 0);
                                        stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'CATNAME - " + pcc.getNameEntry(pr.Name) + "'," +
                                            "'PLACEHOLDERDESC', 'HINT', 'TARGETMODULE', 'TARGETPATH', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                            "0x" + (pr.offsetval + exp.DataOffset).ToString("X8") + ",3,null,null,null," + f.ToString() + ",null,null,null,null,null,null,0.001,null,CATEGORY, 0);");
                                    }
                                    if (pr.TypeVal == PropertyReader.Type.IntProperty)
                                    {
                                        if (isfirst)
                                        {
                                            stringoutput.WriteLine(" -- EXPORT #" + index + " " + exp.PackageFullName + "." + exp.ObjectName);
                                            isfirst = false;
                                        }
                                        Console.WriteLine("INT PROPERTY: " + pcc.getNameEntry(pr.Name) + " at 0x" + (pr.offsetval + exp.DataOffset).ToString("X8"));
                                        stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'CATNAME - " + pcc.getNameEntry(pr.Name) + "'," +
                                            "'PLACEHOLDERDESC', 'HINT', 'TARGETMODULE', 'TARGETPATH', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                            "0x" + (pr.offsetval + exp.DataOffset).ToString("X8") + ",0," + pr.Value.IntValue.ToString() + ",null,null,null,0,null,null,null,null,null,0,null,CATEGORY, 0);");
                                    }
                                }
                                Console.WriteLine();

                            }
                            //    }
                            //    if (data)
                            //    {
                            //        stringoutput.WriteLine("==============Data==============");
                            //        stringoutput.WriteLine(BitConverter.ToString(exp.Data));
                            //    }
                            //}
                            //numDone++;
                        }
                        //stringoutput.WriteLine("--End of " + datasets);

                        if (needsFlush)
                        {
                            Console.WriteLine();
                        }
                        stringoutput.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception parsing " + path + "\n" + e.Message);
                }
            }

        }
        private static PropertyInfo getProperty(PCCObject pcc, PCCObject.ExportEntry entry)
        {
            PropertyInfo p = new PropertyInfo();
            switch (entry.ClassName)
            {
                case "IntProperty":
                    p.type = PropertyReader.Type.IntProperty;
                    break;
                case "StringRefProperty":
                    p.type = PropertyReader.Type.StringRefProperty;
                    break;
                case "FloatProperty":
                    p.type = PropertyReader.Type.FloatProperty;
                    break;
                case "BoolProperty":
                    p.type = PropertyReader.Type.BoolProperty;
                    break;
                case "StrProperty":
                    p.type = PropertyReader.Type.StrProperty;
                    break;
                case "NameProperty":
                    p.type = PropertyReader.Type.NameProperty;
                    break;
                case "DelegateProperty":
                    p.type = PropertyReader.Type.DelegateProperty;
                    break;
                case "ObjectProperty":
                case "ClassProperty":
                case "ComponentProperty":
                    p.type = PropertyReader.Type.ObjectProperty;
                    p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                    break;
                case "StructProperty":
                    p.type = PropertyReader.Type.StructProperty;
                    p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                    break;
                case "BioMask4Property":
                case "ByteProperty":
                    p.type = PropertyReader.Type.ByteProperty;
                    p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4));
                    break;
                case "ArrayProperty":
                    p.type = PropertyReader.Type.ArrayProperty;
                    PropertyInfo arrayTypeProp = getProperty(pcc, pcc.Exports[BitConverter.ToInt32(entry.Data, 44) - 1]);
                    if (arrayTypeProp != null)
                    {
                        switch (arrayTypeProp.type)
                        {
                            case PropertyReader.Type.ObjectProperty:
                            case PropertyReader.Type.StructProperty:
                            case PropertyReader.Type.ArrayProperty:
                                p.reference = arrayTypeProp.reference;
                                break;
                            case PropertyReader.Type.ByteProperty:
                                if (arrayTypeProp.reference == "")
                                    p.reference = arrayTypeProp.type.ToString();
                                else
                                    p.reference = arrayTypeProp.reference;
                                break;
                            case PropertyReader.Type.IntProperty:
                            case PropertyReader.Type.FloatProperty:
                            case PropertyReader.Type.NameProperty:
                            case PropertyReader.Type.BoolProperty:
                            case PropertyReader.Type.StrProperty:
                            case PropertyReader.Type.StringRefProperty:
                            case PropertyReader.Type.DelegateProperty:
                                p.reference = arrayTypeProp.type.ToString();
                                break;
                            case PropertyReader.Type.None:
                            case PropertyReader.Type.Unknown:
                            default:
                                System.Diagnostics.Debugger.Break();
                                p = null;
                                break;
                        }
                    }
                    else
                    {
                        p = null;
                    }
                    break;
                case "InterfaceProperty":
                default:
                    p = null;
                    break;
            }

            return p;
        }
 private static ClassInfo generateClassInfo(int index, PCCObject pcc)
 {
     ClassInfo info = new ClassInfo();
     info.baseClass = pcc.Exports[index].ClassParent;
     info.exportIndex = index;
     info.pccPath = new string(pcc.pccFileName.Skip(pcc.pccFileName.LastIndexOf("BIOGame") + 8).ToArray());
     foreach (PCCObject.ExportEntry entry in pcc.Exports)
     {
         if (entry.idxLink - 1 == index && entry.ClassName != "ScriptStruct" && entry.ClassName != "Enum"
             && entry.ClassName != "Function" && entry.ClassName != "Const" && entry.ClassName != "State")
         {
             //Skip if property is transient (only used during execution, will never be in game files)
             if ((BitConverter.ToUInt64(entry.Data, 24) & 0x0000000000002000) == 0 && !info.properties.ContainsKey(entry.ObjectName))
             {
                 PropertyInfo p = getProperty(pcc, entry);
                 if (p != null)
                 {
                     info.properties.Add(entry.ObjectName, p);
                 }
             }
         }
     }
     return info;
 }
Esempio n. 24
0
 public static string ToRawText(byte[]raw,PCCObject Pcc,bool debug = false)
 {
     BitConverter.IsLittleEndian = true;
     string s = "";
     pcc = Pcc;
     memory = raw;
     memsize = raw.Length;
     DebugCounter = 0;
     _debug = new List<DbgMsg>();
     List<Token> t = ReadAll(0);
     int pos = 32;
     for (int i = 0; i < t.Count; i++)
     {
         s += pos.ToString("X2") + " : " + t[i].text + "\n";
         pos += t[i].raw.Length;
     }
     if (debug)
     {
         s += "\nDebug print:\n\n";
         SortDbgMsg();
         for (int i = 0; i < _debug.Count(); i++)
             s += _debug[i].count.ToString() + " : " + _debug[i].msg;
     }
     return s;
 }
Esempio n. 25
0
        public void addImport(PCCObject.ImportEntry importEntry)
        {
            if (importEntry.pccRef != this)
                throw new Exception("you cannot add a new import entry from another pcc file, it has invalid references!");

            Imports.Add(importEntry);
            ImportCount = Imports.Count;
        }
Esempio n. 26
0
 public ExportEntry(PCCObject pccFile, byte[] importData, uint exportOffset)
 {
     pccRef = pccFile;
     header = (byte[])importData.Clone();
     offset = exportOffset;
     hasChanged = false;
 }
Esempio n. 27
0
 public ImportEntry(PCCObject pccFile, Stream importData)
 {
     pccRef = pccFile;
     header = new byte[ImportEntry.byteSize];
     importData.Read(header, 0, header.Length);
 }
Esempio n. 28
0
 public ImportEntry(PCCObject pccFile, byte[] importData)
 {
     pccRef = pccFile;
     header = (byte[])importData.Clone();
 }
        public static void dumpDynamicMixInsFromPCC(string path)
        {
            PCCObject pcc = new PCCObject(path);
            try
            {
                string savepath = Path.GetFileNameWithoutExtension(path) + ".sql";
                using (StreamWriter stringoutput = new StreamWriter(savepath))
                {
                    int numDone = 1;
                    int numTotal = pcc.Exports.Count;
                    int lastProgress = 0;
                    writeVerboseLine("Enumerating exports");
                    Boolean needsFlush = false;
                    int index = 0;
                    foreach (PCCObject.ExportEntry exp in pcc.Exports)
                    {
                        index++;
                        //filter
                        switch (exp.ObjectName)
                        {
                            case "AnimNodeSequence":
                            case "BioAnimNodeSequenceMirror":
                                continue;
                        }

                        if (exp.PackageFullName.StartsWith("EffectsMaterials"))
                        {
                            continue;
                        }

                        if (exp.PackageFullName.ToUpper().StartsWith("BIOG"))
                        {
                            continue;
                        }

                        if (exp.PackageFullName.ToUpper().StartsWith("BIOVFX"))
                        {
                            continue;
                        }

                        if (exp.PackageFullName.ToUpper().StartsWith("WWISE"))
                        {
                            continue;
                        }

                        if (exp.PackageFullName.ToUpper().StartsWith("GUI_SF"))
                        {
                            continue;
                        }

                        if (!exp.PackageFullName.Contains("Default__"))
                        {
                            continue;
                        }


                        List<PropertyReader.Property> p;

                        p = PropertyReader.getPropList(pcc, exp);
                        if (p.Count > 0)
                        {
                            Boolean isfirst = true;
                            foreach (Property pr in p)
                            {
                                if (pr.TypeVal == PropertyReader.Type.FloatProperty)
                                {
                                    if (isfirst)
                                    {
                                        stringoutput.WriteLine(" -- EXPORT #" + index + " " + exp.PackageFullName + "." + exp.ObjectName);
                                        isfirst = false;
                                    }
                                    Console.WriteLine("FLOAT PROPERTY: " + pcc.getNameEntry(pr.Name) + " at 0x" + (pr.offsetval + exp.DataOffset).ToString("X8"));
                                    byte[] ibuff = BitConverter.GetBytes(pr.Value.IntValue);
                                    float f = BitConverter.ToSingle(ibuff, 0);
                                    stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'CATNAME - " + pcc.getNameEntry(pr.Name) + "'," +
                                        "'PLACEHOLDERDESC', 'HINT', 'TARGETMODULE', 'TARGETPATH', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                        "0x" + (pr.offsetval + exp.DataOffset).ToString("X8") + ",3,null,null,null," + f.ToString() + ",null,null,null,null,null,null,0.001,null,CATEGORY, 0);");
                                }
                                if (pr.TypeVal == PropertyReader.Type.IntProperty)
                                {
                                    if (isfirst)
                                    {
                                        stringoutput.WriteLine(" -- EXPORT #" + index + " " + exp.PackageFullName + "." + exp.ObjectName);
                                        isfirst = false;
                                    }
                                    Console.WriteLine("INT PROPERTY: " + pcc.getNameEntry(pr.Name) + " at 0x" + (pr.offsetval + exp.DataOffset).ToString("X8"));
                                    stringoutput.WriteLine("INSERT INTO dynamicmixinlibrary VALUES(null,'CATNAME - " + pcc.getNameEntry(pr.Name) + "'," +
                                        "'PLACEHOLDERDESC', 'HINT', 'TARGETMODULE', 'TARGETPATH', " + new FileInfo(pcc.pccFileName).Length.ToString() + "," +
                                        "0x" + (pr.offsetval + exp.DataOffset).ToString("X8") + ",0," + pr.Value.IntValue.ToString() + ",null,null,null,0,null,null,null,null,null,0,null,CATEGORY, 0);");
                                }
                            }
                        }
                        //    }
                        //    if (data)
                        //    {
                        //        stringoutput.WriteLine("==============Data==============");
                        //        stringoutput.WriteLine(BitConverter.ToString(exp.Data));
                        //    }
                        //}
                        //numDone++;
                    }
                    //stringoutput.WriteLine("--End of " + datasets);

                    if (needsFlush)
                    {
                        Console.WriteLine();
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception parsing " + path + "\n" + e.Message);
            }
        }
        public static void DumpMeshViewerFile(String file)
        {
            PCCObject pcc = new PCCObject(file);
            int index = 0;
            string savepath = Directory.GetParent(file) + "\\" + Path.GetFileNameWithoutExtension(file) + "_meshmap.txt";
            using (StreamWriter stringoutput = new StreamWriter(savepath))
            {
                foreach (PCCObject.ExportEntry exp in pcc.Exports)
                {
                    index++;
                    if (exp.ClassName == "PathNode")
                    {
                        Console.WriteLine(exp.ClassName);

                        Interpreter i = new Interpreter();
                        i.Pcc = pcc;
                        i.Index = index - 1; //0-based array
                        i.InitInterpreter();
                        TreeNode top = i.topNode;

                        if (top.Children.Count > 0 && top.Children[0].Tag != Interpreter.nodeType.None)
                        {
                            //stringoutput.WriteLine(String.Format("|{0,40}|{1,15}|{2,10}|{3,30}|", "Name", "Type", "Size", "Value"));
                            top.PrintMeshViewer("", stringoutput, false);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Dumps data from a pcc file to a text file
        /// </summary>
        /// <param name="file">PCC file path to dump from</param>
        /// <param name="args">6 element boolean array, specifying what should be dumped. In order: imports, exports, data, scripts, coalesced, names. At least 1 of these options must be true.</param>
        /// <param name="outputfolder"></param>
        public static void dumpPCCFile(string file, Boolean[] args, string outputfolder = null)
        {
            if (GamePath == null)
            {
                Console.Error.WriteLine("Game path not defined. Can't dump file file with undefined game path.");
                return;
            }
            //try
            {
                Boolean imports = args[0];
                Boolean exports = args[1];
                Boolean data = args[2];
                Boolean scripts = args[3];
                Boolean coalesced = args[4];
                Boolean names = args[5];
                Boolean separateExports = args[6];
                Boolean properties = args[7];

                PCCObject pcc = new PCCObject(file);

                string outfolder = outputfolder;
                if (outfolder == null)
                {
                    outfolder = Directory.GetParent(file).ToString();
                }

                if (!outfolder.EndsWith(@"\"))
                {
                    outfolder += @"\";
                }

                if (properties)
                {
                    UnrealObjectInfo.loadfromJSON();
                }

                string savepath = outfolder + Path.GetFileNameWithoutExtension(file) + ".txt";
                Directory.CreateDirectory(Path.GetDirectoryName(savepath));

                using (StreamWriter stringoutput = new StreamWriter(savepath))
                {

                    if (imports)
                    {
                        writeVerboseLine("Getting Imports");
                        stringoutput.WriteLine("--Imports");
                        for (int x = 0; x < pcc.Imports.Count; x++)
                        {
                            PCCObject.ImportEntry imp = pcc.Imports[x];
                            if (imp.PackageFullName != "Class" && imp.PackageFullName != "Package")
                            {
                                stringoutput.WriteLine("#" + ((x + 1) * -1) + ": " + imp.PackageFullName + "." + imp.ObjectName + "(From: " + imp.PackageFile + ") " +
                                    "(Offset: 0x " + (pcc.ImportOffset + (x * PCCObject.ImportEntry.byteSize)).ToString("X4") + ")");
                            }
                            else
                            {
                                stringoutput.WriteLine("#" + ((x + 1) * -1) + ": " + imp.ObjectName + "(From: " + imp.PackageFile + ") " +
                                    "(Offset: 0x " + (pcc.ImportOffset + (x * PCCObject.ImportEntry.byteSize)).ToString("X4") + ")");
                            }
                        }

                        stringoutput.WriteLine("--End of Imports");
                    }

                    if (exports || scripts || data || coalesced)
                    {
                        string datasets = "";
                        if (exports)
                        {
                            datasets += "Exports ";
                        }
                        if (scripts)
                        {
                            datasets += "Scripts ";
                        }
                        if (coalesced)
                        {
                            datasets += "Coalesced ";
                        }
                        if (data)
                        {
                            datasets += "Data ";
                        }

                        stringoutput.WriteLine("--Start of " + datasets);


                        int numDone = 1;
                        int numTotal = pcc.Exports.Count;
                        int lastProgress = 0;
                        writeVerboseLine("Enumerating exports");
                        Boolean needsFlush = false;
                        int index = 0;
                        foreach (PCCObject.ExportEntry exp in pcc.Exports)
                        {
                            index++;
                            writeVerboseLine("Parse export #" + index);

                            //Boolean isCoalesced = coalesced && exp.likelyCoalescedVal;
                            Boolean isCoalesced = exp.likelyCoalescedVal;
                            Boolean isScript = scripts && (exp.ClassName == "Function");
                            Boolean isEnum = exp.ClassName == "Enum";
                            int progress = ((int)(((double)numDone / numTotal) * 100));
                            while (progress >= (lastProgress + 10))
                            {
                                Console.Write("..." + (lastProgress + 10) + "%");
                                needsFlush = true;
                                lastProgress += 10;
                            }
                            if (exports || data || isScript || isCoalesced)
                            {
                                if (separateExports)
                                {
                                    stringoutput.WriteLine("=======================================================================");
                                }
                                stringoutput.Write("#" + index + " ");
                                if (isCoalesced)
                                {
                                    stringoutput.Write("[C] ");
                                }

                                if (exports || isCoalesced || isScript)
                                {
                                    stringoutput.WriteLine(exp.PackageFullName + "." + exp.ObjectName + "(" + exp.ClassName + ") (Superclass: " + exp.ClassParentWrapped + ") (Data Offset: 0x " + exp.DataOffset.ToString("X4") + ")");
                                }

                                if (isEnum)
                                {
                                    SFXEnum sfxenum = new SFXEnum(pcc, exp.Data);
                                    stringoutput.WriteLine(sfxenum.ToString());
                                }

                                if (isScript)
                                {
                                    stringoutput.WriteLine("==============Function==============");
                                    Function func = new Function(exp.Data, pcc);
                                    stringoutput.WriteLine(func.ToRawText());
                                }
                                if (properties)
                                {
                                    Interpreter i = new Interpreter();
                                    i.Pcc = pcc;
                                    i.Index = index - 1; //0-based array
                                    i.InitInterpreter();
                                    TreeNode top = i.topNode;

                                    if (top.Children.Count > 0 && top.Children[0].Tag != Interpreter.nodeType.None)
                                    {
                                        stringoutput.WriteLine("=================================================Properties=================================================");
                                        //stringoutput.WriteLine(String.Format("|{0,40}|{1,15}|{2,10}|{3,30}|", "Name", "Type", "Size", "Value"));
                                        top.PrintPretty("", stringoutput, false);
                                        stringoutput.WriteLine();
                                    }
                                }
                                if (data)
                                {
                                    stringoutput.WriteLine("==============Data==============");
                                    stringoutput.WriteLine(BitConverter.ToString(exp.Data));
                                }
                            }
                            numDone++;
                        }
                        stringoutput.WriteLine("--End of " + datasets);

                        if (needsFlush)
                        {
                            Console.WriteLine();
                        }
                    }

                    if (names)
                    {
                        writeVerboseLine("Gathering names");
                        stringoutput.WriteLine("--Names");

                        int count = 0;
                        foreach (string s in pcc.Names)
                            stringoutput.WriteLine((count++) + " : " + s);
                        stringoutput.WriteLine("--End of Names");

                    }
                }
            }
            //catch (Exception e)
            //{
            //    Console.WriteLine("Exception parsing " + file + "\n" + e.Message);
            //}
        }
        private static SequenceObjectInfo generateSequenceObjectInfo(int i, PCCObject pcc)
        {
            SequenceObjectInfo info = new SequenceObjectInfo();
            PropertyReader.Property inputLinks = PropertyReader.getPropOrNull(pcc, pcc.Exports[i + 1], "InputLinks");
            if (inputLinks != null)
            {
                int pos = 28;
                byte[] global = inputLinks.raw;
                int count = BitConverter.ToInt32(global, 24);
                for (int j = 0; j < count; j++)
                {
                    List<PropertyReader.Property> p2 = PropertyReader.ReadProp(pcc, global, pos);

                    info.inputLinks.Add(p2[0].Value.StringValue);
                    for (int k = 0; k < p2.Count(); k++)
                        pos += p2[k].raw.Length;
                }
            }
            return info;
        }
 public static byte[] getDefaultClassValue(PCCObject pcc, string className, bool fullProps = false)
 {
     if (Structs.ContainsKey(className))
     {
         bool      isImmutable   = ImmutableStructs.Contains(className);
         ClassInfo info          = Structs[className];
         String    pccToLoadPath = Path.Combine(TransplanterLib.GamePath, @"BIOGame\" + info.pccPath);
         PCCObject importPCC     = null;
         pccMemoryCache.TryGetValue(pccToLoadPath, out importPCC);
         if (importPCC == null)
         {
             try
             {
                 importPCC = new PCCObject(pccToLoadPath);
                 pccMemoryCache[pccToLoadPath] = importPCC;
             }
             catch (Exception)
             {
                 return(null);
             }
         }
         byte[] buff;
         //Plane and CoverReference inherit from other structs, meaning they don't have default values (who knows why)
         //thus, I have hardcoded what those default values should be
         if (className == "Plane")
         {
             buff = PlaneDefault;
         }
         else if (className == "CoverReference")
         {
             buff = CoverReferenceDefault;
         }
         else
         {
             buff = importPCC.Exports[info.exportIndex].Data.Skip(0x24).ToArray();
         }
         List <PropertyReader.Property> Props = PropertyReader.ReadProp(importPCC, buff, 0);
         MemoryStream m = new MemoryStream();
         foreach (PropertyReader.Property p in Props)
         {
             string propName = importPCC.getNameEntry(p.Name);
             //check if property is transient, if so, skip (neither of the structs that inherit have transient props)
             if (info.properties.ContainsKey(propName) || propName == "None" || info.baseClass != "Class")
             {
                 if (isImmutable && !fullProps)
                 {
                     PropertyReader.ImportImmutableProperty(pcc, importPCC, p, className, m, true);
                 }
                 else
                 {
                     PropertyReader.ImportProperty(pcc, importPCC, p, className, m, true);
                 }
             }
         }
         return(m.ToArray());
     }
     else if (Classes.ContainsKey(className))
     {
         ClassInfo info          = Structs[className];
         String    pccToLoadPath = Path.Combine(TransplanterLib.GamePath, @"BIOGame\" + info.pccPath);
         PCCObject importPCC;
         if (pccMemoryCache[pccToLoadPath] != null)
         {
             importPCC = pccMemoryCache[pccToLoadPath];
         }
         else
         {
             try
             {
                 importPCC = new PCCObject(pccToLoadPath);
                 pccMemoryCache[pccToLoadPath] = importPCC;
             }
             catch (Exception)
             {
                 return(null);
             }
         }
         PCCObject.ExportEntry          entry = pcc.Exports[info.exportIndex + 1];
         List <PropertyReader.Property> Props = PropertyReader.getPropList(importPCC, entry);
         MemoryStream m = new MemoryStream(entry.DataSize - 4);
         foreach (PropertyReader.Property p in Props)
         {
             if (!info.properties.ContainsKey(importPCC.getNameEntry(p.Name)))
             {
                 //property is transient
                 continue;
             }
             PropertyReader.ImportProperty(pcc, importPCC, p, className, m);
         }
         return(m.ToArray());
     }
     return(null);
 }
 private static void generateEnumValues(int index, PCCObject pcc)
 {
     string enumName = pcc.Exports[index].ObjectName;
     if (!Enums.ContainsKey(enumName))
     {
         List<string> values = new List<string>();
         byte[] buff = pcc.Exports[index].Data;
         //subtract 1 so that we don't get the MAX value, which is an implementation detail
         int count = BitConverter.ToInt32(buff, 20) - 1;
         for (int i = 0; i < count; i++)
         {
             values.Add(pcc.Names[BitConverter.ToInt32(buff, 24 + i * 8)]);
         }
         Enums.Add(enumName, values);
     }
 }
 private static Type getType(PCCObject pcc, int type)
 {
     switch (pcc.getNameEntry(type))
     {
         case "None": return Type.None;
         case "StructProperty": return Type.StructProperty;
         case "IntProperty": return Type.IntProperty;
         case "FloatProperty": return Type.FloatProperty;
         case "ObjectProperty": return Type.ObjectProperty;
         case "NameProperty": return Type.NameProperty;
         case "BoolProperty": return Type.BoolProperty;
         case "ByteProperty": return Type.ByteProperty;
         case "ArrayProperty": return Type.ArrayProperty;
         case "DelegateProperty": return Type.DelegateProperty;
         case "StrProperty": return Type.StrProperty;
         case "StringRefProperty": return Type.StringRefProperty;
         default:
             return Type.Unknown;
     }
 }
        /// <summary>
        /// Extracts all GFX (GUI) files from the specified source file. It will extract only what is listed in packageName for the export, unless it is null, in which case all GFX files are extracted to the specified path.
        /// </summary>
        /// <param name="sourceFile">Source PCC file to inspect.</param>
        /// <param name="path">Directory to put extracted GFX files. If it does not exist, it will be created.</param>
        public static void extractAllGFxMovies(string sourceFile, string outputpath = null, BackgroundWorker worker = null)
        {
            if (outputpath == null)
            {
                outputpath = Directory.GetParent(sourceFile).ToString();
            }

            if (!outputpath.EndsWith("\\"))
            {
                outputpath = outputpath + '\\';
            }
            PCCObject pcc = new PCCObject(sourceFile);
            int numExports = pcc.Exports.Count;
            for (int i = 0; i < numExports; i++)
            {
                PCCObject.ExportEntry exp = pcc.Exports[i];
                if (exp.ClassName == "GFxMovieInfo")
                {
                    Directory.CreateDirectory(outputpath);

                    String fname = exp.ObjectName;

                    writeVerboseLine("Extracting: " + outputpath + exp.PackageFullName + "." + fname + ".swf");
                    extract_swf(exp, outputpath + exp.PackageFullName + "." + fname + ".swf");
                }

                if (worker != null)
                {
                    worker.ReportProgress((int)(((double)i / numExports) * 100));
                }
            }
        }
        /// <summary>
        /// Replaces a single SWF file in a specified PCC. As each export is scanned, if it is a GFX export and the name matches the input gfx filename, it will be replaced.
        /// </summary>
        /// <param name="gfxFile">GFX file to insert (SWF)</param>
        /// <param name="destinationFile">File to update GFX files in</param>
        /// <param name="targetExport">Target export to scan for. If none is specified the filename is used as the packname/object name export to find</param>
        public static int replaceSingleSWF(string gfxFile, string destinationFile, string targetExport = null)
        {
            string inpackobjname = Path.GetFileNameWithoutExtension(gfxFile);
            if (targetExport != null)
            {
                inpackobjname = targetExport;
            }
            string backupfile = destinationFile + ".bak";
            if (File.Exists(backupfile))
            {
                File.Delete(backupfile);
            }
            File.Move(destinationFile, backupfile);
            writeVerboseLine("Scanning " + destinationFile);
            PCCObject pcc = new PCCObject(backupfile);
            int numExports = pcc.Exports.Count;
            bool replaced = false;
            for (int i = 0; i < numExports; i++)
            {
                PCCObject.ExportEntry exp = pcc.Exports[i];

                if (exp.ClassName == "GFxMovieInfo")
                {
                    string packobjname = exp.PackageFullName + "." + exp.ObjectName;
                    if (packobjname.ToLower() == inpackobjname.ToLower())
                    {
                        Console.WriteLine("#" + i + " Replacing " + exp.PackageFullName + "." + exp.ObjectName);
                        replace_swf_file(exp, gfxFile);
                        replaced = true;
                        break;
                    }
                }

            }
            if (replaced)
            {
                Console.WriteLine("Saving pcc...");
                pcc.save(destinationFile);
                return VerifyPCC(destinationFile);
            }
            else
            {
                Console.WriteLine("No GFX file in the PCC with the name of " + inpackobjname + " was found.");
                File.Move(backupfile, destinationFile);
                return 1;
            }
        }
Esempio n. 38
0
 public ImportEntry(PCCObject pccFile, byte[] importData)
 {
     pccRef = pccFile;
     header = (byte[])importData.Clone();
 }
 private static PropertyValue ReadValue(PCCObject pcc, byte[] raw, int start, int type)
 {
     PropertyValue v = new PropertyValue();
     switch (pcc.Names[type])
     {
         case "IntProperty":
         case "FloatProperty":
         case "ObjectProperty":
         case "StringRefProperty":
             v.IntValue = BitConverter.ToInt32(raw, start);
             v.len = 4;
             break;
         case "NameProperty":
             v.IntValue = BitConverter.ToInt32(raw, start);
             var nameRef = new NameReference();
             nameRef.index = v.IntValue;
             nameRef.count = BitConverter.ToInt32(raw, start + 4);
             nameRef.Name = pcc.getNameEntry(nameRef.index);
             if (nameRef.count > 0)
                 nameRef.Name += "_" + (nameRef.count - 1);
             v.NameValue = nameRef;
             v.len = 8;
             break;
         case "BoolProperty":
             if (start < raw.Length)
                 v.IntValue = raw[start];
             v.len = 1;
             break;
     }
     return v;
 }
 static void extract_swf(PCCObject.ExportEntry ent, string filename)
 {
     int originalSize = System.BitConverter.ToInt32(ent.Data, 28);
     byte[] originalFile = copyByteChunk(ent.Data, 32, originalSize);
     File.WriteAllBytes(filename, originalFile);
 }
        /// <summary>
        /// Dumps all exec functions from all pcc's in the specified folder into a file
        /// </summary>
        /// <param name="folder">Folder to search for pcc's for.</param>
        /// <param name="outputfolder">Folder to place a file named ExecFunctions.txt into. If null it will be placed in folder.</param>
        public static void dumpAllExecFromFolder(string folder, string outputfolder = null)
        {
            SortedSet<String> uniqueExecFunctions = new SortedSet<String>(); //unique set of function names
            SortedDictionary<String, List<String>> functionFileMap = new SortedDictionary<String, List<String>>(); //what functions appear in what file(s)
            SortedDictionary<String, String> functionTextMap = new SortedDictionary<String, String>(); //Function > Function Text

            string[] files = Directory.GetFiles(folder, "*.pcc", SearchOption.AllDirectories);
            int filesDone = 1;
            foreach (String pccfile in files)
            {
                Console.WriteLine("[" + (filesDone) + "/" + files.Length + "] Scanning for Exec: " + Path.GetFileName(pccfile));
                PCCObject pcc = new PCCObject(pccfile);
                foreach (PCCObject.ExportEntry exp in pcc.Exports)
                {
                    if (exp.ClassName == "Function")
                    {
                        Function func = new Function(exp.Data, pcc);
                        //exec = 9
                        int execbit = 9;
                        int flagint = func.GetFlagInt();
                        int flag = 1 << execbit;
                        if ((flagint & flag) != 0)
                        {
                            //EXEC FUNCTION!
                            List<String> list;
                            string key = exp.PackageName + "." + exp.ObjectName;
                            if (functionFileMap.TryGetValue(key, out list))
                            {
                                // add to list
                                list.Add(Path.GetFileName(pccfile));
                            }
                            else
                            {
                                //make new list, add to it
                                list = new List<String>();
                                list.Add(Path.GetFileName(pccfile));
                                functionFileMap.Add(exp.PackageName + "." + exp.ObjectName, list);
                            }

                            //Check function text
                            string functext;
                            if (functionTextMap.TryGetValue(key, out functext))
                            {
                                // add to list
                                if (functext != func.ToString())
                                {
                                    functionTextMap[key] = func.ToRawText();
                                }
                            }
                            else
                            {
                                //set first time text
                                functionTextMap[key] = func.ToRawText();
                            }
                        }
                    }
                }
                filesDone++;
            }
            if (outputfolder == null)
            {
                outputfolder = folder;
            }

            if (!outputfolder.EndsWith(@"\")) outputfolder += @"\";
            string outputfile = outputfolder + "ExecFunctions.txt";

            Console.WriteLine("Saving to " + outputfile);
            Directory.CreateDirectory(Path.GetDirectoryName(outputfile));
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputfile, false))
            {
                foreach (String key in functionFileMap.Keys)
                {
                    List<String> fileList = functionFileMap[key];
                    file.WriteLine(key);
                    file.Write("Appears in:");
                    foreach (String filename in fileList)
                    {
                        file.Write(filename + " ");
                    }
                    file.WriteLine();
                    file.WriteLine("============Function============");
                    file.WriteLine(functionTextMap[key]);
                    file.WriteLine();
                }
            }
        }
 public static int detectStart(PCCObject pcc, byte[] raw, long flags)
 {
     if ((flags & (long)UnrealFlags.EObjectFlags.HasStack) != 0)
     {
         return 30;
     }
     int result = 8;
     int test1 = BitConverter.ToInt32(raw, 4);
     int test2 = BitConverter.ToInt32(raw, 8);
     if (pcc.isName(test1) && test2 == 0)
         result = 4;
     if (pcc.isName(test1) && pcc.isName(test2) && test2 != 0)
         result = 8;
     return result;
 }
        /// <summary>
        /// Replaces all SWF files in a specified PCC. As each export is scanned, if it is a GFX export and a correspondingly named packagename.sf file exists, it will be repalced.
        /// </summary>
        /// <param name="gfxSourceFolder">Source folder, with gfx files in the root.</param>
        /// <param name="destinationFile">File to update GFX files in</param>
        public static int replaceSWFs(string gfxSourceFolder, string destinationFile, BackgroundWorker worker = null)
        {
            bool replaced = false;
            string[] gfxfiles = System.IO.Directory.GetFiles(gfxSourceFolder, "*.swf");
            List<String> packobjnames = new List<String>();
            foreach (string gfxfile in gfxfiles)
            {
                string packobjname = Path.GetFileNameWithoutExtension(gfxfile);
                writeVerboseLine("SWF in source folder: " + packobjname);
                packobjnames.Add(packobjname);
            }

            if (gfxfiles.Length > 0)
            {
                string backupfile = destinationFile + ".bak";
                if (File.Exists(backupfile))
                {
                    File.Delete(backupfile);
                }
                File.Move(destinationFile, backupfile);
                writeVerboseLine("Scanning " + destinationFile);
                int numReplaced = 0;
                PCCObject pcc = new PCCObject(backupfile);
                int numExports = pcc.Exports.Count;
                for (int i = 0; i < numExports; i++)
                {
                    PCCObject.ExportEntry exp = pcc.Exports[i];

                    if (exp.ClassName == "GFxMovieInfo")
                    {
                        string packobjname = exp.PackageFullName + "." + exp.ObjectName;
                        int index = packobjnames.IndexOf(packobjname);
                        if (index > -1)
                        {
                            writeVerboseLine("#" + i + " Replacing " + exp.PackageFullName + "." + exp.ObjectName);
                            replace_swf_file(exp, gfxfiles[index]);
                            numReplaced++;
                            replaced = true;
                        }
                    }
                    if (worker != null && numReplaced % 10 == 0)
                    {
                        //Console.WriteLine("Progress: " + i + " / "+numExports);
                        worker.ReportProgress((int)(((double)i / numExports) * 100));
                    }
                }
                writeVerboseLine("Replaced " + numReplaced + " files, saving.");
                if (replaced)
                {
                    //pcc.saveByReconstructing(destinationFile); //34 is default
                    Console.WriteLine("Saving pcc...");
                    pcc.save(destinationFile);
                    return VerifyPCC(destinationFile);
                }
                else
                {
                    Console.WriteLine("No SWFs replaced");
                    File.Move(backupfile, destinationFile);
                    return 0;
                }
            }
            else
            {
                Console.WriteLine("No source GFX files were found.");
                return 1;
            }
        }
        public static int VerifyPCC(string pcc)
        {
            try
            {
                PCCObject obj = new PCCObject(pcc);

                foreach (PCCObject.ImportEntry imp in obj.Imports)
                {
                    String teststr = imp.ClassName;
                    int testval = imp.idxObjectName;
                    teststr = imp.PackageName;
                }
                foreach (PCCObject.ExportEntry exp in obj.Exports)
                {
                    String teststr = exp.ArchtypeName;
                    int testval = exp.DataSize;
                    byte[] data = exp.Data;
                }
                Console.WriteLine("PCC Loaded OK");
                return 0;
            }
            catch (IOException e)
            {
                Console.Error.WriteLine("PCC Failed to load, threw exception: ");
                throw e;
                Console.Error.WriteLine(e.ToString());
                return 1;
            }
        }
 //call this method to regenerate ME3ObjectInfo.json
 //Takes a long time (~5 minutes maybe?). Application will be completely unresponsive during that time.
 public static void generateInfo()
 {
     PCCObject pcc;
     string path = TransplanterLib.GamePath;
     string[] files = Directory.GetFiles(path, "*.pcc", SearchOption.AllDirectories);
     string objectName;
     int length = files.Length;
     for (int i = 0; i < length; i++)
     {
         if (files[i].ToLower().EndsWith(".pcc"))
         {
             pcc = new PCCObject(files[i]);
             for (int j = 0; j < pcc.Exports.Count; j++)
             {
                 if (pcc.Exports[j].ClassName == "Enum")
                 {
                     generateEnumValues(j, pcc);
                 }
                 else if (pcc.Exports[j].ClassName == "Class")
                 {
                     objectName = pcc.Exports[j].ObjectName;
                     if (!Classes.ContainsKey(objectName))
                     {
                         Classes.Add(objectName, generateClassInfo(j, pcc));
                     }
                     if ((objectName.Contains("SeqAct") || objectName.Contains("SeqCond") || objectName.Contains("SequenceLatentAction") ||
                         objectName == "SequenceOp" || objectName == "SequenceAction" || objectName == "SequenceCondition") && !SequenceObjects.ContainsKey(objectName))
                     {
                         SequenceObjects.Add(objectName, generateSequenceObjectInfo(j, pcc));
                     }
                 }
                 else if (pcc.Exports[j].ClassName == "ScriptStruct")
                 {
                     objectName = pcc.Exports[j].ObjectName;
                     if (!Structs.ContainsKey(objectName))
                     {
                         Structs.Add(objectName, generateClassInfo(j, pcc));
                     }
                 }
             }
         }
         System.Diagnostics.Debug.WriteLine($"{i} of {length} processed");
     }
     File.WriteAllText(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase) + "//ME3ObjectInfo.json",
         JsonConvert.SerializeObject(new { SequenceObjects = SequenceObjects, Classes = Classes, Structs = Structs, Enums = Enums }));
 }
        public static List <Property> ReadProp(PCCObject pcc, byte[] raw, int start)
        {
            Property        p;
            PropertyValue   v;
            int             sname;
            List <Property> result = new List <Property>();
            int             pos    = start;

            if (raw.Length - pos < 8)
            {
                return(result);
            }
            int name = (int)BitConverter.ToInt64(raw, pos);

            if (!pcc.isName(name))
            {
                return(result);
            }
            string t = pcc.Names[name];

            if (pcc.Names[name] == "None")
            {
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.None;
                p.i         = 0;
                p.offsetval = pos;
                p.Size      = 8;
                p.Value     = new PropertyValue();
                p.raw       = BitConverter.GetBytes((Int64)name);
                p.offend    = pos + 8;
                result.Add(p);
                return(result);
            }
            int type = (int)BitConverter.ToInt64(raw, pos + 8);
            int size = BitConverter.ToInt32(raw, pos + 16);
            int idx  = BitConverter.ToInt32(raw, pos + 20);

            if (!pcc.isName(type) || size < 0 || size >= raw.Length)
            {
                return(result);
            }
            string tp = pcc.Names[type];

            switch (tp)
            {
            case "DelegateProperty":
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.DelegateProperty;
                p.i         = 0;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = BitConverter.ToInt32(raw, pos + 28);
                v.len       = size;
                v.Array     = new List <PropertyValue>();
                pos        += 24;
                for (int i = 0; i < size; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "ArrayProperty":
                int count = (int)BitConverter.ToInt64(raw, pos + 24);
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.ArrayProperty;
                p.i         = 0;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = type;
                v.len       = size - 4;
                count       = v.len;//TODO can be other objects too
                v.Array     = new List <PropertyValue>();
                pos        += 28;
                for (int i = 0; i < count; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "StrProperty":
                count       = (int)BitConverter.ToInt64(raw, pos + 24);
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.StrProperty;
                p.i         = 0;
                p.offsetval = pos + 24;
                count      *= -1;
                v           = new PropertyValue();
                v.IntValue  = type;
                v.len       = count;
                pos        += 28;
                string s = "";
                for (int i = 0; i < count; i++)
                {
                    s   += (char)raw[pos];
                    pos += 2;
                }
                v.StringValue = s;
                p.Value       = v;
                break;

            case "StructProperty":
                sname       = (int)BitConverter.ToInt64(raw, pos + 24);
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.StructProperty;
                p.i         = 0;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = sname;
                v.len       = size;
                v.Array     = new List <PropertyValue>();
                pos        += 32;
                for (int i = 0; i < size; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "BioMask4Property":
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = Type.ByteProperty;
                p.i         = 0;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.len       = size;
                pos        += 24;
                v.IntValue  = raw[pos];
                pos        += size;
                p.Value     = v;
                break;

            case "ByteProperty":
                sname         = (int)BitConverter.ToInt64(raw, pos + 24);
                p             = new Property();
                p.Name        = name;
                p.TypeVal     = Type.ByteProperty;
                p.i           = 0;
                p.offsetval   = pos + 32;
                v             = new PropertyValue();
                v.StringValue = pcc.getNameEntry(sname);
                v.len         = size;
                pos          += 32;
                if (size == 8)
                {
                    v.IntValue = BitConverter.ToInt32(raw, pos);
                }
                else
                {
                    v.IntValue = raw[pos];
                }
                pos    += size;
                p.Value = v;
                break;

            default:
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = getType(pcc, type);
                p.i         = 0;
                p.offsetval = pos + 24;
                p.Value     = ReadValue(pcc, raw, pos + 24, type);
                pos        += p.Value.len + 24;
                break;
            }
            p.Size   = size;
            p.raw    = new byte[pos - start];
            p.offend = pos;
            if (pos < raw.Length)
            {
                for (int i = 0; i < pos - start; i++)
                {
                    p.raw[i] = raw[start + i];
                }
            }
            result.Add(p);
            if (pos != start)
            {
                result.AddRange(ReadProp(pcc, raw, pos));
            }
            return(result);
        }
        /// <summary>
        /// Dumps functions labeled as Exec into a file
        /// </summary>
        /// <param name="pccfile">File to dump functions from</param>
        /// <param name="outputfile">File to save dump to</param>
        public static void dumpAllExecFromFile(string pccfile, string outputfile = null)
        {
            Console.WriteLine("Scanning " + Path.GetFileName(pccfile) + " for Exec Functions");
            SortedSet<String> uniqueExecFunctions = new SortedSet<String>();
            SortedDictionary<String, List<String>> functionFileMap = new SortedDictionary<String, List<String>>();
            SortedDictionary<String, String> functionTextMap = new SortedDictionary<String, String>(); //Function > Function Text

            PCCObject pcc = new PCCObject(pccfile);
            foreach (PCCObject.ExportEntry exp in pcc.Exports)
            {
                if (exp.ClassName == "Function")
                {
                    Function func = new Function(exp.Data, pcc);
                    //exec = 9
                    int execbit = 9;
                    int flagint = func.GetFlagInt();
                    int flag = 1 << execbit;
                    if ((flagint & flag) != 0)
                    {
                        //EXEC FUNCTION!
                        List<String> list;
                        string key = exp.PackageName + "." + exp.ObjectName;
                        if (functionFileMap.TryGetValue(key, out list))
                        {
                            list.Add(Path.GetFileName(pccfile));
                        }
                        else
                        {
                            list = new List<String>();
                            list.Add(Path.GetFileName(pccfile));
                            functionFileMap.Add(key, list);
                            //add new
                        }
                        //Check function text
                        string functext;
                        if (functionTextMap.TryGetValue(key, out functext))
                        {
                            // add to list
                            if (functext != func.ToString())
                            {
                                functionTextMap[key] = func.ToRawText();
                            }
                        }
                        else
                        {
                            //set first time text
                            functionTextMap[key] = func.ToRawText();
                        }
                    }
                }
            }
            if (outputfile == null)
            {
                outputfile = Directory.GetParent(pccfile).ToString();
            }
            if (!outputfile.EndsWith(@"\")) outputfile += @"\";
            outputfile = outputfile + "ExecFunctions.txt";

            Console.WriteLine("Saving to " + outputfile);
            Directory.CreateDirectory(Path.GetDirectoryName(outputfile));
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputfile, false))
            {
                foreach (String key in functionFileMap.Keys)
                {
                    List<String> fileList = functionFileMap[key];
                    file.WriteLine(key);
                    file.Write("Appears in:");
                    foreach (String filename in fileList)
                    {
                        file.Write(filename + " ");
                    }
                    file.WriteLine();
                    file.WriteLine("============Function============");
                    file.WriteLine(functionTextMap[key]);
                    file.WriteLine();
                }
            }
        }
        private static PropertyInfo getProperty(PCCObject pcc, PCCObject.ExportEntry entry)
        {
            PropertyInfo p = new PropertyInfo();

            switch (entry.ClassName)
            {
            case "IntProperty":
                p.type = PropertyReader.Type.IntProperty;
                break;

            case "StringRefProperty":
                p.type = PropertyReader.Type.StringRefProperty;
                break;

            case "FloatProperty":
                p.type = PropertyReader.Type.FloatProperty;
                break;

            case "BoolProperty":
                p.type = PropertyReader.Type.BoolProperty;
                break;

            case "StrProperty":
                p.type = PropertyReader.Type.StrProperty;
                break;

            case "NameProperty":
                p.type = PropertyReader.Type.NameProperty;
                break;

            case "DelegateProperty":
                p.type = PropertyReader.Type.DelegateProperty;
                break;

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

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

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

            case "ArrayProperty":
                p.type = PropertyReader.Type.ArrayProperty;
                PropertyInfo arrayTypeProp = getProperty(pcc, pcc.Exports[BitConverter.ToInt32(entry.Data, 44) - 1]);
                if (arrayTypeProp != null)
                {
                    switch (arrayTypeProp.type)
                    {
                    case PropertyReader.Type.ObjectProperty:
                    case PropertyReader.Type.StructProperty:
                    case PropertyReader.Type.ArrayProperty:
                        p.reference = arrayTypeProp.reference;
                        break;

                    case PropertyReader.Type.ByteProperty:
                        if (arrayTypeProp.reference == "")
                        {
                            p.reference = arrayTypeProp.type.ToString();
                        }
                        else
                        {
                            p.reference = arrayTypeProp.reference;
                        }
                        break;

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

                    case PropertyReader.Type.None:
                    case PropertyReader.Type.Unknown:
                    default:
                        System.Diagnostics.Debugger.Break();
                        p = null;
                        break;
                    }
                }
                else
                {
                    p = null;
                }
                break;

            case "InterfaceProperty":
            default:
                p = null;
                break;
            }

            return(p);
        }
 public static byte[] getDefaultClassValue(PCCObject pcc, string className, bool fullProps = false)
 {
     if (Structs.ContainsKey(className))
     {
         bool isImmutable = ImmutableStructs.Contains(className);
         ClassInfo info = Structs[className];
         PCCObject importPCC;
         try
         {
             importPCC = new PCCObject(Path.Combine(TransplanterLib.GamePath, @"BIOGame\" + info.pccPath));
         }
         catch (Exception)
         {
             return null;
         }
         byte[] buff;
         //Plane and CoverReference inherit from other structs, meaning they don't have default values (who knows why)
         //thus, I have hardcoded what those default values should be 
         if (className == "Plane")
         {
             buff = PlaneDefault;
         }
         else if (className == "CoverReference")
         {
             buff = CoverReferenceDefault;
         }
         else
         {
             buff = importPCC.Exports[info.exportIndex].Data.Skip(0x24).ToArray();
         }
         List<PropertyReader.Property> Props = PropertyReader.ReadProp(importPCC, buff, 0);
         MemoryStream m = new MemoryStream();
         foreach (PropertyReader.Property p in Props)
         {
             string propName = importPCC.getNameEntry(p.Name);
             //check if property is transient, if so, skip (neither of the structs that inherit have transient props)
             if (info.properties.ContainsKey(propName) || propName == "None" || info.baseClass != "Class")
             {
                 if (isImmutable && !fullProps)
                 {
                     PropertyReader.ImportImmutableProperty(pcc, importPCC, p, className, m, true);
                 }
                 else
                 {
                     PropertyReader.ImportProperty(pcc, importPCC, p, className, m, true);
                 }
             }
         }
         return m.ToArray();
     }
     else if (Classes.ContainsKey(className))
     {
         ClassInfo info = Structs[className];
         PCCObject importPCC;
         try
         {
             importPCC = new PCCObject(Path.Combine(TransplanterLib.GamePath, @"BIOGame\" + info.pccPath));
         }
         catch (Exception)
         {
             return null;
         }
         PCCObject.ExportEntry entry = pcc.Exports[info.exportIndex + 1];
         List<PropertyReader.Property> Props = PropertyReader.getPropList(importPCC, entry);
         MemoryStream m = new MemoryStream(entry.DataSize - 4);
         foreach (PropertyReader.Property p in Props)
         {
             if (!info.properties.ContainsKey(importPCC.getNameEntry(p.Name)))
             {
                 //property is transient
                 continue;
             }
             PropertyReader.ImportProperty(pcc, importPCC, p, className, m);
         }
         return m.ToArray();
     }
     return null;
 }
        public static void ImportProperty(PCCObject pcc, PCCObject importpcc, Property p, string className, System.IO.MemoryStream m, bool inStruct = false)
        {
            string name    = importpcc.getNameEntry(p.Name);
            int    idxname = pcc.FindNameOrAdd(name);

            m.Write(BitConverter.GetBytes(idxname), 0, 4);
            m.Write(new byte[4], 0, 4);
            if (name == "None")
            {
                return;
            }
            string type    = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 8));
            int    idxtype = pcc.FindNameOrAdd(type);

            m.Write(BitConverter.GetBytes(idxtype), 0, 4);
            m.Write(new byte[4], 0, 4);
            string          name2;
            int             idxname2;
            int             size, count, pos;
            List <Property> Props;

            switch (type)
            {
            case "IntProperty":
            case "FloatProperty":
            case "ObjectProperty":
            case "StringRefProperty":
                m.Write(BitConverter.GetBytes(4), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(p.Value.IntValue), 0, 4);
                break;

            case "NameProperty":
                m.Write(BitConverter.GetBytes(8), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                //preserve index or whatever the second part of a namereference is
                m.Write(p.raw, 28, 4);
                break;

            case "BoolProperty":
                m.Write(new byte[8], 0, 8);
                m.WriteByte((byte)p.Value.IntValue);
                break;

            case "BioMask4Property":
                m.Write(BitConverter.GetBytes(p.Size), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.WriteByte((byte)p.Value.IntValue);
                break;

            case "ByteProperty":
                name2    = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                idxname2 = pcc.FindNameOrAdd(name2);
                m.Write(BitConverter.GetBytes(p.Size), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(idxname2), 0, 4);
                m.Write(new byte[4], 0, 4);
                if (p.Size == 8)
                {
                    m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                    m.Write(new byte[4], 0, 4);
                }
                else
                {
                    m.WriteByte(p.raw[32]);
                }
                break;

            case "DelegateProperty":
                size = BitConverter.ToInt32(p.raw, 16);
                if (size == 0xC)
                {
                    name2    = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28));
                    idxname2 = pcc.FindNameOrAdd(name2);
                    m.Write(BitConverter.GetBytes(0xC), 0, 4);
                    m.Write(new byte[4], 0, 4);
                    m.Write(new byte[4], 0, 4);
                    m.Write(BitConverter.GetBytes(idxname2), 0, 4);
                    m.Write(new byte[4], 0, 4);
                }
                else
                {
                    m.Write(BitConverter.GetBytes(size), 0, 4);
                    m.Write(new byte[4], 0, 4);
                    for (int i = 0; i < size; i++)
                    {
                        m.WriteByte(p.raw[24 + i]);
                    }
                }
                break;

            case "StrProperty":
                name2 = p.Value.StringValue;
                m.Write(BitConverter.GetBytes(4 + name2.Length * 2), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(-name2.Length), 0, 4);
                foreach (char c in name2)
                {
                    m.WriteByte((byte)c);
                    m.WriteByte(0);
                }
                break;

            case "StructProperty":
                size     = BitConverter.ToInt32(p.raw, 16);
                name2    = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                idxname2 = pcc.FindNameOrAdd(name2);
                pos      = 32;
                Props    = new List <Property>();
                try
                {
                    Props = ReadProp(importpcc, p.raw, pos);
                }
                catch (Exception)
                {
                }
                m.Write(BitConverter.GetBytes(size), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(idxname2), 0, 4);
                m.Write(new byte[4], 0, 4);
                if (Props.Count == 0 || Props[0].TypeVal == Type.Unknown)
                {
                    for (int i = 0; i < size; i++)
                    {
                        m.WriteByte(p.raw[32 + i]);
                    }
                }
                else
                {
                    foreach (Property pp in Props)
                    {
                        ImportProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                }
                break;

            case "ArrayProperty":
                size  = BitConverter.ToInt32(p.raw, 16);
                count = BitConverter.ToInt32(p.raw, 24);
                UnrealObjectInfo.PropertyInfo info      = UnrealObjectInfo.getPropertyInfo(className, name, inStruct);
                UnrealObjectInfo.ArrayType    arrayType = UnrealObjectInfo.getArrayType(info);
                pos = 28;
                List <Property> AllProps = new List <Property>();

                if (arrayType == UnrealObjectInfo.ArrayType.Struct)
                {
                    for (int i = 0; i < count; i++)
                    {
                        Props = new List <Property>();
                        try
                        {
                            Props = ReadProp(importpcc, p.raw, pos);
                        }
                        catch (Exception)
                        {
                        }
                        AllProps.AddRange(Props);
                        if (Props.Count != 0)
                        {
                            pos = Props[Props.Count - 1].offend;
                        }
                    }
                }
                m.Write(BitConverter.GetBytes(size), 0, 4);
                m.Write(new byte[4], 0, 4);
                m.Write(BitConverter.GetBytes(count), 0, 4);
                if (AllProps.Count != 0 && (info == null || !UnrealObjectInfo.isImmutable(info.reference)))
                {
                    foreach (Property pp in AllProps)
                    {
                        ImportProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                }
                else if (arrayType == UnrealObjectInfo.ArrayType.Name)
                {
                    for (int i = 0; i < count; i++)
                    {
                        string s = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28 + i * 8));
                        m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(s)), 0, 4);
                        //preserve index or whatever the second part of a namereference is
                        m.Write(p.raw, 32 + i * 8, 4);
                    }
                }
                else
                {
                    m.Write(p.raw, 28, size - 4);
                }
                break;

            default:
                throw new Exception(type);
            }
        }
 /// <summary>
 /// Scans the PCC for GFxMovieInfo exports. If anygui is true, it will return true for any. If false, it will only match on a whitelist of values.
 /// </summary>
 /// <param name="pccfilepath"></param>
 /// <param name="anygui"></param>
 /// <returns></returns>
 public static Boolean doesPCCContainGUIs(string pccfilepath, Boolean anygui)
 {
     string[] whitelist = {
         "GUI_SF_AreaMap.ME2_AreaMap",
         "GUI_SF_BlackScreen.BlackScreen",
         "GUI_SF_ConversationWheel.ConversationWheel",
         "GUI_SF_DLC_Docks.DLC_Docks",
         "GUI_SF_Elevators.NormandyElevator",
         "GUI_SF_GalaxyAtWar.galaxyAtWar",
         "GUI_SF_GalaxyMap.GalaxyMap",
         "GUI_SF_GameOver.GameOver",
         "GUI_SF_Jourdex.Jourdex",
         "GUI_SF_LoadSave.LoadSave",
         "GUI_SF_LoadScreenToolTips.LoadScreenToolTips",
         "GUI_SF_Mail.Mail",
         "GUI_SF_MainWheel.MainWheel",
         "GUI_SF_Markers.Markers",
         "GUI_SF_Markers.ObjectiveMarkers",
         "GUI_SF_ME2_AreaMap.ME2_AreaMap",
         "GUI_SF_ME2_HUD.ME2_HUD",
         "GUI_SF_ME2_PowerWheel.ME2_PowerWheel",
         "GUI_SF_ME2_Reticle.ME2_Reticle",
         "GUI_SF_MessageBox.messageBox",
         "GUI_SF_MessageBox_Hint.MessageBox_Hint",
         "GUI_SF_MPPlayerCountdown.MPPlayerCountdown",
         "GUI_SF_Options.Options",
         "GUI_SF_PC_SharedAssets.PC_SharedAssets",
         "GUI_SF_Personalization.Personalization",
         "GUI_SF_PersonalTerminal.PersonalTerminal",
         "GUI_SF_PersonalTerminalApt.PersonalTerminalApt",
         "GUI_SF_PRCStore.PRCStore",
         "GUI_SF_SaveLoadIndicator.SaveLoadIndicator",
         "GUI_SF_SquadRecord.SquadRecord",
         "GUI_SF_Store_NoPurchase.Store_NoPurchase",
         "GUI_SF_Subtitles.Subtitles",
         "GUI_SF_Training.Training",
         "GUI_SF_WarAssets.WarAssets",
         "GUI_SF_Xbox_ControllerIcons.Xbox_ControllerIcons"
     };
     PCCObject pcc = new PCCObject(pccfilepath);
     foreach (PCCObject.ExportEntry export in pcc.Exports)
     {
         if (export.ClassName == "GFxMovieInfo")
         {
             if (anygui)
             {
                 Console.WriteLine("PCC contains at least one GUI export");
                 return true;
             }
             string fullname = export.PackageName + "." + export.ObjectName;
             if (Array.Exists(whitelist, element => element == fullname))
             {
                 Console.WriteLine("PCC contains a whitelisted GUI export.");
                 return true;
             }
         }
     }
     Console.WriteLine("PCC does not contain any GUI exports");
     return false;
 }