예제 #1
0
 public ME3FaceFXAnimSet(IMEPackage Pcc, IExportEntry Entry)
 {
     
     pcc = Pcc;
     export = Entry;
     List<PropertyReader.Property> props = PropertyReader.getPropList(export);
     int start = props[props.Count - 1].offend + 4;
     SerializingContainer Container = new SerializingContainer(new MemoryStream(export.Data.Skip(start).ToArray()));
     Container.isLoading = true;
     Serialize(Container);
 }
예제 #2
0
 protected SObj(int idx, IMEPackage p)
 {
     pcc = p;
     index = idx;
     export = pcc.getExport(index);
     comment = new SText(GetComment(), commentColor, false);
     comment.X = 0;
     comment.Y = 0 - comment.Height;
     comment.Pickable = false;
     this.AddChild(comment);
     this.Pickable = true;
 }
예제 #3
0
 public static void WriteDelegateProperty(this Stream stream, IMEPackage pcc, string propName, int unk, NameReference value)
 {
     stream.WritePropHeader(pcc, propName, PropertyType.DelegateProperty, 12);
     stream.WriteValueS32(unk);
     stream.WriteValueS32(pcc.FindNameOrAdd(value.Name));
     stream.WriteValueS32(value.count);
 }
예제 #4
0
 public static void WriteNoneProperty(this EndianWriter stream, IMEPackage pcc)
 {
     //Debug.WriteLine("Writing none property at 0x" + stream.Position.ToString("X6"));
     stream.WriteNameReference("None", pcc);
 }
예제 #5
0
 public static void WriteStringProperty(this Stream stream, IMEPackage pcc, string propName, string value)
 {
     int strLen = value.Length + 1;
     if (pcc.Game == MEGame.ME3)
     {
         stream.WritePropHeader(pcc, propName, PropertyType.StrProperty, (strLen * 2) + 4);
         stream.WriteValueS32(-strLen);
         stream.WriteStringUnicode(value);
     }
     else
     {
         stream.WritePropHeader(pcc, propName, PropertyType.StrProperty, strLen + 4);
         stream.WriteValueS32(strLen);
         stream.WriteStringASCII(value);
     }
 }
예제 #6
0
 public SAction(int idx, float x, float y, IMEPackage p, GraphEditor grapheditor)
     : base(idx, p, grapheditor)
 {
     GetVarLinks();
     GetOutputLinks();
     originalX = x;
     originalY = y;
 }
예제 #7
0
 protected SBox(int idx, IMEPackage p, GraphEditor grapheditor)
     : base(idx, p, grapheditor)
 {
     
 }
