예제 #1
0
        /// <summary>
        /// Generates the methods of a class.
        /// </summary>
        /// <param name="classObj">The class object.</param>
        /// <returns>Return The methods of the class.</returns>
        private async Task <List <Method> > GenerateMethods(GenericTypes.UEClass classObj)
        {
            var methods = new List <Method>();

            //some classes (AnimBlueprintGenerated...) have multiple members with the same name, so filter them out
            var uniqueMethods = new List <string>();

            // prop can be UEObject, UEField, UEProperty
            for (var prop = (await classObj.GetChildren()).Cast <GenericTypes.UEField>(); prop.IsValid(); prop = await prop.GetNext())
            {
                if (!await prop.IsA <GenericTypes.UEFunction>())
                {
                    continue;
                }

                var function = prop.Cast <GenericTypes.UEFunction>();

                var m = new Method
                {
                    Index    = function.GetIndex(),
                    FullName = await function.GetFullName(),
                    Name     = Generator.GetSafeKeywordsName(NameValidator.MakeValidName(await function.GetName()))
                };

                if (uniqueMethods.Contains(m.FullName))
                {
                    continue;
                }

                uniqueMethods.Add(m.FullName);

                m.IsNative    = (await function.GetFunctionFlags()).HasFlag(UEFunctionFlags.Native);
                m.IsStatic    = (await function.GetFunctionFlags()).HasFlag(UEFunctionFlags.Static);
                m.FlagsString = FunctionFlags.StringifyFlags(await function.GetFunctionFlags());

                var parameters = new List <KeyValuePair <GenericTypes.UEProperty, Method.Parameter> >();
                var unique     = new Dictionary <string, int>();
                for (var param = (await function.GetChildren()).Cast <GenericTypes.UEProperty>(); param.IsValid(); param = (await param.GetNext()).Cast <GenericTypes.UEProperty>())
                {
                    if (await param.GetElementSize() == 0)
                    {
                        continue;
                    }

                    var info = await param.GetInfo();

                    if (info.Type == GenericTypes.UEProperty.PropertyType.Unknown)
                    {
                        continue;
                    }

                    var p = new Method.Parameter(UnrealVersion.Unreal4);

                    if (!p.MakeType(await param.GetPropertyFlags(), out p.ParamType))
                    {
                        //child isn't a parameter
                        continue;
                    }

                    p.PassByReference = false;
                    p.Name            = NameValidator.MakeValidName(await param.GetName());

                    if (!unique.ContainsKey(p.Name))
                    {
                        unique[p.Name] = 1;
                    }
                    else
                    {
                        unique[p.Name]++;
                        p.Name += unique[p.Name];
                    }

                    p.FlagsString = PropertyFlags.StringifyFlags(await param.GetPropertyFlags());
                    p.CppType     = info.CppType;

                    if (await param.IsA <GenericTypes.UEBoolProperty>())
                    {
                        p.CppType = Generator.GetOverrideType("bool");
                    }

                    if (p.ParamType == Method.Parameter.Type.Default)
                    {
                        if (await param.GetArrayDim() > 1)
                        {
                            p.CppType += "*";
                        }
                        else if (info.CanBeReference)
                        {
                            p.PassByReference = true;
                        }
                    }

                    p.Name = Generator.GetSafeKeywordsName(p.Name);
                    parameters.Add(new KeyValuePair <GenericTypes.UEProperty, Method.Parameter>(param, p));
                }

                parameters.Sort((lhs, rhs) => ComparePropertyLess(lhs.Key, rhs.Key).Result ? 0 : 1);

                foreach (var param in parameters)
                {
                    m.Parameters.Add(param.Value);
                }

                methods.Add(m);
            }

            return(methods);
        }
