public SetObjectTypeParam AddParameter(string name, Type dataType)
        {
            var param = new SetObjectTypeParam(name, dataType);

            Parameters.Add(param);
            return(param);
        }
        protected XElement GenerateParam(SetObjectTypeParam param)
        {
            var paramElement = new XElement(param.Name);

            if (param is SetObjectTypeParamGroup group)
            {
                foreach (var p in group.Parameters)
                {
                    paramElement.Add(GenerateParam(p));
                }
            }
            else
            {
                // TODO
                string typeName = new Microsoft.CSharp.CSharpCodeProvider()
                                  .GetTypeOutput(new System.CodeDom.CodeTypeReference(param.DataType));

                paramElement.Add(new XAttribute("type", typeName));
                paramElement.Add(new XAttribute("default", param.DefaultValue));
            }

            paramElement.Add(new XAttribute("description", param.Description));
            return(paramElement);
        }
Exemplo n.º 3
0
        public void ExportXML(Stream fileStream,
                              Dictionary <string, SetObjectType> objectTemplates = null)
        {
            // Convert to XML file and save
            var rootElem = new XElement("SetData");

            foreach (var obj in Objects)
            {
                // Generate Object Element
                var objElem   = new XElement("Object");
                var typeAttr  = new XAttribute("type", obj.ObjectType);
                var objIDAttr = new XAttribute("id", obj.ObjectID);

                // Generate CustomData Element
                var customDataElem = new XElement("CustomData");
                foreach (var customData in obj.CustomData)
                {
                    customDataElem.Add(GenerateParamElement(
                                           customData.Value, customData.Key));
                }

                // Generate Parameters Element
                SetObjectTypeParam p;
                var paramsElem = new XElement("Parameters");
                var template   = (objectTemplates != null && objectTemplates.ContainsKey(obj.ObjectType)) ?
                                 objectTemplates[obj.ObjectType] : null;

                for (int i = 0; i < obj.Parameters.Count; ++i)
                {
                    p = template?.Parameters[i];
                    paramsElem.Add(GenerateParamElement(
                                       obj.Parameters[i], p?.Name, p));
                }

                // Generate Transforms Element
                var transformElem  = GenerateTransformElement(obj.Transform);
                var transformsElem = new XElement("Transforms", transformElem);

                foreach (var transform in obj.Children)
                {
                    transformsElem.Add(GenerateTransformElement(transform));
                }

                // Add all of this to the XDocument
                objElem.Add(typeAttr, objIDAttr, customDataElem,
                            paramsElem, transformsElem);
                rootElem.Add(objElem);
            }

            var xml = new XDocument(rootElem);

            xml.Save(fileStream);

            // Sub-Methods
            XElement GenerateParamElement(SetObjectParam param,
                                          string name = "Parameter", SetObjectTypeParam paramTemp = null)
            {
                // Groups
                if (param is SetObjectParamGroup group)
                {
                    var e = new XElement((string.IsNullOrEmpty(name)) ?
                                         "Group" : name);

                    if (group.Padding.HasValue)
                    {
                        e.Add(new XAttribute("padding", group.Padding.Value));
                    }

                    SetObjectTypeParam p;
                    var templateGroup = (paramTemp as SetObjectTypeParamGroup);
                    var parameters    = group.Parameters;

                    for (int i = 0; i < parameters.Count; ++i)
                    {
                        p = templateGroup?.Parameters[i];
                        e.Add(GenerateParamElement(parameters[i], p?.Name, p));
                    }

                    return(e);
                }

                // Parameters
                var dataType     = param.DataType;
                var dataTypeAttr = new XAttribute("type", dataType.Name);

                if (dataType == typeof(ForcesSetData.ObjectReference))
                {
                    dataTypeAttr.Value = "ForcesObjectReference";
                }

                var elem = new XElement((string.IsNullOrEmpty(name)) ?
                                        "Parameter" : name, dataTypeAttr);

                if (dataType == typeof(Vector2))
                {
                    Helpers.XMLWriteVector2(elem, (Vector2)param.Data);
                }
                else if (dataType == typeof(Vector3))
                {
                    Helpers.XMLWriteVector3(elem, (Vector3)param.Data);
                }
                else if (dataType == typeof(Vector4) || dataType == typeof(Quaternion))
                {
                    Helpers.XMLWriteVector4(elem, (Vector4)param.Data);
                }
                else if (dataType == typeof(uint[]))
                {
                    var arr = (param.Data as uint[]);
                    elem.Add(new XAttribute("count", (arr == null) ? 0 : arr.Length));

                    if (arr == null)
                    {
                        return(elem);
                    }

                    elem.Value = string.Join(",", arr);
                }
                else if (dataType == typeof(ForcesSetData.ObjectReference[]))
                {
                    var arr = (param.Data as ForcesSetData.ObjectReference[]);
                    dataTypeAttr.Value = "ForcesObjectList";
                    elem.Add(new XAttribute("count", (arr == null) ? 0 : arr.Length));

                    if (arr == null)
                    {
                        return(elem);
                    }

                    foreach (var v in arr)
                    {
                        var objRefElem = new XElement("ForcesObjectReference");
                        v.ExportXML(objRefElem);
                        elem.Add(objRefElem);
                    }
                }
                else if (dataType == typeof(ForcesSetData.ObjectReference))
                {
                    var objRef = (param.Data as ForcesSetData.ObjectReference);
                    objRef.ExportXML(elem);
                }
                else
                {
                    elem.Value = param.Data.ToString();
                }

                return(elem);
            }

            XElement GenerateTransformElement(
                SetObjectTransform transform, string name = "Transform")
            {
                // Convert Position/Rotation/Scale into elements.
                var posElem   = new XElement("Position");
                var rotElem   = new XElement("Rotation");
                var scaleElem = new XElement("Scale");

                Helpers.XMLWriteVector3(posElem, transform.Position);
                Helpers.XMLWriteVector4(rotElem, transform.Rotation);
                Helpers.XMLWriteVector3(scaleElem, transform.Scale);

                // Add elements to new transform element and return it.
                return(new XElement(name, posElem, rotElem, scaleElem));
            }
        }
        protected SetObjectParam ReadParameter(BINAReader reader, SetObjectTypeParam param)
        {
            FixPadding(reader, param.DataType);

            // Special Param Types
            if (param is SetObjectTypeParamGroup group)
            {
                var g           = new SetObjectParamGroup(group.Padding);
                var groupParams = g.Parameters;

                foreach (var p in group.Parameters)
                {
                    groupParams.Add(ReadParameter(reader, p));
                }

                reader.FixPadding(group.Padding ?? 16);
                return(g);
            }
            else if (param.DataType == typeof(ObjectReference[]))
            {
                long  arrOffset  = reader.ReadInt64();
                ulong arrLength  = reader.ReadUInt64();
                ulong arrLength2 = reader.ReadUInt64();
                long  curPos     = reader.BaseStream.Position;

                if (arrLength != arrLength2)
                {
                    Console.WriteLine(
                        "WARNING: ArrLength ({0}) != ArrLength2 ({1})",
                        arrLength, arrLength2);
                }

                var arr = new ObjectReference[arrLength];
                if (arrLength > 0 && arrOffset > 0)
                {
                    reader.JumpTo(arrOffset, false);
                    for (uint i = 0; i < arrLength; ++i)
                    {
                        arr[i] = new ObjectReference(reader);
                    }

                    reader.JumpTo(curPos);
                }

                return(new SetObjectParam(param.DataType, arr));
            }
            else if (param.DataType == typeof(ObjectReference))
            {
                return(new SetObjectParam(typeof(ObjectReference),
                                          new ObjectReference(reader)));
            }
            else if (param.DataType == typeof(string))
            {
                var  stringParam   = new SetObjectParam(typeof(string), string.Empty);
                long offset        = reader.ReadInt64();
                long stringPadding = reader.ReadInt64();

                if (offset > 0)
                {
                    long curPos = reader.BaseStream.Position;
                    reader.JumpTo(offset, false);
                    stringParam.Data = reader.ReadNullTerminatedString();
                    reader.JumpTo(curPos);
                }

                if (stringPadding != 0)
                {
                    Console.WriteLine("WARNING: String Padding != 0 ({0:X})!!", stringPadding);
                }

                //reader.FixPadding(16);
                return(stringParam);
            }

            // Data
            var objParam = new SetObjectParam(param.DataType,
                                              reader.ReadByType(param.DataType));

            // Post-Param Padding
            if (param.DataType == typeof(Vector3))
            {
                uint vecPadding = reader.ReadUInt32();
                if (vecPadding != 0)
                {
                    Console.WriteLine("WARNING: Vector Padding != 0 ({0:X})!!", vecPadding);
                }
            }

            return(objParam);
        }
        protected void ReadParam(XElement element, List <SetObjectTypeParam> group)
        {
            string elemName = element.Name.LocalName;
            var    typeAttr = element.Attribute("type");
            var    descAttr = element.Attribute("description");

            if (typeAttr == null)
            {
                var  paddingAttr = element.Attribute("padding");
                uint?padding     = null;

                if (uint.TryParse(paddingAttr?.Value, out var p))
                {
                    padding = p;
                }
                else
                {
                    padding = null;
                }

                var g = new SetObjectTypeParamGroup(elemName, padding, descAttr?.Value);
                foreach (var elem in element.Elements())
                {
                    ReadParam(elem, g.Parameters);
                }

                if (g.Parameters.Count > 0)
                {
                    group.Add(g);
                }

                return;
            }

            if (elemName.ToLower() == "extra")
            {
                var valueAttr = element.Attribute("value");
                var condAttr  = element.Attribute("condition");

                if (valueAttr == null)
                {
                    valueAttr = element.Attribute("name");
                }

                if (valueAttr == null)
                {
                    valueAttr = element.Attribute("length");
                }

                string v         = valueAttr?.Value;
                string condition = condAttr?.Value;

                AddExtra(typeAttr.Value, v, condition);
            }
            else
            {
                var defaultAttr = element.Attribute("default");
                var dataType    = Types.GetTypeFromString(typeAttr.Value);

                var param = new SetObjectTypeParam()
                {
                    Name        = elemName,
                    DataType    = dataType,
                    Description = descAttr?.Value,

                    DefaultValue = (defaultAttr == null) ?
                                   Types.GetDefaultFromType(dataType) :
                                   Helpers.ChangeType(defaultAttr.Value, dataType)
                };

                // Enumerator Values
                foreach (var enumElement in element.Elements())
                {
                    elemName = enumElement.Name.LocalName;
                    if (elemName.ToLower() != "enum")
                    {
                        continue;
                    }

                    var valueAttr = enumElement.Attribute("value");
                    if (valueAttr == null)
                    {
                        continue;
                    }

                    descAttr = enumElement.Attribute("description");
                    var enumType = new SetObjectTypeParamEnum()
                    {
                        Value       = Helpers.ChangeType(valueAttr.Value, dataType),
                        Description = descAttr?.Value
                    };

                    param.Enums.Add(enumType);
                }

                group.Add(param);
            }
        }