예제 #8
0
        public static List<Property> ReadProp(IMEPackage 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.getNameEntry(name);
            p = new Property();
            p.Name = name;
            if (t == "None")
            {
                p.TypeVal = PropertyType.None;         
                p.offsetval = pos;
                p.Size = 8;
                p.Value = new PropertyValue();
                p.raw = BitConverter.GetBytes((long)name);
                p.offend = pos + 8;
                result.Add(p);
                return result;
            }
            int type = (int)BitConverter.ToInt64(raw, pos + 8);            
            p.Size = BitConverter.ToInt32(raw, pos + 16);
            if (!pcc.isName(type) || p.Size < 0 || p.Size >= raw.Length)
                return result;
            string tp = pcc.getNameEntry(type);
            switch (tp)
            {

                case "DelegateProperty":
                    p.TypeVal = PropertyType.DelegateProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = BitConverter.ToInt32(raw, pos + 28);
                    v.len = p.Size;
                    v.Array = new List<PropertyValue>();
                    pos += 24;
                    for (int i = 0; i < p.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 = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.ArrayProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = type;
                    v.len = p.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 = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.StrProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = type;
                    v.len = count;
                    pos += 28;
                    string s = "";
                    if (count < 0)
                    {
                        count *= -1;
                        for (int i = 1; i < count; i++)
                        {
                            s += (char)raw[pos];
                            pos += 2;
                        }
                        pos += 2;
                    }
                    else if (count > 0)
                    {
                        for (int i = 1; i < count; i++)
                        {
                            s += (char)raw[pos];
                            pos++;
                        }
                        pos++;
                    }
                    v.StringValue = s;
                    p.Value = v;
                    break;
                case "StructProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.StructProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = sname;
                    v.len = p.Size;
                    v.Array = new List<PropertyValue>();
                    pos += 32;
                    for (int i = 0; i < p.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.TypeVal = PropertyType.ByteProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.len = p.Size;
                    pos += 24;
                    v.IntValue = raw[pos];
                    pos += p.Size;
                    p.Value = v;
                    break;
                case "ByteProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.ByteProperty;
                    v = new PropertyValue();
                    v.len = p.Size;
                    if (pcc.Game == MEGame.ME3)
                    {
                        p.offsetval = pos + 32;
                        v.StringValue = pcc.getNameEntry(sname);
                        pos += 32;
                        if (p.Size == 8)
                        {
                            v.IntValue = BitConverter.ToInt32(raw, pos);
                        }
                        else
                        {
                            v.IntValue = raw[pos];
                        }
                        pos += p.Size;
                    }
                    else
                    {
                        p.offsetval = pos + 24;
                        if (p.Size != 1)
                        {
                            v.StringValue = pcc.getNameEntry(sname);
                            v.IntValue = sname;
                            pos += 32;
                        }
                        else
                        {
                            v.StringValue = "";
                            v.IntValue = raw[pos + 24];
                            pos += 25;
                        }
                    }
                    p.Value = v;
                    break;
                case "FloatProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.FloatProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.FloatValue = BitConverter.ToSingle(raw, pos + 24);
                    v.len = p.Size;
                    pos += 28;
                    p.Value = v;
                    break;
                case "BoolProperty":
                    p = new Property();
                    p.Name = name;
                    p.TypeVal = PropertyType.BoolProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = raw[pos + 24];
                    if (pcc.Game == MEGame.ME3)
                    {
                        v.len = 1; 
                    }
                    else
                    {
                        v.len = 4;
                    }
                    pos += v.len + 24;
                    p.Value = v;
                    break;
                default:
                    p.TypeVal = getType(pcc,type);
                    p.offsetval = pos + 24;
                    p.Value = ReadValue(pcc, raw, pos + 24, type);
                    pos += p.Value.len + 24;
                    break;
            }
            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;
        }
예제 #9
0
        public static void ImportProperty(IMEPackage pcc, IMEPackage importpcc, Property p, string className, 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);
                    if (pcc.Game != MEGame.ME3)
                    {
                        m.Write(new byte[3], 0, 3);
                    }
                    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":
                    m.Write(BitConverter.GetBytes(p.Size), 0, 4);
                    m.Write(new byte[4], 0, 4);
                    if (pcc.Game == MEGame.ME3)
                    {
                        name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                        idxname2 = pcc.FindNameOrAdd(name2);
                        m.Write(BitConverter.GetBytes(idxname2), 0, 4);
                        m.Write(new byte[4], 0, 4);
                    }
                    if (p.Size != 1)
                    {
                        m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                        m.Write(new byte[4], 0, 4);
                    }
                    else
                    {
                        m.WriteByte(Convert.ToByte(p.Value.IntValue));
                    }
                    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 + '\0';
                    if (p.Value.len < 0)
                    {
                        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);
                        } 
                    }
                    else
                    {
                        m.Write(BitConverter.GetBytes(4 + name2.Length), 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);
                        }
                    }
                    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 == PropertyType.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);
                    PropertyInfo info = ME3UnrealObjectInfo.getPropertyInfo(className, name, inStruct);
                    ArrayType arrayType = ME3UnrealObjectInfo.getArrayType(info);
                    pos = 28;
                    List<Property> AllProps = new List<Property>();

                    if (arrayType == 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 || !ME3UnrealObjectInfo.isImmutable(info.reference)))
                    {
                        foreach (Property pp in AllProps)
                            ImportProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                    else if (arrayType == 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>
        /// Ports an export into a package. Checks if the export already exists, and if it does, returns that instead.
        /// </summary>
        /// <param name="targetPackage">The target package to port into.</param>
        /// <param name="sourceExport">The source export to port over, including all dependencies and references.</param>
        /// <param name="targetLink">The target link UIndex. Only used if createParentPackages is false.</param>
        /// <param name="createParentPackages">If the export should be ported in the same way as it was cooked into the package natively, e.g. create the parent package paths. The export must directly sit under a Package or an exception will be thrown.</param>
        /// <param name="ensureMemoryUniqueness">If this object is an instance, such as a sequence object, and should be made memory-unique so it is properly used</param>
        /// <returns></returns>
        public static ExportEntry PortExportIntoPackage(IMEPackage targetPackage, ExportEntry sourceExport, int targetLink = 0, bool createParentPackages = true, bool ensureMemoryUniqueness = false, bool useMemorySafeImport = false, PackageCache cache = null)
        {
#if DEBUG
            // in preprocessor to prevent this from running in release mode
            if (sourceExport.FileRef.FilePath != null && targetPackage.FilePath != null)
            {
                Debug.WriteLine($"Porting {sourceExport.InstancedFullPath} from {Path.GetFileName(sourceExport.FileRef.FilePath)} into {Path.GetFileName(targetPackage.FilePath)}");
            }
#endif
            var existing = targetPackage.FindExport(sourceExport.InstancedFullPath);
            if (existing != null)
            {
                return(existing);
            }

            // Create parent hierarchy
            IEntry newParent = null;
            if (createParentPackages)
            {
                List <IEntry> parents = new List <IEntry>();
                var           parent  = sourceExport.Parent;
                while (parent != null)
                {
                    if (parent.ClassName != "Package")
                    {
                        throw new Exception("Parent is not package!");
                    }
                    parents.Add(parent);
                    parent = parent.Parent;
                }

                // Create the parents
                parents.Reverse();
                foreach (var p in parents)
                {
                    var sourceFullPath = p.InstancedFullPath;
                    var matchingParent = targetPackage.FindEntry(sourceFullPath);

                    if (matchingParent != null)
                    {
                        newParent = matchingParent;
                        continue;
                    }

                    newParent = ExportCreator.CreatePackageExport(targetPackage, p.ObjectName, newParent);
                }
            }
            else
            {
                newParent = targetPackage.GetEntry(targetLink);
            }


            IEntry newEntry;
            if (!useMemorySafeImport)
            {
                Dictionary <IEntry, IEntry> crossPCCObjectMap = new Dictionary <IEntry, IEntry>(); // Not sure what this is used for these days. Should probably just be part of the method
                var relinkResults = EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneAllDependencies, sourceExport, targetPackage,
                                                                         newParent, true, out newEntry, crossPCCObjectMap);
                if (relinkResults.Any())
                {
                    Debugger.Break();
                }
            }
            else
            {
                // Memory safe, fixes upstream
                var relinkedResults = EntryExporter.ExportExportToPackage(sourceExport, targetPackage, out newEntry, MERFileSystem.GetGlobalCache(), cache);
                if (relinkedResults.Any())
                {
                    Debugger.Break();
                }
            }
#if DEBUG
            //(sourceExport.FileRef as MEPackage).CompareToPackageDetailed(targetPackage);
#endif

            // Helps ensure we don't have memory duplicates
            if (ensureMemoryUniqueness)
            {
                newEntry.ObjectName = targetPackage.GetNextIndexedName(newEntry.ObjectName);
            }

            return(newEntry as ExportEntry);
        }
예제 #11
0
 public void LoadME3Package(string s)
 {
     pcc?.Release(wpfWindow: this);
     Pcc = MEPackageHandler.OpenME3Package(s, wpfWindow: this);
 }
예제 #12
0
        /// <summary>
        /// Copies the inputstream to the outputstream, for the specified amount of bytes
        /// </summary>
        /// <param name="input">Stream to copy from</param>
        /// <param name="output">Stream to copy to</param>
        /// <param name="bytes">The number of bytes to copy</param>
        //public static void CopyToEx(this Stream input, Stream output, int bytes)
        //{
        //    var buffer = new byte[32768];
        //    int read;
        //    while (bytes > 0 &&
        //           (read = input.Read(buffer, 0, Math.Min(buffer.Length, bytes))) > 0)
        //    {
        //        output.Write(buffer, 0, read);
        //        bytes -= read;
        //    }
        //}

        public static NameReference ReadNameReference(this Stream stream, IMEPackage pcc)
        {
            return(new NameReference(pcc.getNameEntry(stream.ReadInt32()), stream.ReadInt32()));
        }
예제 #13
0
 public static void WriteNameReference(this Stream stream, NameReference name, IMEPackage pcc)
 {
     stream.WriteInt32(pcc.FindNameOrAdd(name.Name));
     stream.WriteInt32(name.Number);
 }
예제 #14
0
 public ImportEntry(IMEPackage pccFile)
 {
     FileRef = pccFile;
     Header  = new byte[byteSize];
 }
예제 #15
0
 public static void WriteDelegateProperty(this EndianWriter stream, IMEPackage pcc, NameReference propName, ScriptDelegate value, int staticArrayIndex)
 {
     stream.WritePropHeader(pcc, propName, PropertyType.DelegateProperty, 12, staticArrayIndex);
     stream.WriteInt32(value.Object);
     stream.WriteNameReference(value.FunctionName, pcc);
 }
예제 #16
0
 public static void WriteArrayProperty(this EndianWriter stream, IMEPackage pcc, NameReference propName, int count, Func <Stream> func, int staticArrayIndex)
 {
     stream.WriteArrayProperty(pcc, propName, count, func(), staticArrayIndex);
 }
예제 #17
0
 public static Property getPropOrNull(IMEPackage pcc, byte[] data, int start, string propName)
 {
     List<Property> props = ReadProp(pcc, data, start);
     foreach (Property prop in props)
     {
         if (pcc.getNameEntry(prop.Name) == propName)
         {
             return prop;
         }
     }
     return null;
 }
예제 #18
0
        public static PropertyCollection RemoveIncompatibleProperties(IMEPackage sourcePcc, PropertyCollection props, string typeName, MEGame newGame)
        {
            var infoProps = UnrealObjectInfo.GetAllProperties(newGame, typeName);

            infoProps.KeyComparer = StringComparer.OrdinalIgnoreCase;
            var newProps = new PropertyCollection();

            foreach (Property prop in props)
            {
                if (infoProps.ContainsKey(prop.Name))
                {
                    switch (prop)
                    {
                    case ArrayProperty <DelegateProperty> adp:
                        //don't think these exist? if they do, delete them
                        break;

                    case ArrayProperty <EnumProperty> aep:
                        if (UnrealObjectInfo.GetEnumValues(newGame, aep.Reference) is List <NameReference> enumValues)
                        {
                            foreach (EnumProperty enumProperty in aep)
                            {
                                if (!enumValues.Contains(enumProperty.Value))
                                {
                                    enumProperty.Value = enumValues.First();     //hope that the first value is a reasonable default
                                }
                            }
                            newProps.Add(aep);
                        }
                        break;

                    case ArrayProperty <ObjectProperty> asp:
                        for (int i = asp.Count - 1; i >= 0; i--)
                        {
                            if (asp[i].Value == 0 || sourcePcc.GetEntry(asp[i].Value) is IEntry entry && !entry.FullPath.StartsWith(UnrealPackageFile.TrashPackageName))
                            {
                                continue;
                            }
                            //delete if it references a trashed entry or if value is invalid
                            asp.RemoveAt(i);
                        }
                        newProps.Add(asp);
                        break;

                    case ArrayProperty <StructProperty> asp:
                        if (UnrealObjectInfo.GetStructs(newGame).ContainsKey(asp.Reference))
                        {
                            if (HasIncompatibleImmutabilities(asp.Reference, out bool newImmutability))
                            {
                                break;
                            }
                            foreach (StructProperty structProperty in asp)
                            {
                                structProperty.Properties  = RemoveIncompatibleProperties(sourcePcc, structProperty.Properties, structProperty.StructType, newGame);
                                structProperty.IsImmutable = newImmutability;
                            }
                            newProps.Add(asp);
                        }
                        break;

                    case DelegateProperty delegateProperty:
                        //script related, so just delete it.
                        break;

                    case EnumProperty enumProperty:
                        if (UnrealObjectInfo.GetEnumValues(newGame, enumProperty.EnumType) is List <NameReference> values)
                        {
                            if (!values.Contains(enumProperty.Value))
                            {
                                enumProperty.Value = values.First();     //hope that the first value is a reasonable default
                            }
                            newProps.Add(enumProperty);
                        }
                        break;

                    case ObjectProperty objectProperty:
                    {
                        if (objectProperty.Value == 0 || sourcePcc.GetEntry(objectProperty.Value) is IEntry entry && !entry.FullPath.StartsWith(UnrealPackageFile.TrashPackageName))
                        {
                            newProps.Add(objectProperty);
                        }
                        break;
                    }

                    case StructProperty structProperty:
                        string structType = structProperty.StructType;
                        if (UnrealObjectInfo.GetStructs(newGame).ContainsKey(structType))
                        {
                            if (HasIncompatibleImmutabilities(structType, out bool newImmutability))
                            {
                                break;
                            }
                            structProperty.Properties  = RemoveIncompatibleProperties(sourcePcc, structProperty.Properties, structType, newGame);
                            structProperty.IsImmutable = newImmutability;
                            newProps.Add(structProperty);
                        }
                        break;

                    default:
                        newProps.Add(prop);
                        break;
                    }
                }
            }

            return(newProps);

            bool HasIncompatibleImmutabilities(string structType, out bool newImmutability)
            {
                bool sourceIsImmutable = UnrealObjectInfo.IsImmutable(structType, sourcePcc.Game);

                newImmutability = UnrealObjectInfo.IsImmutable(structType, newGame);

                if (sourceIsImmutable && newImmutability && !UnrealObjectInfo.GetClassOrStructInfo(sourcePcc.Game, structType).properties
                    .SequenceEqual(UnrealObjectInfo.GetClassOrStructInfo(newGame, structType).properties))
                {
                    //both immutable, but have different properties
                    return(true);
                }

                if (!sourceIsImmutable && newImmutability)
                {
                    //can't easily guarantee it will have have all neccesary properties
                    return(true);
                }

                return(false);
            }
        }
예제 #19
0
        public static CustomProperty PropertyToGrid(Property p, IMEPackage pcc)
        {
            string cat = p.TypeVal.ToString();
            CustomProperty pg;
            NameProp pp;
            switch (p.TypeVal)
            {
                case PropertyType.BoolProperty :
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (p.Value.IntValue == 1), typeof(bool), false, true);
                    break;
                case PropertyType.FloatProperty: 
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.FloatValue, typeof(float), false, true);
                    break;
                case PropertyType.ByteProperty:
                    if (p.Size != 8)
                    {
                        pg = new CustomProperty(pcc.getNameEntry(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.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true);
                    }
                    break;
                case PropertyType.NameProperty:
                    pp = new NameProp();
                    pp.name = pcc.getNameEntry(p.Value.IntValue);
                    pp.nameindex = p.Value.IntValue;
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true);
                    break;
                case PropertyType.ObjectProperty:
                    ObjectProp ppo = new ObjectProp();
                    ppo.objectName = pcc.getObjectName(p.Value.IntValue);
                    ppo.index = p.Value.IntValue;
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppo, typeof(ObjectProp), false, true);
                    break;
                case PropertyType.StrProperty:
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.StringValue, typeof(string), false, true);
                    break;
                case PropertyType.ArrayProperty:
                    pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, BitConverter.ToInt32(p.raw,24) + " elements", typeof(string), false, true);
                    break;
                case PropertyType.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.getNameEntry(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.getNameEntry(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 = BitConverter.ToInt32(p.raw, 32) * 360f / 65536f;
                        rp.Yaw = BitConverter.ToInt32(p.raw, 36) * 360f / 65536f;
                        rp.Roll = BitConverter.ToInt32(p.raw, 40) * 360f / 65536f;
                        pg = new CustomProperty(pcc.getNameEntry(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.getNameEntry(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.getNameEntry(p.Name), cat, ppp, typeof(StructProp), false, true);
                    }
                    break;                    
                default:
                    pg = new CustomProperty(pcc.getNameEntry(p.Name),cat,p.Value.IntValue,typeof(int),false,true);
                    break;
            }
            return pg;
        }
        private static PropertyInfo getProperty(ExportEntry entry)
        {
            IMEPackage pcc = entry.FileRef;

            string       reference = null;
            PropertyType type;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return(new PropertyInfo(type, reference, transient));
        }
예제 #21
0
 static PropertyValue ReadValue(IMEPackage pcc, byte[] raw, int start, int type)
 {
     PropertyValue v = new PropertyValue();
     switch (pcc.getNameEntry(type))
     {
         case "IntProperty":
         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.Name = pcc.getNameEntry(v.IntValue);
             nameRef.count = BitConverter.ToInt32(raw, start + 4);
             if (nameRef.count > 0)
                 nameRef.Name += "_" + (nameRef.count - 1);
             v.NameValue = nameRef;
             v.StringValue = nameRef.Name;
             v.len = 8;
             break;
     }
     return v;
 }
예제 #22
0
        /// <summary>
        /// Attempts to relink unreal binary data to object pointers if they are part of the clone tree.
        /// It's gonna be an ugly mess.
        /// </summary>
        /// <param name="importpcc">PCC being imported from</param>
        private List <string> relinkBinaryObjects(IMEPackage importpcc)
        {
            List <string> relinkFailedReport = new List <string>();

            foreach (KeyValuePair <int, int> entry in crossPCCObjectMap)
            {
                if (entry.Key > 0)
                {
                    IExportEntry exp        = pcc.getExport(entry.Value);
                    byte[]       binarydata = exp.getBinaryData();
                    if (binarydata.Length > 0)
                    {
                        //has binary data
                        //This is temporary until I find a more permanent style for relinking binary
                        try
                        {
                            switch (exp.ClassName)
                            {
                            case "WwiseEvent":
                            {
                                int count = BitConverter.ToInt32(binarydata, 0);
                                for (int i = 0; i < count; i++)
                                {
                                    int  originalValue    = BitConverter.ToInt32(binarydata, 4 + (i * 4));
                                    int  currentObjectRef = unrealIndexToME3ExpIndexing(originalValue);        //count + i * intsize
                                    int  mapped;
                                    bool isMapped = crossPCCObjectMap.TryGetValue(currentObjectRef, out mapped);
                                    if (isMapped)
                                    {
                                        mapped = me3ExpIndexingToUnreal(mapped, originalValue < 0);         //if the value is 0, it would have an error anyways.
                                        Debug.WriteLine("Binary relink hit for WwiseEvent Export " + exp.UIndex + " 0x" + (4 + (i * 4)).ToString("X6") + " " + originalValue + " -> " + (mapped + 1));
                                        WriteMem(4 + (i * 4), binarydata, BitConverter.GetBytes(mapped));
                                        int newValue = BitConverter.ToInt32(binarydata, 4 + (i * 4));
                                        Debug.WriteLine(originalValue + " -> " + newValue);
                                    }
                                    else
                                    {
                                        Debug.WriteLine("Binary relink missed WwiseEvent Export " + exp.UIndex + " 0x" + (4 + (i * 4)).ToString("X6") + " " + originalValue);
                                        relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: WwiseEvent referenced WwiseStream " + originalValue + " is not in the mapping tree and could not be relinked");
                                    }
                                }
                                exp.setBinaryData(binarydata);
                            }
                            break;

                            case "Class":
                            {
                                if (exp.FileRef.Game != importpcc.Game)
                                {
                                    //Cannot relink against a different game.
                                    continue;
                                }
                                IExportEntry importingExp = importpcc.getExport(entry.Key);
                                if (importingExp.ClassName != "Class")
                                {
                                    continue;         //the class was not actually set, so this is not really class.
                                }

                                //This is going to be pretty ugly
                                try
                                {
                                    byte[] newdata = importpcc.Exports[entry.Key].Data;         //may need to rewrite first unreal header
                                    byte[] data    = importpcc.Exports[entry.Key].Data;

                                    int offset            = 0;
                                    int unrealExportIndex = BitConverter.ToInt32(data, offset);
                                    offset += 4;


                                    int superclassIndex = BitConverter.ToInt32(data, offset);
                                    if (superclassIndex < 0)
                                    {
                                        //its an import
                                        ImportEntry superclassImportEntry = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(superclassIndex))];
                                        ImportEntry newSuperclassValue    = getOrAddCrossImport(superclassImportEntry.GetFullPath, importpcc, exp.FileRef);
                                        WriteMem(offset, newdata, BitConverter.GetBytes(newSuperclassValue.UIndex));
                                    }
                                    else
                                    {
                                        relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Superclass is an export in the source package and was not relinked.");
                                    }


                                    int unknown1 = BitConverter.ToInt32(data, offset);
                                    offset += 4;

                                    int classObjTree = BitConverter.ToInt32(data, offset);         //Don't know if I need to do this.
                                    offset += 4;


                                    //I am not sure what these mean. However if Pt1&2 are 33/25, the following bytes that follow are extended.
                                    int   headerUnknown1 = BitConverter.ToInt32(data, offset);
                                    Int64 ignoreMask     = BitConverter.ToInt64(data, offset);
                                    offset += 8;

                                    Int16 labelOffset = BitConverter.ToInt16(data, offset);
                                    offset += 2;
                                    int skipAmount = 0x6;
                                    //Find end of script block. Seems to be 10 FF's.
                                    while (offset + skipAmount + 10 < data.Length)
                                    {
                                        //Debug.WriteLine("Cheecking at 0x"+(offset + skipAmount + 10).ToString("X4"));
                                        bool isEnd = true;
                                        for (int i = 0; i < 10; i++)
                                        {
                                            byte b = data[offset + skipAmount + i];
                                            if (b != 0xFF)
                                            {
                                                isEnd = false;
                                                break;
                                            }
                                        }
                                        if (isEnd)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            skipAmount++;
                                        }
                                    }

                                    int offsetEnd = offset + skipAmount + 10;
                                    offset += skipAmount + 10;         //heuristic to find end of script
                                    uint stateMask = BitConverter.ToUInt32(data, offset);
                                    offset += 4;

                                    int localFunctionsTableCount = BitConverter.ToInt32(data, offset);
                                    offset += 4;
                                    bool isMapped;
                                    for (int i = 0; i < localFunctionsTableCount; i++)
                                    {
                                        int           nameTableIndex = BitConverter.ToInt32(data, offset);
                                        int           nameIndex      = BitConverter.ToInt32(data, offset + 4);
                                        NameReference importingName  = importpcc.getNameEntry(nameTableIndex);
                                        int           newFuncName    = exp.FileRef.FindNameOrAdd(importingName);
                                        WriteMem(offset, newdata, BitConverter.GetBytes(newFuncName));
                                        offset += 8;

                                        int functionObjectIndex = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset));
                                        int mapped;
                                        isMapped = crossPCCObjectMap.TryGetValue(functionObjectIndex, out mapped);
                                        if (isMapped)
                                        {
                                            mapped = me3ExpIndexingToUnreal(mapped, functionObjectIndex < 0);         //if the value is 0, it would have an error anyways.
                                            WriteMem(offset, newdata, BitConverter.GetBytes(mapped));
                                        }
                                        else
                                        {
                                            relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Local function[" + i + "] could not be remapped during porting: " + functionObjectIndex + " is not in the mapping tree and could not be relinked");
                                        }
                                        offset += 4;
                                    }

                                    int classMask = BitConverter.ToInt32(data, offset);
                                    offset += 4;
                                    if (importpcc.Game != MEGame.ME3)
                                    {
                                        offset += 1;         //seems to be a blank byte here
                                    }

                                    int coreReference = BitConverter.ToInt32(data, offset);
                                    if (coreReference < 0)
                                    {
                                        //its an import
                                        ImportEntry outerclassReferenceImport = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(coreReference))];
                                        ImportEntry outerclassNewImport       = getOrAddCrossImport(outerclassReferenceImport.GetFullPath, importpcc, exp.FileRef);
                                        WriteMem(offset, newdata, BitConverter.GetBytes(outerclassNewImport.UIndex));
                                    }
                                    else
                                    {
                                        relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Outerclass is an export in the original package, not relinked.");
                                    }
                                    offset += 4;


                                    if (importpcc.Game == MEGame.ME3)
                                    {
                                        offset = ClassParser_RelinkComponentsTable(importpcc, exp, relinkFailedReport, ref newdata, offset);
                                        offset = ClassParser_ReadImplementsTable(importpcc, exp, relinkFailedReport, ref newdata, offset);
                                        int    postComponentsNoneNameIndex = BitConverter.ToInt32(data, offset);
                                        int    postComponentNoneIndex      = BitConverter.ToInt32(data, offset + 4);
                                        string postCompName = importpcc.getNameEntry(postComponentsNoneNameIndex);         //This appears to be unused in ME3, it is always None it seems.
                                        int    newFuncName  = exp.FileRef.FindNameOrAdd(postCompName);
                                        WriteMem(offset, newdata, BitConverter.GetBytes(newFuncName));
                                        offset += 8;

                                        int unknown4 = BitConverter.ToInt32(data, offset);
                                        offset += 4;
                                    }
                                    else
                                    {
                                        offset = ClassParser_ReadImplementsTable(importpcc, exp, relinkFailedReport, ref data, offset);
                                        offset = ClassParser_RelinkComponentsTable(importpcc, exp, relinkFailedReport, ref data, offset);

                                        int me12unknownend1 = BitConverter.ToInt32(data, offset);
                                        offset += 4;

                                        int me12unknownend2 = BitConverter.ToInt32(data, offset);
                                        offset += 4;
                                    }

                                    int defaultsClassLink = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset));
                                    int defClassLink;
                                    isMapped = crossPCCObjectMap.TryGetValue(defaultsClassLink, out defClassLink);
                                    if (isMapped)
                                    {
                                        defClassLink = me3ExpIndexingToUnreal(defClassLink, defaultsClassLink < 0);         //if the value is 0, it would have an error anyways.
                                        WriteMem(offset, newdata, BitConverter.GetBytes(defClassLink));
                                    }
                                    else
                                    {
                                        relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: DefaultsClassLink cannot be currently automatically relinked by Binary Relinker. Please manually set this in Binary Editor");
                                    }
                                    offset += 4;

                                    if (importpcc.Game == MEGame.ME3)
                                    {
                                        int functionsTableCount = BitConverter.ToInt32(data, offset);
                                        offset += 4;

                                        for (int i = 0; i < functionsTableCount; i++)
                                        {
                                            int functionsTableIndex = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset));
                                            int mapped;
                                            isMapped = crossPCCObjectMap.TryGetValue(functionsTableIndex, out mapped);
                                            if (isMapped)
                                            {
                                                mapped = me3ExpIndexingToUnreal(mapped, functionsTableIndex < 0);         //if the value is 0, it would have an error anyways.
                                                WriteMem(offset, newdata, BitConverter.GetBytes(mapped));
                                            }
                                            else
                                            {
                                                if (functionsTableIndex < 0)
                                                {
                                                    ImportEntry functionObjIndex    = importpcc.Imports[Math.Abs(functionsTableIndex)];
                                                    ImportEntry newFunctionObjIndex = getOrAddCrossImport(functionObjIndex.GetFullPath, importpcc, exp.FileRef);
                                                    WriteMem(offset, newdata, BitConverter.GetBytes(newFunctionObjIndex.UIndex));
                                                }
                                                else
                                                {
                                                    relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Full Functions List function[" + i + "] could not be remapped during porting: " + functionsTableIndex + " is not in the mapping tree and could not be relinked");
                                                }
                                            }
                                            offset += 4;
                                        }
                                    }
                                    exp.Data = newdata;
                                }
                                catch (Exception ex)
                                {
                                    relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Exception relinking: " + ex.Message);
                                }
                            }
                            break;

                            default:
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relinking failed: " + e.Message);
                        }
                        //Run an interpreter pass over it - we will find objectleafnodes and attempt to update the same offset in the destination file.
                        //BinaryInterpreter binaryrelinkInterpreter = new ME3Explorer.BinaryInterpreter(importpcc, importpcc.Exports[entry.Key], pcc, pcc.Exports[entry.Value], crossPCCObjectMapping);
                    }
                }
            }
            return(relinkFailedReport);
        }