예제 #2
0
        /// <summary>
        /// Generates the members of a struct or class.
        /// </summary>
        /// <param name="structObj">The structure object.</param>
        /// <param name="offset">The start offset.</param>
        /// <param name="properties">The properties describing the members.</param>
        /// <returns>The members of the struct or class.</returns>
        private async Task <List <Member> > GenerateMembers(GenericTypes.UEStruct structObj, int offset, List <GenericTypes.UEProperty> properties)
        {
            var members                  = new List <Member>();
            var uniqueMemberNames        = new Dictionary <string, int>();
            int unknownDataCounter       = 0;
            var previousBitfieldProperty = new GenericTypes.UEBoolProperty();

            foreach (var prop in properties)
            {
                if (offset < await prop.GetOffset())
                {
                    int size = await prop.GetOffset() - offset;

                    members.Add(CreatePadding(unknownDataCounter++, offset, size, "MISSED OFFSET"));
                }

                var info = await prop.GetInfo();

                if (info.Type != GenericTypes.UEProperty.PropertyType.Unknown)
                {
                    var sp = new Member
                    {
                        Offset = await prop.GetOffset(),
                        Size   = info.Size,
                        Type   = info.CppType,
                        Name   = NameValidator.MakeValidName(await prop.GetName())
                    };

                    if (!uniqueMemberNames.ContainsKey(sp.Name))
                    {
                        uniqueMemberNames[sp.Name] = 1;
                    }
                    else
                    {
                        uniqueMemberNames[sp.Name]++;
                        sp.Name += uniqueMemberNames[sp.Name];
                    }

                    if (await prop.GetArrayDim() > 1)
                    {
                        sp.Name += $"[0x{await prop.GetArrayDim():X}]";
                    }

                    if (await prop.IsA <GenericTypes.UEBoolProperty>() && await prop.Cast <GenericTypes.UEBoolProperty>().IsBitfield())
                    {
                        var boolProp    = prop.Cast <GenericTypes.UEBoolProperty>();
                        var missingBits = await boolProp.GetMissingBitsCount(previousBitfieldProperty);

                        if (missingBits[1] != -1)
                        {
                            if (missingBits[0] > 0)
                            {
                                members.Add(CreateBitfieldPadding(unknownDataCounter++, await previousBitfieldProperty.GetOffset(), info.CppType, missingBits[0]));
                            }
                            if (missingBits[1] > 0)
                            {
                                members.Add(CreateBitfieldPadding(unknownDataCounter++, sp.Offset, info.CppType, missingBits[1]));
                            }
                        }
                        else if (missingBits[0] > 0)
                        {
                            members.Add(CreateBitfieldPadding(unknownDataCounter++, sp.Offset, info.CppType, missingBits[0]));
                        }

                        previousBitfieldProperty = boolProp;
                        sp.Name += " : 1";
                    }

                    sp.Name  = Generator.GetSafeKeywordsName(sp.Name);
                    sp.Flags = (int)await prop.GetPropertyFlags();

                    sp.FlagsString = PropertyFlags.StringifyFlags(await prop.GetPropertyFlags());

                    members.Add(sp);

                    int sizeMismatch = (await prop.GetElementSize() * await prop.GetArrayDim()) - (info.Size * await prop.GetArrayDim());
                    if (sizeMismatch > 0)
                    {
                        members.Add(CreatePadding(unknownDataCounter++, offset, sizeMismatch, "FIX WRONG TYPE SIZE OF PREVIOUS PROPERTY"));
                    }
                }
                else
                {
                    var size = await prop.GetElementSize() * await prop.GetArrayDim();

                    members.Add(CreatePadding(unknownDataCounter++, offset, size, "UNKNOWN PROPERTY: " + await prop.GetFullName()));
                }

                offset = await prop.GetOffset() + await prop.GetElementSize() * await prop.GetArrayDim();
            }

            if (offset < await structObj.GetPropertySize())
            {
                int size = await structObj.GetPropertySize() - offset;

                members.Add(CreatePadding(unknownDataCounter, offset, size, "MISSED OFFSET"));
            }

            return(members);
        }