public SetObject(SetObjectType type, string typeName, uint objID) { ObjectType = typeName; ObjectID = objID; foreach (var param in type.Parameters) { if (param is SetObjectTypeParamGroup group) { var g = new SetObjectParamGroup(group.Padding); var groupParams = g.Parameters; foreach (var p in group.Parameters) { groupParams.Add(new SetObjectParam(p.DataType, p.DefaultValue)); } Parameters.Add(g); continue; } Parameters.Add(new SetObjectParam(param.DataType, param.DefaultValue)); } }
public void ImportXML(Stream fileStream) { // Load XML and add loaded data to set data var xml = XDocument.Load(fileStream); uint objID = 0; // For Object elements with no ID attribute. foreach (var objElem in xml.Root.Elements("Object")) { // Generate Object var typeAttr = objElem.Attribute("type"); var objIDAttr = objElem.Attribute("id"); if (typeAttr == null) { continue; } var obj = new SetObject() { ObjectType = typeAttr.Value, ObjectID = (objIDAttr == null) ? objID : Convert.ToUInt32(objIDAttr.Value), }; // Assign CustomData to Object var customDataElem = objElem.Element("CustomData"); if (customDataElem != null) { foreach (var customData in customDataElem.Elements()) { obj.CustomData.Add(customData.Name.LocalName, LoadParam(customData)); } } // Assign Parameters to Object var parametersElem = objElem.Element("Parameters"); if (parametersElem != null) { foreach (var paramElem in parametersElem.Elements()) { obj.Parameters.Add(LoadParam(paramElem)); } } // Assign Transforms to Object var transformsElem = objElem.Element("Transforms"); if (transformsElem != null) { var transforms = transformsElem.Elements("Transform"); int transformCount = transforms.Count(); if (transformCount > 0) { uint i = 0; obj.Children = new SetObjectTransform[transformCount - 1]; foreach (var transformElem in transforms) { var transform = LoadTransform(transformElem); if (i > 0) { obj.Children[i - 1] = transform; } else { obj.Transform = transform; } ++i; } } } ++objID; Objects.Add(obj); } // Sub-Methods SetObjectParam LoadParam(XElement paramElem) { // Groups var dataTypeAttr = paramElem.Attribute("type"); if (dataTypeAttr == null) { var padAttr = paramElem.Attribute("padding"); uint?padding = null; if (uint.TryParse(padAttr?.Value, out var pad)) { padding = pad; } var group = new SetObjectParamGroup(padding); var parameters = group.Parameters; foreach (var param in paramElem.Elements()) { parameters.Add(LoadParam(param)); } return(group); } // Parameters var dataType = Types.GetTypeFromString(dataTypeAttr.Value); object data = null; if (dataType == typeof(Vector2)) { data = Helpers.XMLReadVector2(paramElem); } else if (dataType == typeof(Vector3)) { data = Helpers.XMLReadVector3(paramElem); } else if (dataType == typeof(Vector4)) { data = Helpers.XMLReadVector4(paramElem); } else if (dataType == typeof(Quaternion)) { data = Helpers.XMLReadQuat(paramElem); } else if (dataType == typeof(uint[])) { var countAttr = paramElem.Attribute("count"); uint arrLength = 0; if (countAttr != null) { uint.TryParse(countAttr.Value, out arrLength); } var values = paramElem.Value.Split(','); var arr = new uint[arrLength]; for (uint i = 0; i < arrLength; ++i) { if (i >= values.Length) { break; } uint.TryParse(values[i], out arr[i]); } data = arr; } else if (dataType == typeof(ForcesSetData.ObjectReference[])) { var countAttr = paramElem.Attribute("count"); uint arrLength = 0; if (countAttr != null) { uint.TryParse(countAttr.Value, out arrLength); } uint i = 0; var arr = new ForcesSetData.ObjectReference[arrLength]; foreach (var refElem in paramElem.Elements("ForcesObjectReference")) { var objRef = new ForcesSetData.ObjectReference(); objRef.ImportXML(refElem); arr[i] = objRef; ++i; } data = arr; } else if (dataType == typeof(ForcesSetData.ObjectReference)) { var objRef = new ForcesSetData.ObjectReference(); objRef.ImportXML(paramElem); data = objRef; } else { data = Convert.ChangeType(paramElem.Value, dataType); } return(new SetObjectParam(dataType, data)); } SetObjectTransform LoadTransform(XElement elem) { var posElem = elem.Element("Position"); var rotElem = elem.Element("Rotation"); var scaleElem = elem.Element("Scale"); return(new SetObjectTransform() { Position = Helpers.XMLReadVector3(posElem), Rotation = Helpers.XMLReadQuat(rotElem), Scale = Helpers.XMLReadVector3(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); }