예제 #23
0
 private void importImport(IMEPackage importpcc, int n, int link)
 {
     ImportEntry imp = importpcc.getImport(n);
     ImportEntry nimp = new ImportEntry(pcc, imp.header);
     nimp.idxLink = link;
     nimp.idxClassName = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxClassName));
     nimp.idxObjectName = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxObjectName));
     nimp.idxPackageFile = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxPackageFile));
     pcc.addImport(nimp);
 }
예제 #24
0
        public InterpCurve(IMEPackage _pcc, PropertyReader.Property p)
        {
            pcc = _pcc;

            Curves = new ObservableCollection<Curve>();
            Name = pcc.getNameEntry(p.Name);
            curveType = (CurveType)Enum.Parse(typeof(CurveType), pcc.getNameEntry(p.Value.IntValue));

            float InVal = 0f;
            CurveMode InterpMode = CurveMode.CIM_Linear;
            var points = PropertyReader.ReadStructArrayProp(pcc, PropertyReader.getPropOrNull(pcc, p.raw, 32, "Points"));
            switch (curveType)
            {
                case CurveType.InterpCurveQuat:
                    throw new NotImplementedException($"InterpCurveQuat has not been implemented yet.");
                case CurveType.InterpCurveFloat:
                    float OutVal = 0f;
                    float ArriveTangent = 0f;
                    float LeaveTangent = 0f;
                    LinkedList<CurvePoint> vals = new LinkedList<CurvePoint>();
                    foreach (var point in points)
                    {
                        foreach (var prop in point)
                        {
                            switch (pcc.getNameEntry(prop.Name))
                            {
                                case "InVal":
                                    InVal = BitConverter.ToSingle(prop.raw, 24);
                                    break;
                                case "OutVal":
                                    OutVal = BitConverter.ToSingle(prop.raw, 24);
                                    break;
                                case "ArriveTangent":
                                    ArriveTangent = BitConverter.ToSingle(prop.raw, 24);
                                    break;
                                case "LeaveTangent":
                                    LeaveTangent = BitConverter.ToSingle(prop.raw, 24);
                                    break;
                                case "InterpMode":
                                    InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue));
                                    break;
                                default:
                                    break;
                            }
                        }
                        vals.AddLast(new CurvePoint(InVal, OutVal, ArriveTangent, LeaveTangent, InterpMode));
                    }
                    Curves.Add(new Curve("X", vals));
                    break;
                case CurveType.InterpCurveVector:
                    Vector OutValVec = new Vector(0, 0, 0);
                    Vector ArriveTangentVec = new Vector(0, 0, 0);
                    Vector LeaveTangentVec = new Vector(0, 0, 0);
                    LinkedList<CurvePoint> x = new LinkedList<CurvePoint>();
                    LinkedList<CurvePoint> y = new LinkedList<CurvePoint>();
                    LinkedList<CurvePoint> z = new LinkedList<CurvePoint>();
                    foreach (var point in points)
                    {
                        foreach (var prop in point)
                        {
                            switch (pcc.getNameEntry(prop.Name))
                            {
                                case "InVal":
                                    InVal = BitConverter.ToSingle(prop.raw, 24);
                                    break;
                                case "OutVal":
                                    OutValVec = GetVector(prop);
                                    break;
                                case "ArriveTangent":
                                    ArriveTangentVec = GetVector(prop);
                                    break;
                                case "LeaveTangent":
                                    LeaveTangentVec = GetVector(prop);
                                    break;
                                case "InterpMode":
                                    InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue));
                                    break;
                                default:
                                    break;
                            }
                        }
                        x.AddLast(new CurvePoint(InVal, OutValVec.X, ArriveTangentVec.X, LeaveTangentVec.X, InterpMode));
                        y.AddLast(new CurvePoint(InVal, OutValVec.Y, ArriveTangentVec.Y, LeaveTangentVec.Y, InterpMode));
                        z.AddLast(new CurvePoint(InVal, OutValVec.Z, ArriveTangentVec.Z, LeaveTangentVec.Z, InterpMode));
                    }
                    if (Name == "EulerTrack")
                    {
                        Curves.Add(new Curve("Roll", x));
                        Curves.Add(new Curve("Pitch", y));
                        Curves.Add(new Curve("Yaw", z));
                    }
                    else
                    {
                        Curves.Add(new Curve("X", x));
                        Curves.Add(new Curve("Y", y));
                        Curves.Add(new Curve("Z", z)); 
                    }
                    break;
                case CurveType.InterpCurveVector2D:
                    throw new NotImplementedException($"InterpCurveVector2D has not been implemented yet.");
                case CurveType.InterpCurveTwoVectors:
                    throw new NotImplementedException($"InterpCurveTwoVectors has not been implemented yet.");
                case CurveType.InterpCurveLinearColor:
                    throw new NotImplementedException($"InterpCurveLinearColor has not been implemented yet.");
                default:
                    break;
            }
            foreach (var curve in Curves)
            {
                curve.SharedValueChanged += Curve_SharedValueChanged;
                curve.ListModified += Curve_ListModified;
            }
        }
예제 #25
0
 public SVar(int idx, float x, float y, IMEPackage p, GraphEditor grapheditor)
     : base(idx, p, grapheditor)
 {
     string s = export.ObjectName;
     s = s.Replace("BioSeqVar_", "");
     s = s.Replace("SFXSeqVar_", "");
     s = s.Replace("SeqVar_", "");
     type = getType(s);
     float w = 60;
     float h = 60;
     shape = PPath.CreateEllipse(0, 0, w, h);
     outlinePen = new Pen(getColor(type));
     shape.Pen = outlinePen;
     shape.Brush = nodeBrush;
     shape.Pickable = false;
     this.AddChild(shape);
     this.Bounds = new RectangleF(0, 0, w, h);
     val = new SText(GetValue());
     val.Pickable = false;
     val.TextAlignment = StringAlignment.Center;
     val.X = w / 2 - val.Width / 2;
     val.Y = h / 2 - val.Height / 2;
     this.AddChild(val);
     var props = export.GetProperties();
     foreach (var prop in props)
     {
         if (prop.Name == "VarName" || prop.Name == "varName")
         {
             SText VarName = new SText((prop as NameProperty).Value, Color.Red, false);
             VarName.Pickable = false;
             VarName.TextAlignment = StringAlignment.Center;
             VarName.X = w / 2 - VarName.Width / 2;
             VarName.Y = h;
             this.AddChild(VarName);
             break;
         }
     }
     this.TranslateBy(x, y);
     this.MouseEnter += OnMouseEnter;
     this.MouseLeave += OnMouseLeave;
 }
예제 #26
0
        //call this method to regenerate ME1ObjectInfo.json
        //Takes a long time (10 to 20 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo(string outpath)
        {
            Classes         = new Dictionary <string, ClassInfo>();
            Structs         = new Dictionary <string, ClassInfo>();
            Enums           = new Dictionary <string, List <NameReference> >();
            SequenceObjects = new Dictionary <string, SequenceObjectInfo>();
            foreach (string file in MELoadedFiles.GetOfficialFiles(MEGame.ME1))
            {
                if (Path.GetExtension(file) == ".upk" || Path.GetExtension(file) == ".sfm" || Path.GetExtension(file) == ".u")
                {
                    Debug.WriteLine($"File: {file}");
                    using IMEPackage pcc = MEPackageHandler.OpenME1Package(file);
                    for (int j = 1; j <= pcc.ExportCount; j++)
                    {
                        ExportEntry exportEntry = pcc.GetUExport(j);
                        string      className   = exportEntry.ClassName;
                        if (className == "Enum")
                        {
                            generateEnumValues(exportEntry);
                        }
                        else if (className == "Class")
                        {
                            string objectName = exportEntry.ObjectName;
                            Debug.WriteLine($"Generating information for {objectName}");
                            if (!Classes.ContainsKey(objectName))
                            {
                                Classes.Add(objectName, generateClassInfo(exportEntry));
                            }
                        }
                        else if (className == "ScriptStruct")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!Structs.ContainsKey(exportEntry.ObjectName))
                            {
                                Structs.Add(objectName, generateClassInfo(exportEntry, isStruct: true));
                            }
                        }
                        else if (exportEntry.IsA("SequenceObject"))
                        {
                            if (!SequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo))
                            {
                                seqObjInfo = new SequenceObjectInfo();
                                SequenceObjects.Add(className, seqObjInfo);
                            }

                            int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion");
                            if (objInstanceVersion > seqObjInfo.ObjInstanceVersion)
                            {
                                seqObjInfo.ObjInstanceVersion = objInstanceVersion;
                            }
                        }
                    }
                }
            }

            //CUSTOM ADDITIONS
            Classes["LightMapTexture2D"] = new ClassInfo
            {
                baseClass   = "Texture2D",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName
            };

            Classes["StaticMesh"] = new ClassInfo
            {
                baseClass   = "Object",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName,
                properties  =
                {
                    new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision",   new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision",        new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision",         new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("ForceDoubleSidedShadowVolumes", new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("BodySetup",                     new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")),
                    new KeyValuePair <string, PropertyInfo>("LODDistanceRatio",              new PropertyInfo(PropertyType.FloatProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex",       new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapResolution",            new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("SoundCue",                      new PropertyInfo(PropertyType.ObjectProperty, "SoundCue")),
                }
            };


            File.WriteAllText(outpath, JsonConvert.SerializeObject(new { SequenceObjects, Classes, Structs, Enums }, Formatting.Indented));
        }
예제 #27
0
        private int ClassParser_RelinkComponentsTable(IMEPackage importpcc, IExportEntry exp, List <string> relinkFailedReport, ref byte[] data, int offset)
        {
            if (importpcc.Game == MEGame.ME3)
            {
                int           componentTableNameIndex = BitConverter.ToInt32(data, offset);
                int           componentTableIndex     = BitConverter.ToInt32(data, offset + 4);
                NameReference importingName           = importpcc.getNameEntry(componentTableNameIndex);
                int           newComponentTableName   = exp.FileRef.FindNameOrAdd(importingName);
                WriteMem(offset, data, BitConverter.GetBytes(newComponentTableName));
                offset += 8;

                int componentTableCount = BitConverter.ToInt32(data, offset);
                offset += 4;

                for (int i = 0; i < componentTableCount; i++)
                {
                    int nameTableIndex = BitConverter.ToInt32(data, offset);
                    int nameIndex      = BitConverter.ToInt32(data, offset + 4);
                    importingName = importpcc.getNameEntry(nameTableIndex);
                    int componentName = exp.FileRef.FindNameOrAdd(importingName);
                    WriteMem(offset, data, BitConverter.GetBytes(componentName));
                    offset += 8;

                    int  componentObjectIndex = BitConverter.ToInt32(data, offset);
                    int  mapped;
                    bool isMapped = crossPCCObjectMap.TryGetValue(componentObjectIndex, out mapped);
                    if (isMapped)
                    {
                        mapped = me3ExpIndexingToUnreal(mapped, componentObjectIndex < 0); //if the value is 0, it would have an error anyways.
                        WriteMem(offset, data, BitConverter.GetBytes(mapped));
                    }
                    else
                    {
                        if (componentObjectIndex < 0)
                        {
                            ImportEntry componentObjectImport    = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(componentObjectIndex))];
                            ImportEntry newComponentObjectImport = getOrAddCrossImport(componentObjectImport.GetFullPath, importpcc, exp.FileRef);
                            WriteMem(offset, data, BitConverter.GetBytes(newComponentObjectImport.UIndex));
                        }
                        else if (componentObjectIndex > 0) //we do not remap on 0 here in binary land
                        {
                            relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Component[" + i + "] could not be remapped during porting: " + componentObjectIndex + " is not in the mapping tree");
                        }
                    }
                    offset += 4;
                }
            }
            else
            {
                int componentTableCount = BitConverter.ToInt32(data, offset);
                offset += 4;

                for (int i = 0; i < componentTableCount; i++)
                {
                    int nameTableIndex = BitConverter.ToInt32(data, offset);
                    int nameIndex      = BitConverter.ToInt32(data, offset + 4);

                    offset += 8;

                    int componentObjectIndex = BitConverter.ToInt32(data, offset);
                    if (componentObjectIndex != 0)
                    {
                        int  mapped;
                        bool isMapped = crossPCCObjectMap.TryGetValue(componentObjectIndex, out mapped);
                        if (isMapped)
                        {
                            mapped = me3ExpIndexingToUnreal(mapped, componentObjectIndex < 0); //if the value is 0, it would have an error anyways.
                            WriteMem(offset, data, BitConverter.GetBytes(mapped));
                        }
                        else
                        {
                            if (componentObjectIndex < 0)
                            {
                                ImportEntry componentObjectImport    = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(componentObjectIndex))];
                                ImportEntry newComponentObjectImport = getOrAddCrossImport(componentObjectImport.GetFullPath, importpcc, exp.FileRef);
                                WriteMem(offset, data, BitConverter.GetBytes(newComponentObjectImport.UIndex));
                            }
                            else
                            {
                                relinkFailedReport.Add("Binary Class Component[" + i + "] could not be remapped during porting: " + componentObjectIndex + " is not in the mapping tree");
                            }
                        }
                    }
                    offset += 4;
                }
            }
            return(offset);
        }
        public static IEntry GetEntry(Window owner, IMEPackage pcc, SupportedTypes supportedInputTypes, string directionsText = null)
        {
            var dlg = new EntrySelector(owner, pcc, supportedInputTypes, directionsText);

            return(dlg.ShowDialog() == true ? dlg.ChosenEntry : null);
        }
예제 #29
0
 public static void propGridPropertyValueChanged(PropertyValueChangedEventArgs e, int n, IMEPackage pcc)
 {
     string name = e.ChangedItem.Label;
     GridItem parent = e.ChangedItem.Parent;
     //if (parent != null) name = parent.Label;
     if (parent.Label == "data")
     {
         GridItem parent2 = parent.Parent;
         if (parent2 != null) name = parent2.Label;
     }
     Type parentVal = null;
     if (parent.Value != null)
     {
         parentVal = parent.Value.GetType();
     }
     if (name == "nameindex" || name == "index" || parentVal == typeof(ColorProp) || parentVal == typeof(VectorProp) || parentVal == typeof(Unreal.RotatorProp) || parentVal == typeof(Unreal.LinearColorProp))
     {
         name = parent.Label;
     }
     IExportEntry ent = pcc.getExport(n);
     byte[] data = ent.Data;
     List<PropertyReader.Property> p = PropertyReader.getPropList(ent);
     int m = -1;
     for (int i = 0; i < p.Count; i++)
         if (pcc.getNameEntry(p[i].Name) == name)
             m = i;
     if (m == -1)
         return;
     byte[] buff2;
     switch (p[m].TypeVal)
     {
         case PropertyType.BoolProperty:
             byte res = 0;
             if ((bool)e.ChangedItem.Value == true)
                 res = 1;
             data[p[m].offsetval] = res;
             break;
         case PropertyType.FloatProperty:
             buff2 = BitConverter.GetBytes((float)e.ChangedItem.Value);
             for (int i = 0; i < 4; i++)
                 data[p[m].offsetval + i] = buff2[i];
             break;
         case PropertyType.IntProperty:
         case PropertyType.StringRefProperty:
             int newv = Convert.ToInt32(e.ChangedItem.Value);
             int oldv = Convert.ToInt32(e.OldValue);
             buff2 = BitConverter.GetBytes(newv);
             for (int i = 0; i < 4; i++)
                 data[p[m].offsetval + i] = buff2[i];
             break;
         case PropertyType.StrProperty:
             string s = Convert.ToString(e.ChangedItem.Value);
             int stringMultiplier = 1;
             int oldLength = BitConverter.ToInt32(data, p[m].offsetval);
             if (oldLength < 0)
             {
                 stringMultiplier = 2;
                 oldLength *= -2;
             }
             int oldSize = 4 + oldLength;
             List<byte> stringBuff = new List<byte>(s.Length * stringMultiplier);
             if (stringMultiplier == 2)
             {
                 for (int j = 0; j < s.Length; j++)
                 {
                     stringBuff.AddRange(BitConverter.GetBytes(s[j]));
                 }
                 stringBuff.Add(0);
             }
             else
             {
                 for (int j = 0; j < s.Length; j++)
                 {
                     stringBuff.Add(BitConverter.GetBytes(s[j])[0]);
                 }
             }
             stringBuff.Add(0);
             buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier + 4);
             for (int j = 0; j < 4; j++)
                 data[p[m].offsetval - 8 + j] = buff2[j];
             buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier == 1 ? 1 : -1);
             for (int j = 0; j < 4; j++)
                 data[p[m].offsetval + j] = buff2[j];
             buff2 = new byte[data.Length - oldLength + stringBuff.Count];
             int startLength = p[m].offsetval + 4;
             int startLength2 = startLength + oldLength;
             for (int i = 0; i < startLength; i++)
             {
                 buff2[i] = data[i];
             }
             for (int i = 0; i < stringBuff.Count; i++)
             {
                 buff2[i + startLength] = stringBuff[i];
             }
             startLength += stringBuff.Count;
             for (int i = 0; i < data.Length - startLength2; i++)
             {
                 buff2[i + startLength] = data[i + startLength2];
             }
             data = buff2;
             break;
         case PropertyType.StructProperty:
             if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(ColorProp))
             {
                 switch (e.ChangedItem.Label)
                 {
                     case "Alpha":
                         data[p[m].offsetval + 11] = Convert.ToByte(e.ChangedItem.Value);
                         break;
                     case "Red":
                         data[p[m].offsetval + 10] = Convert.ToByte(e.ChangedItem.Value);
                         break;
                     case "Green":
                         data[p[m].offsetval + 9] = Convert.ToByte(e.ChangedItem.Value);
                         break;
                     case "Blue":
                         data[p[m].offsetval + 8] = Convert.ToByte(e.ChangedItem.Value);
                         break;
                     default:
                         break;
                 }
             }
             else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(VectorProp))
             {
                 int offset = 0;
                 switch (e.ChangedItem.Label)
                 {
                     case "X":
                         offset = 8;
                         break;
                     case "Y":
                         offset = 12;
                         break;
                     case "Z":
                         offset = 16;
                         break;
                     default:
                         break;
                 }
                 if (offset != 0)
                 {
                     buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value));
                     for (int i = 0; i < 4; i++)
                         data[p[m].offsetval + offset + i] = buff2[i];
                 }
             }
             else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.RotatorProp))
             {
                 int offset = 0;
                 switch (e.ChangedItem.Label)
                 {
                     case "Pitch":
                         offset = 8;
                         break;
                     case "Yaw":
                         offset = 12;
                         break;
                     case "Roll":
                         offset = 16;
                         break;
                     default:
                         break;
                 }
                 if (offset != 0)
                 {
                     int val = Convert.ToInt32(Convert.ToSingle(e.ChangedItem.Value) * 65536f / 360f);
                     buff2 = BitConverter.GetBytes(val);
                     for (int i = 0; i < 4; i++)
                         data[p[m].offsetval + offset + i] = buff2[i];
                 }
             }
             else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.LinearColorProp))
             {
                 int offset = 0;
                 switch (e.ChangedItem.Label)
                 {
                     case "Red":
                         offset = 8;
                         break;
                     case "Green":
                         offset = 12;
                         break;
                     case "Blue":
                         offset = 16;
                         break;
                     case "Alpha":
                         offset = 20;
                         break;
                     default:
                         break;
                 }
                 if (offset != 0)
                 {
                     buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value));
                     for (int i = 0; i < 4; i++)
                         data[p[m].offsetval + offset + i] = buff2[i];
                 }
             }
             else if (e.ChangedItem.Value is int)
             {
                 int val = Convert.ToInt32(e.ChangedItem.Value);
                 if (e.ChangedItem.Label == "nameindex")
                 {
                     int val1 = Convert.ToInt32(e.ChangedItem.Value);
                     buff2 = BitConverter.GetBytes(val1);
                     for (int i = 0; i < 4; i++)
                         data[p[m].offsetval + i] = buff2[i];
                 }
                 else
                 {
                     string sidx = e.ChangedItem.Label.Replace("[", "");
                     sidx = sidx.Replace("]", "");
                     int index = Convert.ToInt32(sidx);
                     buff2 = BitConverter.GetBytes(val);
                     for (int i = 0; i < 4; i++)
                         data[p[m].offsetval + i + index * 4 + 8] = buff2[i];
                 }
             }
             break;
         case PropertyType.ByteProperty:
         case PropertyType.NameProperty:
             if (e.ChangedItem.Value is int)
             {
                 int val = Convert.ToInt32(e.ChangedItem.Value);
                 buff2 = BitConverter.GetBytes(val);
                 for (int i = 0; i < 4; i++)
                     data[p[m].offsetval + i] = buff2[i];
             }
             break;
         case PropertyType.ObjectProperty:
             if (e.ChangedItem.Value is int)
             {
                 int val = Convert.ToInt32(e.ChangedItem.Value);
                 buff2 = BitConverter.GetBytes(val);
                 for (int i = 0; i < 4; i++)
                     data[p[m].offsetval + i] = buff2[i];
             }
             break;
         default:
             return;
     }
     ent.Data = data;
 }
예제 #30
0
        /// <summary>
        /// Adds an import from the importingPCC to the destinationPCC with the specified importFullName, or returns the existing one if it can be found.
        /// This method will look at importingPCC's import upstream chain and check for the most downstream one's existence in destinationPCC,
        /// including if none can be founc (in which case the entire upstream is copied). It will then create new imports to match the remaining
        /// downstream ones and return the originally named import, however now located in destinationPCC.
        /// </summary>
        /// <param name="importFullName">GetFullPath() of an import from ImportingPCC</param>
        /// <param name="importingPCC">PCC to import imports from</param>
        /// <param name="destinationPCC">PCC to add imports to</param>
        /// <returns></returns>
        private ImportEntry getOrAddCrossImport(string importFullName, IMEPackage importingPCC, IMEPackage destinationPCC, int?forcedLinkIdx = null)
        {
            //This code is kind of ugly, sorry.

            //see if this import exists locally
            foreach (ImportEntry imp in destinationPCC.Imports)
            {
                if (imp.GetFullPath == importFullName)
                {
                    return(imp);
                }
            }

            //Import doesn't exist, so we're gonna need to add it
            //But first we need to figure out what needs to be added upstream as links
            //Search upstream until we find something, or we can't get any more upstreams
            ImportEntry mostdownstreamimport = null;

            string[] importParts = importFullName.Split('.');

            if (!forcedLinkIdx.HasValue)
            {
                List <int> upstreamLinks = new List <int>(); //0 = top level, 1 = next level... n = what we wanted to import
                int        upstreamCount = 1;

                ImportEntry upstreamImport = null;
                //get number of required upstream imports that do not yet exist
                while (upstreamCount < importParts.Count())
                {
                    string upstream = String.Join(".", importParts, 0, importParts.Count() - upstreamCount);
                    foreach (ImportEntry imp in destinationPCC.Imports)
                    {
                        if (imp.GetFullPath == upstream)
                        {
                            upstreamImport = imp;
                            break;
                        }
                    }

                    if (upstreamImport != null)
                    {
                        //We found an upsteam import that already exists
                        break;
                    }
                    upstreamCount++;
                }

                IExportEntry donorUpstreamExport = null;
                if (upstreamImport == null)
                {
                    //We have to import the entire upstream chain
                    string      fullobjectname      = importParts[0];
                    ImportEntry donorTopLevelImport = null;
                    foreach (ImportEntry imp in importingPCC.Imports) //importing side info we will move to our dest pcc
                    {
                        if (imp.GetFullPath == fullobjectname)
                        {
                            donorTopLevelImport = imp;
                            break;
                        }
                    }

                    if (donorTopLevelImport == null)
                    {
                        //This is issue KinkoJiro had. It is aborting relinking at this step. Will need to find a way to
                        //work with exports as parents for imports which will block it.
                        //Update: This has been partially implemented.
                        Debug.WriteLine("No upstream import was found in the source file. It's probably an export: " + importFullName);
                        foreach (IExportEntry exp in destinationPCC.Exports) //importing side info we will move to our dest pcc
                        {
                            //Console.WriteLine(exp.GetFullPath);
                            if (exp.GetFullPath == fullobjectname)
                            {
                                // = imp;
                                //We will need to find a way to cross map this as this will block cross import mapping unless these exports already exist.
                                Debug.WriteLine("FOUND UPSTREAM, AS EXPORT!");
                                KFreonLib.Debugging.DebugOutput.StartDebugger("Package Editor Relinker");
                                KFreonLib.Debugging.DebugOutput.PrintLn("Error: Upstream item that is required is an export in the pcc to import from: " + fullobjectname);
                                donorUpstreamExport = exp;
                                upstreamCount--; //level 1 now from the top down
                                                 //Create new import with this as higher IDK
                                break;
                            }
                        }
                        if (donorUpstreamExport == null)
                        {
                            Debug.WriteLine("An error has occured. Could not find an upstream import or export for relinking: " + fullobjectname + " from " + pcc.FileName);
                            return(null);
                        }
                    }

                    if (donorUpstreamExport == null)
                    {
                        //Create new toplevel import and set that as the most downstream one. (top = bottom at this point)
                        int downstreamPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(donorTopLevelImport.PackageFile));
                        int downstreamClassName   = destinationPCC.FindNameOrAdd(donorTopLevelImport.ClassName);
                        int downstreamName        = destinationPCC.FindNameOrAdd(fullobjectname);

                        mostdownstreamimport = new ImportEntry(destinationPCC);
                        // mostdownstreamimport.idxLink = downstreamLinkIdx; ??
                        mostdownstreamimport.idxClassName   = downstreamClassName;
                        mostdownstreamimport.idxObjectName  = downstreamName;
                        mostdownstreamimport.idxPackageFile = downstreamPackageFile;
                        destinationPCC.addImport(mostdownstreamimport); //Add new top level downstream import
                        upstreamImport = mostdownstreamimport;
                        upstreamCount--;                                //level 1 now from the top down
                                                                        //return null;
                    }
                }

                //Have an upstream import, now we need to add downstream imports.
                while (upstreamCount > 0)
                {
                    upstreamCount--;
                    string      fullobjectname = String.Join(".", importParts, 0, importParts.Count() - upstreamCount);
                    ImportEntry donorImport    = null;

                    //Get or create names for creating import and get upstream linkIdx
                    int downstreamName = destinationPCC.FindNameOrAdd(importParts[importParts.Count() - upstreamCount - 1]);
                    foreach (ImportEntry imp in importingPCC.Imports) //importing side info we will move to our dest pcc
                    {
                        if (imp.GetFullPath == fullobjectname)
                        {
                            donorImport = imp;
                            break;
                        }
                    }
                    if (donorImport == null)
                    {
                        throw new Exception("No suitable upstream import was found for porting - this may be an export in the source file that is referenced as a parent or dependency. You should import this object and its parents first. " + fullobjectname + "(as part of " + importFullName + ")");
                    }

                    int downstreamPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(donorImport.PackageFile));
                    int downstreamClassName   = destinationPCC.FindNameOrAdd(donorImport.ClassName);

                    mostdownstreamimport                = new ImportEntry(destinationPCC);
                    mostdownstreamimport.idxLink        = donorUpstreamExport == null ? upstreamImport.UIndex : donorUpstreamExport.UIndex;
                    mostdownstreamimport.idxClassName   = downstreamClassName;
                    mostdownstreamimport.idxObjectName  = downstreamName;
                    mostdownstreamimport.idxPackageFile = downstreamPackageFile;
                    destinationPCC.addImport(mostdownstreamimport);
                    upstreamImport = mostdownstreamimport;
                }
            }
            else
            {
                //get importing import
                ImportEntry importingImport = importingPCC.Imports.FirstOrDefault(x => x.GetFullPath == importFullName); //this shouldn't be null
                mostdownstreamimport                = new ImportEntry(destinationPCC);
                mostdownstreamimport.idxLink        = forcedLinkIdx.Value;
                mostdownstreamimport.idxClassName   = destinationPCC.FindNameOrAdd(importingImport.ClassName);
                mostdownstreamimport.idxObjectName  = destinationPCC.FindNameOrAdd(importingImport.ObjectName);
                mostdownstreamimport.idxPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(importingImport.PackageFile));
                destinationPCC.addImport(mostdownstreamimport);
            }
            return(mostdownstreamimport);
        }
예제 #31
0
 public static void WriteArrayProperty(this Stream stream, IMEPackage pcc, string propName, int count, Func<MemoryStream> func)
 {
     stream.WriteArrayProperty(pcc, propName, count, func());
 }
예제 #32
0
        private string relinkObjectProperty(IMEPackage importingPCC, IMEPackage destinationPCC, ObjectProperty objProperty, List <KeyValuePair <int, int> > crossPCCObjectMappingList)
        {
            if (objProperty.Value == 0)
            {
                return(null); //do not relink 0
            }
            if (importingPCC == destinationPCC && objProperty.Value < 0)
            {
                return(null); //do not relink same-pcc imports.
            }
            int sourceObjReference = objProperty.Value;

            if (sourceObjReference > 0)
            {
                sourceObjReference--; //make 0 based for mapping.
            }
            if (sourceObjReference < 0)
            {
                sourceObjReference++; //make 0 based for mapping.
            }
            //if (objProperty.Name != null)
            //{
            //    Debug.WriteLine(objProperty.Name);
            //}
            KeyValuePair <int, int> mapping = crossPCCObjectMappingList.Where(pair => pair.Key == sourceObjReference).FirstOrDefault();
            var defaultKVP = default(KeyValuePair <int, int>); //struct comparison

            if (!mapping.Equals(defaultKVP))
            {
                //relink
                int newval = 0;
                if (mapping.Value > 0)
                {
                    newval = mapping.Value + 1; //reincrement
                }
                else if (mapping.Value < 0)
                {
                    newval = mapping.Value - 1; //redecrement
                }
                objProperty.Value = (newval);
                IEntry entry = destinationPCC.getEntry(newval);
                string s     = "";
                if (entry != null)
                {
                    s = entry.GetFullPath;
                }
                Debug.WriteLine("Relink hit: " + sourceObjReference + objProperty.Name + ": " + s);
            }
            else if (objProperty.Value < 0) //It's an unmapped import
            {
                //objProperty is currently pointing to importingPCC as that is where we read the properties from
                int n               = objProperty.Value;
                int origvalue       = n;
                int importZeroIndex = Math.Abs(n) - 1;
                //Debug.WriteLine("Relink miss, attempting JIT relink on " + n + " " + rootNode.Text);
                if (n < 0 && importZeroIndex < importingPCC.ImportCount)
                {
                    //Get the original import
                    ImportEntry origImport         = importingPCC.getImport(importZeroIndex);
                    string      origImportFullName = origImport.GetFullPath;
                    //Debug.WriteLine("We should import " + origImport.GetFullPath);

                    ImportEntry crossImport          = null;
                    string      linkFailedDueToError = null;
                    try
                    {
                        crossImport = getOrAddCrossImport(origImportFullName, importingPCC, destinationPCC);
                    }
                    catch (Exception e)
                    {
                        //Error during relink
                        KFreonLib.Debugging.DebugOutput.StartDebugger("PCC Relinker");
                        DebugOutput.PrintLn("Exception occured during relink: ");
                        DebugOutput.PrintLn(ExceptionHandlerDialogWPF.FlattenException(e));
                        DebugOutput.PrintLn("You may want to consider discarding this sessions' changes as relinking was not able to properly finish.");
                        linkFailedDueToError = e.Message;
                    }
                    if (crossImport != null)
                    {
                        //cache item. Imports are stored +1, Exports-1. Someday I will go back and make this just 0 indexed
                        crossPCCObjectMappingList.Add(new KeyValuePair <int, int>(sourceObjReference, crossImport.UIndex + 1)); //add to mapping to speed up future relinks
                        objProperty.Value = crossImport.UIndex;
                        Debug.WriteLine("Relink hit: Dynamic CrossImport for " + origvalue + " " + importingPCC.getEntry(origvalue).GetFullPath + " -> " + objProperty.Value);
                    }
                    else
                    {
                        if (linkFailedDueToError != null)
                        {
                            Debug.WriteLine("Relink failed: CrossImport porting failed for " + objProperty.Name + " " + objProperty.Value + ": " + importingPCC.getEntry(origvalue).GetFullPath);
                            return("Relink failed for " + objProperty.Name + " " + objProperty.Value + ": " + linkFailedDueToError);
                        }
                        else
                        if (destinationPCC.getEntry(objProperty.Value) != null)
                        {
                            Debug.WriteLine("Relink failed: CrossImport porting failed for " + objProperty.Name + " " + objProperty.Value + ": " + importingPCC.getEntry(origvalue).GetFullPath);
                            return("Relink failed: CrossImport porting failed for " + objProperty.Name + " " + objProperty.Value + " " + destinationPCC.getEntry(objProperty.Value).GetFullPath);
                        }
                        else
                        {
                            return("Relink failed: New export does not exist - this is probably a bug in cross import code for " + objProperty.Name + " " + objProperty.Value);
                        }
                    }
                }
            }
            else
            {
                string path = importingPCC.getEntry(objProperty.Value) != null?importingPCC.getEntry(objProperty.Value).GetFullPath : "Entry not found: " + objProperty.Value;

                Debug.WriteLine("Relink failed: " + objProperty.Name + " " + objProperty.Value + " " + path);
                return("Relink failed: " + objProperty.Name + " " + objProperty.Value + " " + path);
            }
            return(null);
        }
예제 #33
0
 public static void WriteStringRefProperty(this Stream stream, IMEPackage pcc, string propName, int value)
 {
     stream.WritePropHeader(pcc, propName, PropertyType.StringRefProperty, 4);
     stream.WriteValueS32(value);
 }
예제 #34
0
 public override void WriteTo(Stream ms, IMEPackage pcc, int fileOffset)
 {
     ms.WriteFromBuffer(data);
 }
예제 #35
0
 public static void WriteStructPropVector(this Stream stream, IMEPackage pcc, string propName, float x, float y, float z)
 {
     MemoryStream m = new MemoryStream(12);
     m.WriteValueF32(x);
     m.WriteValueF32(y);
     m.WriteValueF32(z);
     stream.WriteStructProperty(pcc, propName, "Vector", m.ToArray());
 }
예제 #36
0
 public override byte[] ToArray(IMEPackage pcc, int fileOffset = 0)
 {
     return(data);
 }
예제 #37
0
 public static string PropertyToText(Property p, IMEPackage pcc)
 {
     string s = "";
     s = "Name: " + pcc.getNameEntry(p.Name);
     s += " Type: " + TypeToString((int)p.TypeVal);
     s += " Size: " + p.Size;
     switch (p.TypeVal)
     {
         case PropertyType.StructProperty:
             s += " \"" + pcc.getNameEntry (p.Value.IntValue) + "\" with " + p.Value.Array.Count + " bytes";
             break;
         case PropertyType.IntProperty:                
         case PropertyType.ObjectProperty:
         case PropertyType.StringRefProperty :
             s += " Value: " + p.Value.IntValue;
             break;
         case PropertyType.BoolProperty:
             s += " Value: " + (p.raw[24] == 1);
             break;
         case PropertyType.FloatProperty:
             s += " Value: " + p.Value.FloatValue;
             break;
         case PropertyType.NameProperty:
             s += " " + pcc.getNameEntry(p.Value.IntValue);
             break;
         case PropertyType.ByteProperty:
             s += " Value: \"" + p.Value.StringValue + "\" with \"" + pcc.getNameEntry(p.Value.IntValue) + "\"";
             break;
         case PropertyType.ArrayProperty:
             s += " bytes"; //Value: " + p.Value.Array.Count.ToString() + " Elements";
             break;
         case PropertyType.StrProperty:
             if (p.Value.StringValue.Length == 0)
                 break;
             s += " Value: " + p.Value.StringValue;
             break;
     }
     return s;
 }
예제 #38
0
        public static void propGridPropertyValueChanged(PropertyValueChangedEventArgs e, int n, IMEPackage pcc)
        {
            string   name   = e.ChangedItem.Label;
            GridItem parent = e.ChangedItem.Parent;

            //if (parent != null) name = parent.Label;
            if (parent.Label == "data")
            {
                GridItem parent2 = parent.Parent;
                if (parent2 != null)
                {
                    name = parent2.Label;
                }
            }
            Type parentVal = null;

            if (parent.Value != null)
            {
                parentVal = parent.Value.GetType();
            }
            if (name == "nameindex" || name == "index" || parentVal == typeof(ColorProp) || parentVal == typeof(VectorProp) || parentVal == typeof(Unreal.RotatorProp) || parentVal == typeof(Unreal.LinearColorProp))
            {
                name = parent.Label;
            }
            IExportEntry ent = pcc.getExport(n);

            byte[] data = ent.Data;
            List <PropertyReader.Property> p = PropertyReader.getPropList(ent);
            int m = -1;

            for (int i = 0; i < p.Count; i++)
            {
                if (pcc.getNameEntry(p[i].Name) == name)
                {
                    m = i;
                }
            }
            if (m == -1)
            {
                return;
            }
            byte[] buff2;
            switch (p[m].TypeVal)
            {
            case PropertyType.BoolProperty:
                byte res = 0;
                if ((bool)e.ChangedItem.Value == true)
                {
                    res = 1;
                }
                data[p[m].offsetval] = res;
                break;

            case PropertyType.FloatProperty:
                buff2 = BitConverter.GetBytes((float)e.ChangedItem.Value);
                for (int i = 0; i < 4; i++)
                {
                    data[p[m].offsetval + i] = buff2[i];
                }
                break;

            case PropertyType.IntProperty:
            case PropertyType.StringRefProperty:
                int newv = Convert.ToInt32(e.ChangedItem.Value);
                int oldv = Convert.ToInt32(e.OldValue);
                buff2 = BitConverter.GetBytes(newv);
                for (int i = 0; i < 4; i++)
                {
                    data[p[m].offsetval + i] = buff2[i];
                }
                break;

            case PropertyType.StrProperty:
                string s = Convert.ToString(e.ChangedItem.Value);
                int    stringMultiplier = 1;
                int    oldLength        = BitConverter.ToInt32(data, p[m].offsetval);
                if (oldLength < 0)
                {
                    stringMultiplier = 2;
                    oldLength       *= -2;
                }
                int         oldSize    = 4 + oldLength;
                List <byte> stringBuff = new List <byte>(s.Length * stringMultiplier);
                if (stringMultiplier == 2)
                {
                    for (int j = 0; j < s.Length; j++)
                    {
                        stringBuff.AddRange(BitConverter.GetBytes(s[j]));
                    }
                    stringBuff.Add(0);
                }
                else
                {
                    for (int j = 0; j < s.Length; j++)
                    {
                        stringBuff.Add(BitConverter.GetBytes(s[j])[0]);
                    }
                }
                stringBuff.Add(0);
                buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier + 4);
                for (int j = 0; j < 4; j++)
                {
                    data[p[m].offsetval - 8 + j] = buff2[j];
                }
                buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier == 1 ? 1 : -1);
                for (int j = 0; j < 4; j++)
                {
                    data[p[m].offsetval + j] = buff2[j];
                }
                buff2 = new byte[data.Length - oldLength + stringBuff.Count];
                int startLength  = p[m].offsetval + 4;
                int startLength2 = startLength + oldLength;
                for (int i = 0; i < startLength; i++)
                {
                    buff2[i] = data[i];
                }
                for (int i = 0; i < stringBuff.Count; i++)
                {
                    buff2[i + startLength] = stringBuff[i];
                }
                startLength += stringBuff.Count;
                for (int i = 0; i < data.Length - startLength2; i++)
                {
                    buff2[i + startLength] = data[i + startLength2];
                }
                data = buff2;
                break;

            case PropertyType.StructProperty:
                if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(ColorProp))
                {
                    switch (e.ChangedItem.Label)
                    {
                    case "Alpha":
                        data[p[m].offsetval + 11] = Convert.ToByte(e.ChangedItem.Value);
                        break;

                    case "Red":
                        data[p[m].offsetval + 10] = Convert.ToByte(e.ChangedItem.Value);
                        break;

                    case "Green":
                        data[p[m].offsetval + 9] = Convert.ToByte(e.ChangedItem.Value);
                        break;

                    case "Blue":
                        data[p[m].offsetval + 8] = Convert.ToByte(e.ChangedItem.Value);
                        break;

                    default:
                        break;
                    }
                }
                else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(VectorProp))
                {
                    int offset = 0;
                    switch (e.ChangedItem.Label)
                    {
                    case "X":
                        offset = 8;
                        break;

                    case "Y":
                        offset = 12;
                        break;

                    case "Z":
                        offset = 16;
                        break;

                    default:
                        break;
                    }
                    if (offset != 0)
                    {
                        buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value));
                        for (int i = 0; i < 4; i++)
                        {
                            data[p[m].offsetval + offset + i] = buff2[i];
                        }
                    }
                }
                else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.RotatorProp))
                {
                    int offset = 0;
                    switch (e.ChangedItem.Label)
                    {
                    case "Pitch":
                        offset = 8;
                        break;

                    case "Yaw":
                        offset = 12;
                        break;

                    case "Roll":
                        offset = 16;
                        break;

                    default:
                        break;
                    }
                    if (offset != 0)
                    {
                        int val = Convert.ToSingle(e.ChangedItem.Value).ToUnrealRotationUnits();
                        buff2 = BitConverter.GetBytes(val);
                        for (int i = 0; i < 4; i++)
                        {
                            data[p[m].offsetval + offset + i] = buff2[i];
                        }
                    }
                }
                else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.LinearColorProp))
                {
                    int offset = 0;
                    switch (e.ChangedItem.Label)
                    {
                    case "Red":
                        offset = 8;
                        break;

                    case "Green":
                        offset = 12;
                        break;

                    case "Blue":
                        offset = 16;
                        break;

                    case "Alpha":
                        offset = 20;
                        break;

                    default:
                        break;
                    }
                    if (offset != 0)
                    {
                        buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value));
                        for (int i = 0; i < 4; i++)
                        {
                            data[p[m].offsetval + offset + i] = buff2[i];
                        }
                    }
                }
                else if (e.ChangedItem.Value is int)
                {
                    int val = Convert.ToInt32(e.ChangedItem.Value);
                    if (e.ChangedItem.Label == "nameindex")
                    {
                        int val1 = Convert.ToInt32(e.ChangedItem.Value);
                        buff2 = BitConverter.GetBytes(val1);
                        for (int i = 0; i < 4; i++)
                        {
                            data[p[m].offsetval + i] = buff2[i];
                        }
                    }
                    else
                    {
                        string sidx = e.ChangedItem.Label.Replace("[", "");
                        sidx = sidx.Replace("]", "");
                        int index = Convert.ToInt32(sidx);
                        buff2 = BitConverter.GetBytes(val);
                        for (int i = 0; i < 4; i++)
                        {
                            data[p[m].offsetval + i + index * 4 + 8] = buff2[i];
                        }
                    }
                }
                break;

            case PropertyType.ByteProperty:
            case PropertyType.NameProperty:
                if (e.ChangedItem.Value is int)
                {
                    int val = Convert.ToInt32(e.ChangedItem.Value);
                    buff2 = BitConverter.GetBytes(val);
                    for (int i = 0; i < 4; i++)
                    {
                        data[p[m].offsetval + i] = buff2[i];
                    }
                }
                break;

            case PropertyType.ObjectProperty:
                if (e.ChangedItem.Value is int)
                {
                    int val = Convert.ToInt32(e.ChangedItem.Value);
                    buff2 = BitConverter.GetBytes(val);
                    for (int i = 0; i < 4; i++)
                    {
                        data[p[m].offsetval + i] = buff2[i];
                    }
                }
                break;

            default:
                return;
            }
            ent.Data = data;
        }
예제 #39
0
 public static List<List<Property>> ReadStructArrayProp(IMEPackage pcc, Property p)
 {
     List<List<Property>> res = new List<List<Property>>();
     int pos = 28;
     int linkCount = BitConverter.ToInt32(p.raw, 24);
     for (int i = 0; i < linkCount; i++)
     {
         List<Property> p2 = ReadProp(pcc, p.raw, pos);
         for (int j = 0; j < p2.Count(); j++)
         {
             pos += p2[j].raw.Length;
         }
         res.Add(p2);
     }
     return res;
 }
        public static Dictionary <IEntry, List <string> > FindUsagesOfName(this IMEPackage pcc, string name)
        {
            var result = new Dictionary <IEntry, List <string> >();

            foreach (ExportEntry exp in pcc.Exports)
            {
                try
                {
                    //find header references
                    if (exp.ObjectName.Name == name)
                    {
                        result.AddToListAt(exp, "Header: Object Name");
                    }
                    if (exp.HasComponentMap && exp.ComponentMap.Any(kvp => kvp.Key.Name == name))
                    {
                        result.AddToListAt(exp, "Header: ComponentMap");
                    }

                    if ((!exp.IsDefaultObject && exp.IsOrInheritsFrom("Component") || pcc.Game == MEGame.UDK && exp.ClassName.EndsWith("Component")) &&
                        exp.ParentFullPath.Contains("Default__") &&
                        exp.DataSize >= 12 && BitConverter.ToInt32(exp.Data, 4) is int nameIdx && pcc.IsName(nameIdx) &&
                        pcc.GetNameEntry(nameIdx) == name)
                    {
                        result.AddToListAt(exp, "Component TemplateName (0x4)");
                    }

                    //find property references
                    findPropertyReferences(exp.GetProperties(), exp, false, "Property: ");

                    //find binary references
                    if (!exp.IsDefaultObject && ObjectBinary.From(exp) is { } objBin)
                    {
                        if (objBin is BioStage bioStage)
                        {
                            if (bioStage.length > 0 && name == "m_aCameraList")
                            {
                                result.AddToListAt(exp, "(Binary prop: m_aCameraList name)");
                            }
                            int i = 0;
                            foreach ((NameReference key, PropertyCollection props) in bioStage.CameraList)
                            {
                                if (key.Name == name)
                                {
                                    result.AddToListAt(exp, $"(Binary prop: m_aCameraList[{i}])");
                                }
                                findPropertyReferences(props, exp, false, "Binary prop: m_aCameraList[{i}].");
                                ++i;
                            }
                        }
                        else if (objBin is UScriptStruct scriptStruct)
                        {
                            findPropertyReferences(scriptStruct.Defaults, exp, false, "Binary Property:");
                        }
                        else
                        {
                            List <(NameReference, string)> names = objBin.GetNames(exp.FileRef.Game);
                            foreach ((NameReference nameRef, string propName) in names)
                            {
                                if (nameRef.Name == name)
                                {
                                    result.AddToListAt(exp, $"(Binary prop: {propName})");
                                }
                            }
                        }
                    }
                }
                catch
                {
                    result.AddToListAt(exp, "Exception occured while reading this export!");
                }
            }

            foreach (ImportEntry import in pcc.Imports)
            {
                try
                {
                    if (import.ObjectName.Name == name)
                    {
                        result.AddToListAt(import, "ObjectName");
                    }
                    if (import.PackageFile == name)
                    {
                        result.AddToListAt(import, "PackageFile");
                    }
                    if (import.ClassName == name)
                    {
                        result.AddToListAt(import, "Class");
                    }
                }
                catch (Exception e)
                {
                    result.AddToListAt(import, "Exception occured while reading this import!");
                }
            }

            return(result);

            void findPropertyReferences(PropertyCollection props, ExportEntry exp, bool isInImmutable = false, string prefix = "")
            {
                foreach (UProperty prop in props)
                {
                    if (!isInImmutable && prop.Name.Name == name)
                    {
                        result.AddToListAt(exp, $"{prefix}{prop.Name} name");
                    }
                    switch (prop)
                    {
                    case NameProperty nameProperty:
                        if (nameProperty.Value.Name == name)
                        {
                            result.AddToListAt(exp, $"{prefix}{nameProperty.Name} value");
                        }
                        break;

                    case DelegateProperty delegateProperty:
                        if (delegateProperty.Value.FunctionName.Name == name)
                        {
                            result.AddToListAt(exp, $"{prefix}{delegateProperty.Name} function name");
                        }
                        break;

                    case EnumProperty enumProperty:
                        if (pcc.Game >= MEGame.ME3 && !isInImmutable && enumProperty.EnumType.Name == name)
                        {
                            result.AddToListAt(exp, $"{prefix}{enumProperty.Name} enum type");
                        }
                        if (enumProperty.Value.Name == name)
                        {
                            result.AddToListAt(exp, $"{prefix}{enumProperty.Name} enum value");
                        }
                        break;

                    case StructProperty structProperty:
                        if (!isInImmutable && structProperty.StructType == name)
                        {
                            result.AddToListAt(exp, $"{prefix}{structProperty.Name} struct type");
                        }
                        findPropertyReferences(structProperty.Properties, exp, structProperty.IsImmutable, $"{prefix}{structProperty.Name}: ");
                        break;

                    case ArrayProperty <NameProperty> arrayProperty:
                        for (int i = 0; i < arrayProperty.Count; i++)
                        {
                            NameProperty nameProp = arrayProperty[i];
                            if (nameProp.Value.Name == name)
                            {
                                result.AddToListAt(exp, $"{prefix}{arrayProperty.Name}[{i}]");
                            }
                        }
                        break;

                    case ArrayProperty <EnumProperty> arrayProperty:
                        for (int i = 0; i < arrayProperty.Count; i++)
                        {
                            EnumProperty enumProp = arrayProperty[i];
                            if (enumProp.Value.Name == name)
                            {
                                result.AddToListAt(exp, $"{prefix}{arrayProperty.Name}[{i}]");
                            }
                        }
                        break;

                    case ArrayProperty <StructProperty> arrayProperty:
                        for (int i = 0; i < arrayProperty.Count; i++)
                        {
                            StructProperty structProp = arrayProperty[i];
                            findPropertyReferences(structProp.Properties, exp, structProp.IsImmutable, $"{prefix}{arrayProperty.Name}[{i}].");
                        }
                        break;
                    }
                }
            }
        }
예제 #41
0
 static PropertyType getType(IMEPackage pcc, int type)
 {
     switch (pcc.getNameEntry(type))
     {
         case "None": return PropertyType.None;
         case "StructProperty": return PropertyType.StructProperty;
         case "IntProperty": return PropertyType.IntProperty;
         case "FloatProperty": return PropertyType.FloatProperty;
         case "ObjectProperty": return PropertyType.ObjectProperty;
         case "NameProperty": return PropertyType.NameProperty;
         case "BoolProperty": return PropertyType.BoolProperty;
         case "ByteProperty": return PropertyType.ByteProperty;
         case "ArrayProperty": return PropertyType.ArrayProperty;
         case "DelegateProperty": return PropertyType.DelegateProperty;
         case "StrProperty": return PropertyType.StrProperty;
         case "StringRefProperty": return PropertyType.StringRefProperty;                    
         default:
             return PropertyType.Unknown;
     }
 }
예제 #42
0
 public PathNode_Dynamic(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
     shape.Brush = dynamicPathnodefindingNodeBrush;
 }
예제 #43
0
 public static int detectStart(IMEPackage pcc, byte[] raw, ulong flags)
 {
     if ((flags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
     {
         if (pcc.Game != MEGame.ME3)
         {
             return 32; 
         }
         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;
 }
예제 #44
0
 public CoverLink(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #45
0
 private bool importTree(TreeNode sourceNode, IMEPackage importpcc, int n)
 {
     int nextIndex;
     int index;
     foreach (TreeNode node in sourceNode.Nodes)
     {
         index = Convert.ToInt32(node.Name);
         if (index >= 0)
         {
             if (!importExport(importpcc, index, n))
             {
                 return false;
             }
             nextIndex = pcc.ExportCount;
         }
         else
         {
             importImport(importpcc, -index - 1, n);
             nextIndex = -pcc.ImportCount;
         }
         if (node.Nodes.Count > 0)
         {
             if (!importTree(node, importpcc, nextIndex))
             {
                 return false;
             }
         }
     }
     return true;
 }
예제 #46
0
 public SFXNav_JumpDownNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #47
0
 private bool importExport(IMEPackage importpcc, int n, int link)
 {
     IExportEntry ex = importpcc.getExport(n);
     IExportEntry nex = null;
     switch (pcc.Game)
     {
         case MEGame.ME1:
             nex = new ME1ExportEntry(pcc as ME1Package);
             break;
         case MEGame.ME2:
             nex = new ME2ExportEntry(pcc as ME2Package);
             break;
         case MEGame.ME3:
             nex = new ME3ExportEntry(pcc as ME3Package);
             break;
     }
     byte[] idata = ex.Data;
     PropertyCollection props = ex.GetProperties();
     int start = ex.GetPropertyStart();
     int end = props.endOffset;
     MemoryStream res = new MemoryStream();
     if ((importpcc.getExport(n).ObjectFlags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
     {
         byte[] stackdummy = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //Lets hope for the best :D
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,};
         if (pcc.Game != MEGame.ME3)
         {
             stackdummy = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,};
         }
         res.Write(stackdummy, 0, stackdummy.Length);
     }
     else
     {
         res.Write(new byte[start], 0, start);
     }
     //store copy of names list in case something goes wrong
     List<string> names = pcc.Names.ToList();
     try
     {
         props.WriteTo(res, pcc);
     }
     catch (Exception exception)
     {
         //restore namelist
         pcc.setNames(names);
         MessageBox.Show("Error occured while trying to import " + ex.ObjectName + " : " + exception.Message);
         return false;
     }
     if (importpcc.Game == MEGame.ME3 && importpcc.getObjectName(ex.idxClass) == "SkeletalMesh")
     {
         SkeletalMesh skl = new SkeletalMesh(importpcc as ME3Package, n);
         SkeletalMesh.BoneStruct bone;
         for (int i = 0; i < skl.Bones.Count; i++)
         {
             bone = skl.Bones[i];
             string s = importpcc.getNameEntry(bone.Name);
             bone.Name = pcc.FindNameOrAdd(s);
             skl.Bones[i] = bone;
         }
         SkeletalMesh.TailNamesStruct tailName;
         for (int i = 0; i < skl.TailNames.Count; i++)
         {
             tailName = skl.TailNames[i];
             string s = importpcc.getNameEntry(tailName.Name);
             tailName.Name = pcc.FindNameOrAdd(s);
             skl.TailNames[i] = tailName;
         }
         SerializingContainer container = new SerializingContainer(res);
         container.isLoading = false;
         skl.Serialize(container);
     }
     else
     {
         res.Write(idata, end, idata.Length - end);
     }
     nex.setHeader((byte[])ex.header.Clone());
     nex.Data = res.ToArray();
     nex.idxObjectName = pcc.FindNameOrAdd(importpcc.getNameEntry(ex.idxObjectName));
     nex.idxLink = link;
     nex.idxArchtype = nex.idxClass = nex.idxClassParent = 0;
     pcc.addExport(nex);
     return true;
 }
예제 #48
0
 public SFXNav_LeapNodeHumanoid(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #49
0
 public SAction(int idx, float x, float y, IMEPackage p)
     : base(idx, p)
 {
     GetVarLinks();
     GetOutputLinks();
     originalX = x;
     originalY = y;
 }
예제 #50
0
 public PendingNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #51
0
 public SFrame(int idx, float x, float y, IMEPackage p, GraphEditor grapheditor)
     : base(idx, p, grapheditor)
 {
     string s = export.ObjectName;
     float w = 0;
     float h = 0;
     var props = export.GetProperties();
     foreach (var prop in props)
     {
         if (prop.Name == "SizeX")
         {
             w = (prop as IntProperty);
         }
         if (prop.Name == "SizeY")
         {
             h = (prop as IntProperty);
         }
     }
     MakeTitleBox(s);
     shape = PPath.CreateRectangle(0, -titleBox.Height, w, h + titleBox.Height);
     outlinePen = new Pen(Color.Black);
     shape.Pen = outlinePen;
     shape.Brush = new SolidBrush(Color.Transparent);
     shape.Pickable = false;
     this.AddChild(shape);
     titleBox.TranslateBy(0, -titleBox.Height);
     this.AddChild(titleBox);
     comment.Y -= titleBox.Height;
     this.Bounds = new RectangleF(0, -titleBox.Height, titleBox.Width, titleBox.Height);
     this.TranslateBy(x, y);
 }
예제 #52
0
 public SFXDynamicCoverSlotMarker(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
     shape.Brush = dynamicPathfindingNodeBrush;
 }
예제 #53
0
 protected SBox(int idx, IMEPackage p)
     : base(idx, p)
 {
     
 }
예제 #54
0
 public MantleMarker(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #55
0
 public SEvent(int idx, float x, float y, IMEPackage p, GraphEditor grapheditor)
     : base(idx, p, grapheditor)
 {
     outlinePen = new Pen(Color.FromArgb(214, 30, 28));
     string s = export.ObjectName;
     s = s.Replace("BioSeqEvt_", "");
     s = s.Replace("SFXSeqEvt_", "");
     s = s.Replace("SeqEvt_", "");
     s = s.Replace("SeqEvent_", "");
     float starty = 0;
     float w = 15;
     float midW = 0;
     varLinkBox = new PPath();
     GetVarLinks();
     for (int i = 0; i < Varlinks.Count; i++)
     {
         string d = "";
         foreach (int l in Varlinks[i].Links)
             d = d + "#" + l + ",";
         d = d.Remove(d.Length - 1);
         SText t2 = new SText( d + "\n" + Varlinks[i].Desc);
         t2.X = w;
         t2.Y = 0;
         w += t2.Width + 20;
         t2.Pickable = false;
         Varlinks[i].node.TranslateBy(t2.X + t2.Width / 2, t2.Y + t2.Height);
         t2.AddChild(Varlinks[i].node);
         varLinkBox.AddChild(t2);
     }
     if(Varlinks.Count != 0)
         varLinkBox.AddRectangle(0, 0, w, varLinkBox[0].Height);
     varLinkBox.Pickable = false;
     varLinkBox.Pen = outlinePen;
     varLinkBox.Brush = nodeBrush;
     GetOutputLinks();
     outLinkBox = new PPath();
     for (int i = 0; i < Outlinks.Count(); i++)
     {
         SText t2 = new SText(Outlinks[i].Desc);
         if(t2.Width + 10 > midW) midW = t2.Width + 10;
         //t2.TextAlignment = StringAlignment.Far;
         //t2.ConstrainWidthToTextWidth = false;
         t2.X = 0 - t2.Width;
         t2.Y = starty + 3;
         starty += t2.Height + 6;
         t2.Pickable = false;
         Outlinks[i].node.TranslateBy(0, t2.Y + t2.Height / 2);
         t2.AddChild(Outlinks[i].node);
         outLinkBox.AddChild(t2);
     }
     outLinkBox.AddPolygon(new PointF[] { new PointF(0, 0), new PointF(0, starty), new PointF(-0.5f*midW, starty+30), new PointF(0 - midW, starty), new PointF(0 - midW, 0), new PointF(midW/-2, -30) });
     outLinkBox.Pickable = false;
     outLinkBox.Pen = outlinePen;
     outLinkBox.Brush = nodeBrush;
     var props = export.GetProperties();
     foreach (var prop in props)
     {
         if (prop.Name.Name.Contains("EventName") || prop.Name == "sScriptName")
             s += "\n\"" + (prop as NameProperty) + "\"";
         else if (prop.Name == "InputLabel" || prop.Name == "sEvent")
             s += "\n\"" + (prop as StrProperty) + "\"";
     }
     float tW = GetTitleBox(s, w);
     if (tW > w)
     {
         if (midW > tW)
         {
             w = midW;
             titleBox.Width = w;
         }
         else
         {
             w = tW;
         }
         varLinkBox.Width = w;
     }
     float h = titleBox.Height + 1;
     outLinkBox.TranslateBy(titleBox.Width/2 + midW/2, h + 30);
     h += outLinkBox.Height + 1;
     varLinkBox.TranslateBy(0, h);
     h += varLinkBox.Height;
     this.bounds = new RectangleF(0, 0, w, h);
     this.AddChild(titleBox);
     this.AddChild(varLinkBox);
     this.AddChild(outLinkBox);
     this.TranslateBy(x, y);
 }
예제 #56
0
        };                                                                                                                         //Bottom part of H

        public SFXNav_HarvesterMoveNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
            : base(idx, x, y, p, grapheditor)
        {
        }
예제 #57
0
 public TreeNode FindSequences(IMEPackage pcc, int index, bool wantFullName = false)
 {
     TreeNode ret = new TreeNode("#" + index + ": " + (wantFullName ? pcc.getExport(index).GetFullPath : pcc.getExport(index).ObjectName));
     ret.Name = index.ToString();
     var seqObjs = pcc.getExport(index).GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects");
     if (seqObjs != null)
     {
         IExportEntry exportEntry;
         foreach (ObjectProperty seqObj in seqObjs)
         {
             exportEntry = pcc.getExport(seqObj.Value - 1);
             if (exportEntry.ClassName == "Sequence" || exportEntry.ClassName.StartsWith("PrefabSequence"))
             {
                 TreeNode t = FindSequences(pcc, seqObj.Value - 1, false);
                 ret.Nodes.Add(t);
             }
             else if (exportEntry.ClassName == "SequenceReference")
             {
                 var propSequenceReference = exportEntry.GetProperty<ObjectProperty>("oSequenceReference");
                 if (propSequenceReference != null)
                 {
                     TreeNode t = FindSequences(pcc, propSequenceReference.Value - 1, false);
                     ret.Nodes.Add(t);
                 }
             }
         }
     }
     return ret;
 }
예제 #58
0
 public SFXNav_LargeMantleNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor)
     : base(idx, x, y, p, grapheditor)
 {
 }
예제 #59
0
 public static void WriteArrayProperty(this Stream stream, IMEPackage pcc, string propName, int count, MemoryStream value)
 {
     stream.WritePropHeader(pcc, propName, PropertyType.ArrayProperty, 4 + (int)value.Length);
     stream.WriteValueS32(count);
     stream.WriteStream(value);
 }
예제 #60
0
        public static PropertyCollection getDefaultStructValue(string className, bool stripTransients)
        {
            bool isImmutable = UnrealObjectInfo.IsImmutable(className, MEGame.ME1);

            if (Structs.ContainsKey(className))
            {
                ClassInfo info = Structs[className];
                try
                {
                    PropertyCollection structProps = new PropertyCollection();
                    ClassInfo          tempInfo    = info;
                    while (tempInfo != null)
                    {
                        foreach ((string propName, PropertyInfo propInfo) in tempInfo.properties)
                        {
                            if (stripTransients && propInfo.Transient)
                            {
                                continue;
                            }
                            if (getDefaultProperty(propName, propInfo, stripTransients, isImmutable) is Property uProp)
                            {
                                structProps.Add(uProp);
                            }
                        }
                        if (!Structs.TryGetValue(tempInfo.baseClass, out tempInfo))
                        {
                            tempInfo = null;
                        }
                    }
                    structProps.Add(new NoneProperty());
                    string filepath = null;
                    if (ME1Directory.BioGamePath != null)
                    {
                        filepath = Path.Combine(ME1Directory.BioGamePath, info.pccPath);
                    }

                    Stream loadStream = null;
                    if (File.Exists(info.pccPath)) //dynamic lookup (relative path)
                    {
                        filepath   = info.pccPath;
                        loadStream = new MemoryStream(File.ReadAllBytes(info.pccPath));
                    }
                    else if (info.pccPath == UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName)
                    {
                        filepath   = "GAMERESOURCES_ME1";                                                                                       //used for cache
                        loadStream = Utilities.LoadFileFromCompressedResource("GameResources.zip", CoreLib.CustomResourceFileName(MEGame.ME1)); // should this be ME3 (it was originally before corelib move)
                    }
                    else if (filepath != null && File.Exists(filepath))
                    {
                        loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                    }
#if AZURE
                    else if (MiniGameFilesPath != null && File.Exists(Path.Combine(MiniGameFilesPath, info.pccPath)))
                    {
                        filepath = Path.Combine(MiniGameFilesPath, info.pccPath);

                        // Load from test minigame folder. This is only really useful on azure where we don't have access to
                        // games
                        loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                    }
#endif
                    if (loadStream == null)
                    {
                        filepath = Path.Combine(ME1Directory.DefaultGamePath, info.pccPath); //for files from ME1 DLC
                        if (File.Exists(filepath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                        }
                    }
                    if (loadStream != null)
                    {
                        using (IMEPackage importPCC = MEPackageHandler.OpenMEPackageFromStream(loadStream, filepath, useSharedPackageCache: true))
                        {
                            var                exportToRead = importPCC.GetUExport(info.exportIndex);
                            byte[]             buff         = exportToRead.Data.Skip(0x30).ToArray();
                            PropertyCollection defaults     = PropertyCollection.ReadProps(exportToRead, new MemoryStream(buff), className);
                            foreach (var prop in defaults)
                            {
                                structProps.TryReplaceProp(prop);
                            }
                        }
                    }
                    return(structProps);
                }
                catch
                {
                    return(null);
                }
            }
            return(null);
        }