private static byte[] Traverse(XmlNode node, PsoBuilder pb, MetaName type = 0, bool isRoot = false) { if (type == 0) { type = (MetaName)(uint)GetHash(node.Name); } var infos = PsoTypes.GetStructureInfo(type); if (infos != null) { byte[] data = new byte[infos.StructureLength]; var arrayResults = new PsoArrayResults(); arrayResults.Structures = new Dictionary <int, Array_Structure>(); arrayResults.StructurePointers = new Dictionary <int, Array_StructurePointer>(); arrayResults.UInts = new Dictionary <int, Array_uint>(); arrayResults.UShorts = new Dictionary <int, Array_ushort>(); arrayResults.UBytes = new Dictionary <int, Array_byte>(); arrayResults.Floats = new Dictionary <int, Array_float>(); arrayResults.Float_XYZs = new Dictionary <int, Array_Vector3>(); arrayResults.Hashes = new Dictionary <int, Array_uint>(); Array.Clear(data, 0, infos.StructureLength); //shouldn't really be necessary... PsoStructureEntryInfo arrEntry = null; //if (isRoot) //{ // pb.EnsureBlock(type); //} for (int i = 0; i < infos.Entries.Length; i++) { var entry = infos.Entries[i]; var cnode = GetEntryNode(node.ChildNodes, entry.EntryNameHash); if (entry.EntryNameHash == (MetaName)MetaTypeName.ARRAYINFO) { arrEntry = entry; continue; } if (cnode == null) { //warning: node not found in XML for this entry! continue; } switch (entry.Type) { case PsoDataType.Array: { TraverseArray(cnode, pb, entry, arrEntry, arrayResults, data, infos); break; } case PsoDataType.Structure: { var stype = (MetaName)entry.ReferenceKey; if (stype == 0) { var stypestr = Xml.GetStringAttribute(cnode, "type"); if (!string.IsNullOrEmpty(stypestr)) { stype = (MetaName)(uint)GetHash(stypestr); } } var struc = Traverse(cnode, pb, stype); if (struc != null) { switch (entry.Unk_5h) { default: //ErrorXml(sb, cind, ename + ": Unexpected Structure subtype: " + entry.Unk_5h.ToString()); break; case 0: //default structure Buffer.BlockCopy(struc, 0, data, entry.DataOffset, struc.Length); break; case 3: //structure pointer... case 4: //also pointer? what's the difference? var bptr = pb.AddItem(stype, struc); var ptr = new PsoPOINTER(bptr.BlockID, bptr.Offset, 0); ptr.SwapEnd(); var ptrb = MetaTypes.ConvertToBytes(ptr); Buffer.BlockCopy(ptrb, 0, data, entry.DataOffset, ptrb.Length); break; } } else { } break; } case PsoDataType.Map: { TraverseMap(cnode, pb, entry, infos, data, arrayResults); break; } case PsoDataType.Bool: { byte val = (cnode.Attributes["value"].Value == "false") ? (byte)0 : (byte)1; data[entry.DataOffset] = val; break; } case PsoDataType.SByte: { var val = Convert.ToSByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = (byte)val; break; } case PsoDataType.UByte: { var val = Convert.ToByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = val; break; } case PsoDataType.SShort: { var val = Convert.ToInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case PsoDataType.UShort: { var val = Convert.ToUInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case PsoDataType.SInt: { var val = Convert.ToInt32(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case PsoDataType.UInt: { switch (entry.Unk_5h) { default: //ErrorXml(sb, cind, ename + ": Unexpected Integer subtype: " + entry.Unk_5h.ToString()); break; case 0: //signed int (? flags?) var sval = Convert.ToInt32(cnode.Attributes["value"].Value); Write(sval, data, entry.DataOffset); break; case 1: //unsigned int var ustr = cnode.Attributes["value"].Value; uint uval = 0; if (ustr.StartsWith("0x")) { ustr = ustr.Substring(2); uval = Convert.ToUInt32(ustr, 16); } else { uval = Convert.ToUInt32(ustr); } Write(uval, data, entry.DataOffset); break; } break; } case PsoDataType.Float: { float val = FloatUtil.Parse(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case PsoDataType.Float2: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); break; } case PsoDataType.Float3: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); break; } case PsoDataType.Float4: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); float w = FloatUtil.Parse(cnode.Attributes["w"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); Write(w, data, entry.DataOffset + sizeof(float) * 3); break; } case PsoDataType.String: { TraverseString(cnode, pb, entry, data); break; } case PsoDataType.Enum: { pb.AddEnumInfo((MetaName)entry.ReferenceKey); switch (entry.Unk_5h) { default: //ErrorXml(sb, cind, ename + ": Unexpected Enum subtype: " + entry.Unk_5h.ToString()); break; case 0: //int enum int ival = GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type); Write(ival, data, entry.DataOffset); break; case 1: //short enum? short sval = (short)GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type); Write(sval, data, entry.DataOffset); break; case 2: //byte enum byte bval = (byte)GetEnumInt((MetaName)entry.ReferenceKey, cnode.InnerText, entry.Type); data[entry.DataOffset] = bval; break; } break; } case PsoDataType.Flags: { //uint fCount = (entry.ReferenceKey >> 16) & 0x0000FFFF; uint fEntry = (entry.ReferenceKey & 0xFFF); var fEnt = (fEntry != 0xFFF) ? infos.GetEntry((int)fEntry) : null; PsoEnumInfo flagsInfo = null; MetaName fEnum = (MetaName)(fEnt?.ReferenceKey ?? 0); if ((fEnt != null) && (fEnt.EntryNameHash == (MetaName)MetaTypeName.ARRAYINFO)) { flagsInfo = PsoTypes.GetEnumInfo(fEnum); } if (flagsInfo == null) { if (fEntry != 0xFFF) { } //flagsInfo = PsoTypes.GetEnumInfo(entry.EntryNameHash); } if (flagsInfo != null) { pb.AddEnumInfo(flagsInfo.IndexInfo.NameHash); } else { } //error? switch (entry.Unk_5h) { default: //ErrorXml(sb, cind, ename + ": Unexpected Flags subtype: " + entry.Unk_5h.ToString()); break; case 0: //int flags int ival = GetEnumInt(fEnum, cnode.InnerText, entry.Type); Write(ival, data, entry.DataOffset); break; case 1: //short flags short sval = (short)GetEnumInt(fEnum, cnode.InnerText, entry.Type); Write(sval, data, entry.DataOffset); break; case 2: //byte flags byte bval = (byte)GetEnumInt(fEnum, cnode.InnerText, entry.Type); data[entry.DataOffset] = bval; break; } break; } case PsoDataType.Float3a: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); break; } case PsoDataType.Float4a: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); //float w = FloatUtil.Parse(cnode.Attributes["w"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); //Write(w, data, entry.DataOffset + sizeof(float) * 3); break; } case PsoDataType.HFloat: { var val = Convert.ToInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case PsoDataType.Long: { var uval = Convert.ToUInt64(cnode.Attributes["value"].Value); Write(uval, data, entry.DataOffset); break; } default: break; } } arrayResults.WriteArrays(data); pb.AddStructureInfo(infos.IndexInfo.NameHash); if (isRoot) { pb.RootPointer = pb.AddItem(type, data); } return(data); } else { } //info not found return(null); }
private static Array_Vector3 TraverseRawVector3Array(XmlNode node, MetaBuilder mb) { var items = new List <Vector4>(); float x = 0f; float y = 0f; float z = 0f; float w = 0f; var cnodes = node.SelectNodes("Item"); if (cnodes.Count > 0) { foreach (XmlNode cnode in cnodes) { var str = cnode.InnerText; var strs = str.Split(','); if (strs.Length >= 3) { x = FloatUtil.Parse(strs[0].Trim()); y = FloatUtil.Parse(strs[1].Trim()); z = FloatUtil.Parse(strs[2].Trim()); if (strs.Length >= 4) { w = FloatUtil.Parse(strs[3].Trim()); } var val = new Vector4(x, y, z, w); items.Add(val); } } } else { var split = node.InnerText.Split('\n');// Regex.Split(node.InnerText, @"[\s\r\n\t]"); for (int i = 0; i < split.Length; i++) { var s = split[i]?.Trim(); if (string.IsNullOrEmpty(s)) { continue; } var split2 = Regex.Split(s, @"[\s\t]"); int c = 0; x = 0f; y = 0f; z = 0f; for (int n = 0; n < split2.Length; n++) { var ts = split2[n]?.Trim(); if (string.IsNullOrEmpty(ts)) { continue; } var f = FloatUtil.Parse(ts); switch (c) { case 0: x = f; break; case 1: y = f; break; case 2: z = f; break; } c++; } if (c >= 3) { var val = new Vector4(x, y, z, w); items.Add(val); } } } return(mb.AddPaddedVector3ArrayPtr(items.ToArray())); }
private static void GetParsedArrayOfBytes(XmlNode node, byte[] data, MetaStructureEntryInfo_s entry, MetaStructureEntryInfo_s arrEntry) { int offset = entry.DataOffset; var ns = NumberStyles.Any; var ic = CultureInfo.InvariantCulture; var sa = new[] { ' ' }; var so = StringSplitOptions.RemoveEmptyEntries; var split = node.InnerText.Trim().Split(sa, so); //split = Split(node.InnerText, 2); to read as unsplitted HEX switch (arrEntry.DataType) { default: //expecting hex string. split = Split(node.InnerText, 2); for (int j = 0; j < split.Length; j++) { byte val = Convert.ToByte(split[j], 16); data[offset] = val; offset += sizeof(byte); } break; case MetaStructureEntryDataType.SignedByte: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { sbyte val; // = Convert.ToSByte(split[j], 10); if (sbyte.TryParse(split[j].Trim(), ns, ic, out val)) { data[offset] = (byte)val; offset += sizeof(sbyte); } } break; case MetaStructureEntryDataType.UnsignedByte: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { byte val; // = Convert.ToByte(split[j], 10); if (byte.TryParse(split[j].Trim(), ns, ic, out val)) { data[offset] = val; offset += sizeof(byte); } } break; case MetaStructureEntryDataType.SignedShort: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { short val; // = Convert.ToInt16(split[j], 10); if (short.TryParse(split[j].Trim(), ns, ic, out val)) { Write(val, data, offset); offset += sizeof(short); } } break; case MetaStructureEntryDataType.UnsignedShort: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { ushort val; // = Convert.ToUInt16(split[j], 10); if (ushort.TryParse(split[j].Trim(), ns, ic, out val)) { Write(val, data, offset); offset += sizeof(ushort); } } break; case MetaStructureEntryDataType.SignedInt: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { int val; // = Convert.ToInt32(split[j], 10); if (int.TryParse(split[j].Trim(), ns, ic, out val)) { Write(val, data, offset); offset += sizeof(int); } } break; case MetaStructureEntryDataType.UnsignedInt: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { uint val; // = Convert.ToUInt32(split[j], 10); if (uint.TryParse(split[j].Trim(), ns, ic, out val)) { Write(val, data, offset); offset += sizeof(uint); } } break; case MetaStructureEntryDataType.Float: //expecting space-separated array. for (int j = 0; j < split.Length; j++) { float val; // = FloatUtil.Parse(split[j]); if (FloatUtil.TryParse(split[j].Trim(), out val)) { Write(val, data, offset); offset += sizeof(float); } } break; } }
public bool Check(float value) => FloatUtil.IsClamped(value, this.minValue, this.maxValue);
private static void WriteNode(StringBuilder sb, int indent, RbfStructure rs) { if (rs.Children.Count == 0) { SelfClosingTag(sb, indent, rs.Name); return; } int cind = indent + 1; bool oneline = ((rs.Children.Count == 1) && (rs.Children[0].Name == null)); OpenTag(sb, indent, rs.Name, !oneline); foreach (var child in rs.Children) { if (child is RbfBytes) { var bytesChild = (RbfBytes)child; var contentField = rs.FindChild("content") as RbfString;//TODO: fix this to output nicer XML! if (contentField != null) { OpenTag(sb, cind, "value"); var aind = cind + 1; if (contentField.Value == "char_array") { foreach (byte k in bytesChild.Value) { Indent(sb, aind); sb.AppendLine(k.ToString()); } } else if (contentField.Value.Equals("short_array")) { var valueReader = new DataReader(new MemoryStream(bytesChild.Value)); while (valueReader.Position < valueReader.Length) { Indent(sb, aind); var y = valueReader.ReadUInt16(); sb.AppendLine(y.ToString()); } } else { ErrorXml(sb, aind, "Unexpected content type: " + contentField.Value); } CloseTag(sb, cind, "value"); } else { string stringValue = Encoding.ASCII.GetString(bytesChild.Value); string str = stringValue.Substring(0, stringValue.Length - 1); //removes null terminator sb.Append(str); } } if (child is RbfFloat) { var floatChild = (RbfFloat)child; ValueTag(sb, cind, child.Name, FloatUtil.ToString(floatChild.Value)); } if (child is RbfString) { var stringChild = (RbfString)child; StringTag(sb, cind, stringChild.Name, stringChild.Value); //if (stringChild.Name.Equals("content")) //else if (stringChild.Name.Equals("type")) //else throw new Exception("Unexpected string content"); } if (child is RbfStructure) { WriteNode(sb, cind, child as RbfStructure); } if (child is RbfUint32) { var intChild = (RbfUint32)child; ValueTag(sb, cind, intChild.Name, UintString(intChild.Value)); } if (child is RbfBoolean) { var booleanChild = (RbfBoolean)child; ValueTag(sb, cind, booleanChild.Name, booleanChild.Value.ToString()); } if (child is RbfFloat3) { var v3 = child as RbfFloat3; SelfClosingTag(sb, cind, v3.Name + " x=\"" + FloatUtil.ToString(v3.X) + "\" y=\"" + FloatUtil.ToString(v3.Y) + "\" z=\"" + FloatUtil.ToString(v3.Z) + "\""); } } CloseTag(sb, oneline ? 0 : indent, rs.Name); }
private void LoadCarGen() { if (CurrentCarGen == null) { //CarGenPanel.Enabled = false; CarAddToProjectButton.Enabled = false; CarDeleteButton.Enabled = false; CarModelTextBox.Text = string.Empty; CarModelHashLabel.Text = "Hash: 0"; CarPopGroupTextBox.Text = string.Empty; CarPopGroupHashLabel.Text = "Hash: 0"; CarFlagsTextBox.Text = string.Empty; CarPositionTextBox.Text = string.Empty; CarOrientXTextBox.Text = string.Empty; CarOrientYTextBox.Text = string.Empty; CarPerpendicularLengthTextBox.Text = string.Empty; CarBodyColorRemap1TextBox.Text = string.Empty; CarBodyColorRemap2TextBox.Text = string.Empty; CarBodyColorRemap3TextBox.Text = string.Empty; CarBodyColorRemap4TextBox.Text = string.Empty; CarLiveryTextBox.Text = string.Empty; foreach (int i in CarFlagsCheckedListBox.CheckedIndices) { CarFlagsCheckedListBox.SetItemCheckState(i, CheckState.Unchecked); } } else { populatingui = true; var c = CurrentCarGen.CCarGen; //CarGenPanel.Enabled = true; CarAddToProjectButton.Enabled = !ProjectForm.YmapExistsInProject(CurrentCarGen.Ymap); CarDeleteButton.Enabled = !CarAddToProjectButton.Enabled; CarModelTextBox.Text = c.carModel.ToString(); CarModelHashLabel.Text = "Hash: " + c.carModel.Hash.ToString(); CarPopGroupTextBox.Text = c.popGroup.ToString(); CarPopGroupHashLabel.Text = "Hash: " + c.popGroup.Hash.ToString(); CarFlagsTextBox.Text = c.flags.ToString(); CarPositionTextBox.Text = FloatUtil.GetVector3String(c.position); CarOrientXTextBox.Text = FloatUtil.ToString(c.orientX); CarOrientYTextBox.Text = FloatUtil.ToString(c.orientY); CarPerpendicularLengthTextBox.Text = FloatUtil.ToString(c.perpendicularLength); CarBodyColorRemap1TextBox.Text = c.bodyColorRemap1.ToString(); CarBodyColorRemap2TextBox.Text = c.bodyColorRemap2.ToString(); CarBodyColorRemap3TextBox.Text = c.bodyColorRemap3.ToString(); CarBodyColorRemap4TextBox.Text = c.bodyColorRemap4.ToString(); CarLiveryTextBox.Text = c.livery.ToString(); for (int i = 0; i < CarFlagsCheckedListBox.Items.Count; i++) { var cv = ((c.flags & (1u << i)) > 0); CarFlagsCheckedListBox.SetItemCheckState(i, cv ? CheckState.Checked : CheckState.Unchecked); } populatingui = false; if (ProjectForm.WorldForm != null) { ProjectForm.WorldForm.SelectObject(CurrentCarGen); } ////struct CCarGen: //Vector3 position { get; set; } //16 16: Float_XYZ: 0: position //float orientX { get; set; } //32 32: Float: 0: orientX=735213009 //float orientY { get; set; } //36 36: Float: 0: orientY=979440342 //float perpendicularLength { get; set; } //40 40: Float: 0: perpendicularLength=124715667 //MetaHash carModel { get; set; } //44 44: Hash: 0: carModel //uint flags { get; set; } //48 48: UnsignedInt: 0: flags //int bodyColorRemap1 { get; set; } //52 52: SignedInt: 0: bodyColorRemap1=1429703670 //int bodyColorRemap2 { get; set; } //56 56: SignedInt: 0: bodyColorRemap2=1254848286 //int bodyColorRemap3 { get; set; } //60 60: SignedInt: 0: bodyColorRemap3=1880965569 //int bodyColorRemap4 { get; set; } //64 64: SignedInt: 0: bodyColorRemap4=1719152247 //MetaHash popGroup { get; set; } //68 68: Hash: 0: popGroup=911358791 //sbyte livery { get; set; } //72 72: SignedByte: 0: livery } }
private static void WriteParsedArrayOfBytesNode(StringBuilder sb, int indent, byte[] data, string ename, int eoffset, StructureEntryInfo entry, StructureEntryInfo arrEntry) { OpenTag(sb, indent, ename, false); var byteArrLen = ((int)entry.ReferenceKey); switch (arrEntry.DataType) { default: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n; byte b = ((bidx >= 0) && (bidx < data.Length)) ? data[bidx] : (byte)0; sb.Append(b.ToString("X").PadLeft(2, '0')); } break; case StructureEntryDataType.SignedByte: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n; sbyte b = ((bidx >= 0) && (bidx < data.Length)) ? (sbyte)data[bidx] : (sbyte)0; sb.Append(b.ToString()); //sb.Append(b.ToString("X").PadLeft(2, '0')); to show HEX values if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.UnsignedByte: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n; byte b = ((bidx >= 0) && (bidx < data.Length)) ? data[bidx] : (byte)0; sb.Append(b.ToString()); if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.SignedShort: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n * 2; short b = ((bidx >= 0) && (bidx < data.Length)) ? BitConverter.ToInt16(data, bidx) : (short)0; sb.Append(b.ToString()); if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.UnsignedShort: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n * 2; ushort b = ((bidx >= 0) && (bidx < data.Length)) ? BitConverter.ToUInt16(data, bidx) : (ushort)0; sb.Append(b.ToString()); if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.SignedInt: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n * 4; int b = ((bidx >= 0) && (bidx < data.Length)) ? BitConverter.ToInt32(data, bidx) : (int)0; sb.Append(b.ToString()); if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.UnsignedInt: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n * 4; uint b = ((bidx >= 0) && (bidx < data.Length)) ? BitConverter.ToUInt32(data, bidx) : (uint)0; sb.Append(b.ToString()); if (n < byteArrLen - 1) { sb.Append(" "); } } break; case StructureEntryDataType.Float: for (int n = 0; n < byteArrLen; n++) { var bidx = eoffset + n * 4; float b = ((bidx >= 0) && (bidx < data.Length)) ? BitConverter.ToSingle(data, bidx) : (float)0; sb.Append(FloatUtil.ToString(b)); if (n < byteArrLen - 1) { sb.Append(" "); } } break; } CloseTag(sb, 0, ename); }
public static DBEntry Read(string dbFile, int build, out string error) { error = ""; using (var fs = new FileStream(dbFile, FileMode.Open, FileAccess.Read)) using (var br = new BinaryReader(fs, Encoding.UTF8)) { DBHeader header = ReadHeader(br, dbFile, build); if (IsKnown(header, out DBEntry known)) { return(known); } if (!ValidationChecks(header, dbFile, out error)) { return(null); } if (header.RecordSize / header.FieldCount != 4) // dbc has byte column { error = "Has byte columns."; return(new DBEntry() { Name = Path.GetFileName(dbFile).ToUpper(), Builds = new List <int>() { build }, Fields = new List <DBField>() }); } Dictionary <int, string> stringTable = new Dictionary <int, string>(); List <byte[]> dataTable = new List <byte[]>(); FieldInfo[] fieldInfo = new FieldInfo[header.FieldCount]; bool hasStrings = false; int nullStrings = 0; // stringtable stuff long pos = br.BaseStream.Position; long stringTableStart = br.BaseStream.Position += header.RecordCount * header.RecordSize; stringTable = ReadStringTable(br, stringTableStart); //Get stringtable br.Scrub(pos); // if 1 or 2 empty strings only then strings aren't unused hasStrings = !(stringTable.Values.Count <= 2 && stringTable.Values.All(x => string.IsNullOrWhiteSpace(x))); // count empties nullStrings = stringTable.Count(x => string.IsNullOrWhiteSpace(x.Value)); // read data for (int i = 0; i < header.RecordCount; i++) { dataTable.Add(br.ReadBytes((int)header.RecordSize)); } // compute possible types for (int i = 0; i < header.FieldCount; i++) { // no pdb dbc struct has uint fields ITS ALL A LIE!! List <FieldType> options = new List <FieldType>() { FieldType.INT, /*FieldType.UINT,*/ FieldType.FLOAT, FieldType.STRING }; if (!hasStrings) { options.Remove(FieldType.STRING); // strings not used } List <int> intVals = new List <int>(); List <string> stringVals = new List <string>(); List <float> floatVals = new List <float>(); for (int r = 0; r < dataTable.Count; r++) { byte[] data = dataTable[r].Skip(i * 4).Take(4).ToArray(); // ignore 0 byte columns as they could be anything if (data.All(x => x == 0)) { continue; } // int value int asInt = BitConverter.ToInt32(data, 0); intVals.Add(asInt); // string check if (options.Contains(FieldType.STRING)) { if (!stringTable.ContainsKey(asInt)) { options.Remove(FieldType.STRING); stringVals.Clear(); // 100% not a string! } else { stringVals.Add(stringTable[asInt]); } } // float check if (options.Contains(FieldType.FLOAT) && FloatUtil.IsLikelyFloat(asInt)) { floatVals.Add(BitConverter.ToSingle(data, 0)); } // uint check - prefer signed over unsigned as per the wow client if (options.Contains(FieldType.UINT) && asInt < 0) { options.Remove(FieldType.UINT); } } fieldInfo[i] = new FieldInfo() { IsEmpty = intVals.Count == 0, FloatPercentage = (floatVals.Count / (float)intVals.Count) * 100f, // % of valid floats Options = options, UniqueStrings = stringVals.Distinct().Count(), UniqueInts = intVals.Distinct().Count() }; } // calculate field types List <FieldType> temp = new List <FieldType>(); for (int i = 0; i < fieldInfo.Length; i++) { var info = fieldInfo[i]; if (info.IsEmpty) // all records are 0 { // most likely to be int, less likely to be float, very unlikely to be a string temp.Add(info.Options.Contains(FieldType.UINT) ? FieldType.UINT : FieldType.INT); } else if (info.Options.Contains(FieldType.FLOAT) && info.FloatPercentage > FLOAT_THRESHOLD) // threshold needs tweaking? { temp.Add(FieldType.FLOAT); // high % of valid floats } else if (info.Options.Contains(FieldType.STRING) && info.UniqueStrings > 0) { // 1 string, 1st field is more likely an ID not a string if (stringTable.Count - nullStrings < header.FieldCount && header.RecordCount == 1) { if (i == 0) { temp.Add(info.Options.Contains(FieldType.UINT) ? FieldType.UINT : FieldType.INT); } else { temp.Add(FieldType.STRING); } } else if (info.UniqueStrings == 1) { // very unlikely to have a column with the same string in every row if there is temp.Add(info.Options.Contains(FieldType.UINT) ? FieldType.UINT : FieldType.INT); } else { temp.Add(FieldType.STRING); // case of 0 = "" and 1 = "" in stringtable } } else { temp.Add(info.Options.Contains(FieldType.UINT) ? FieldType.UINT : FieldType.INT); // uint over int } // LANGREFSTRING check if (temp[temp.Count - 1] == FieldType.STRING) { if (IsLangStringRef(fieldInfo, i + 1, build, out int offset)) { temp[temp.Count - 1] = FieldType.LANGSTRINGREF; i += offset; } } } return(new DBEntry() { Name = Path.GetFileName(dbFile).ToUpper(), Builds = new List <int>() { build }, Fields = temp.Select(x => new DBField() { Name = "", Type = x.ToString().ToUpper() }).ToList() }); } }
private void EntitySearchExportResultsButton_Click(object sender, EventArgs e) { if (EntityResults.Count == 0) { MessageBox.Show("Nothing to export!"); return; } SaveFileDialog.FileName = "Entities_" + EntitySearchTextBox.Text; if (SaveFileDialog.ShowDialog() != DialogResult.OK) { return; } string fname = SaveFileDialog.FileName; StringBuilder sb = new StringBuilder(); sb.AppendLine("ArchetypeName, PositionX, PositionY, PositionZ, RotationX, RotationY, RotationZ, RotationW, YmapFile"); foreach (var ent in EntityResults) { sb.AppendLine(string.Format("{0}, {1}, {2}, {3}", ent.Name, FloatUtil.GetVector3String(ent._CEntityDef.position), FloatUtil.GetVector4String(ent._CEntityDef.rotation), ent.Ymap?.RpfFileEntry?.Path ?? "")); } File.WriteAllText(fname, sb.ToString()); }
public override string ToString() { return("(Size: " + FloatUtil.GetVector3String(AABBSize) + ")"); }
/// <summary> /// Converts a possibly zero (no limit) custom speed limit to a game speed limit. /// </summary> /// <param name="customSpeedLimit">Custom speed limit which can be zero</param> /// <returns>Speed limit in game speed units</returns> public float ToGameSpeedLimit(float customSpeedLimit) { return(FloatUtil.IsZero(customSpeedLimit) ? MAX_SPEED : customSpeedLimit); }
public override string ToString() { return(string.Format("{0}, {1}, {2}", FloatUtil.ToString(minX), FloatUtil.ToString(minY), FloatUtil.ToString(z), FloatUtil.ToString(maxX), FloatUtil.ToString(maxY))); }
private void UpdateUI() { if (CurrentEmitter?.AudioEmitter == null) { AddToProjectButton.Enabled = false; DeleteButton.Enabled = false; populatingui = true; NameTextBox.Text = string.Empty; PositionTextBox.Text = string.Empty; InnerRadTextBox.Text = string.Empty; OuterRadTextBox.Text = string.Empty; Hash1TextBox.Text = string.Empty; Hash2TextBox.Text = string.Empty; Unk01TextBox.Text = string.Empty; Unk02UpDown.Value = 0; Unk03UpDown.Value = 0; Unk04UpDown.Value = 0; Unk05UpDown.Value = 0; Unk06UpDown.Value = 0; Unk07UpDown.Value = 0; Unk08UpDown.Value = 0; Unk09UpDown.Value = 0; Unk10UpDown.Value = 0; Unk11UpDown.Value = 0; Unk12UpDown.Value = 0; Unk13UpDown.Value = 0; Flags0TextBox.Text = string.Empty; Flags1TextBox.Text = string.Empty; Flags2TextBox.Text = string.Empty; Flags3TextBox.Text = string.Empty; Flags4TextBox.Text = string.Empty; Flags5TextBox.Text = string.Empty; ExtParamsTextBox.Text = string.Empty; populatingui = false; } else { AddToProjectButton.Enabled = CurrentEmitter?.RelFile != null ? !ProjectForm.AudioFileExistsInProject(CurrentEmitter.RelFile) : false; DeleteButton.Enabled = !AddToProjectButton.Enabled; populatingui = true; var e = CurrentEmitter.AudioEmitter; NameTextBox.Text = e.NameHash.ToString(); PositionTextBox.Text = FloatUtil.GetVector3String(e.Position); InnerRadTextBox.Text = FloatUtil.ToString(e.InnerRad); OuterRadTextBox.Text = FloatUtil.ToString(e.OuterRad); Hash1TextBox.Text = e.Hash1.ToString(); Hash2TextBox.Text = e.Hash2.ToString(); Unk01TextBox.Text = FloatUtil.ToString(e.Unk01); Unk02UpDown.Value = e.Unk02.Value; Unk03UpDown.Value = e.Unk03.Value; Unk04UpDown.Value = e.Unk04.Value; Unk05UpDown.Value = e.Unk05.Value; Unk06UpDown.Value = e.Unk06.Value; Unk07UpDown.Value = e.Unk07.Value; Unk08UpDown.Value = e.Unk08.Value; Unk09UpDown.Value = e.Unk09.Value; Unk10UpDown.Value = e.Unk10.Value; Unk11UpDown.Value = e.Unk11.Value; Unk12UpDown.Value = e.Unk12.Value; Unk13UpDown.Value = e.Unk13.Value; Flags0TextBox.Text = e.Flags0.Hex; Flags1TextBox.Text = e.Flags1.Hex; Flags2TextBox.Text = e.Flags2.Hex; Flags3TextBox.Text = e.Flags3.Hex; Flags4TextBox.Text = e.Flags4.Hex; Flags5TextBox.Text = e.Flags5.Hex; StringBuilder sb = new StringBuilder(); if (e.ExtParams != null) { foreach (var extparam in e.ExtParams) { sb.Append(extparam.Hash.ToString()); sb.Append(", "); sb.Append(FloatUtil.ToString(extparam.Value)); sb.Append(", "); sb.Append(extparam.Flags.ToString()); sb.AppendLine(); } } ExtParamsTextBox.Text = sb.ToString(); populatingui = false; if (ProjectForm.WorldForm != null) { ProjectForm.WorldForm.SelectAudio(CurrentEmitter); } } }
public static UIMeasurement Decode(int value, int unit) { return(new UIMeasurement(FloatUtil.DecodeToFloat(value), (UIMeasurementUnit)unit)); }
/// <summary> /// The window for selecting and applying a speed limit /// </summary> /// <param name="num"></param> private void GuiSpeedLimitsWindow(int num) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); Color oldColor = GUI.color; List <SpeedValue> allSpeedLimits = EnumerateSpeedLimits(SpeedUnit.CurrentlyConfigured); allSpeedLimits.Add(new SpeedValue(0)); // add last item: no limit bool showMph = GlobalConfig.Instance.Main.DisplaySpeedLimitsMph; var column = 0u; // break palette to a new line at breakColumn int breakColumn = showMph ? BREAK_PALETTE_COLUMN_MPH : BREAK_PALETTE_COLUMN_KMPH; foreach (SpeedValue speedLimit in allSpeedLimits) { // Highlight palette item if it is very close to its float speed if (FloatUtil.NearlyEqual(currentPaletteSpeedLimit.GameUnits, speedLimit.GameUnits)) { GUI.color = Color.gray; } GuiSpeedLimitsWindow_AddButton(showMph, speedLimit); GUI.color = oldColor; // TODO: This can be calculated from SpeedLimit MPH or KMPH limit constants column++; if (column % breakColumn == 0) { GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); //--------------------- // UI buttons row //--------------------- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(Translation.GetString("Default_speed_limits"), GUILayout.Width(200))) { TrafficManagerTool.ShowAdvisor(this.GetType().Name + "_Defaults"); defaultsWindowVisible = true; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); //--------------------- // Checkboxes row //--------------------- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); showLimitsPerLane = GUILayout.Toggle( showLimitsPerLane, Translation.GetString("Show_lane-wise_speed_limits")); GUILayout.FlexibleSpace(); // Display MPH checkbox, if ticked will save global config bool displayMph = GlobalConfig.Instance.Main.DisplaySpeedLimitsMph; displayMph = GUILayout.Toggle(displayMph, Translation.GetString("Display_speed_limits_mph")); if (GlobalConfig.Instance.Main.DisplaySpeedLimitsMph != displayMph) { OptionsGeneralTab.SetDisplayInMph(displayMph); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); DragWindow(ref paletteWindowRect); }
private void ParseWDC1(MemoryStream stream, string file) { stream.Position = 0; Dictionary <int, FieldType> FieldTypes = new Dictionary <int, FieldType>() { { 8, FieldType.ULONG }, { 4, FieldType.INT }, { 2, FieldType.USHORT }, { 1, FieldType.BYTE }, }; using (var dbReader = new BinaryReader(stream, Encoding.UTF8)) { WDC1 header = ExtractHeader(dbReader) as WDC1; if (header == null) { return; } if (header.RecordCount == 0 || header.RecordSize == 0) { return; } long pos = dbReader.BaseStream.Position; Dictionary <int, string> StringTable = new StringTable().Read(dbReader, pos, pos + header.StringBlockSize); bool stringtableused = StringTable.Values.Any(x => !string.IsNullOrWhiteSpace(x)) && !header.HasOffsetTable; List <FieldInfo> fields = new List <FieldInfo>(); var copyTable = header.ReadOffsetData(dbReader, dbReader.BaseStream.Position); for (int f = 0; f < header.ColumnMeta.Count; f++) { FieldType byteType; if (f == header.IdIndex || (f == 0 && header.HasIndexTable)) { fields.Add(new FieldInfo() { ArraySize = 1, Type = FieldType.INT }); continue; } if (header.ColumnMeta[f].CompressionType == CompressionType.None) { int bitSize = header.FieldStructure[f].BitCount; byteType = FieldTypes[NextPow2(~~(bitSize + 7) / 8)]; } else if (header.ColumnMeta[f].CompressionType > CompressionType.Immediate) { byteType = FieldType.INT; } else { byteType = FieldTypes[NextPow2(~~(header.ColumnMeta[f].BitWidth + 7) / 8)]; } fields.Add(new FieldInfo() { ArraySize = header.ColumnMeta[f].ArraySize, Type = byteType == FieldType.INT ? FieldType.UNKNOWN : byteType }); } int offset = 0; for (int i = 0; i < fields.Count; i++) { switch (fields[i].Type) { case FieldType.BYTE: offset++; continue; case FieldType.USHORT: offset += 2; continue; case FieldType.INT: offset += 4; continue; case FieldType.ULONG: offset += 8; continue; } List <FieldType> options = new List <FieldType>() { FieldType.INT, FieldType.FLOAT, FieldType.STRING }; if (!stringtableused) { options.Remove(FieldType.STRING); //Stringtable not used } List <int> ints = new List <int>(); List <float> floats = new List <float>(); foreach (var c in copyTable) { for (int x = 0; x < fields[i].ArraySize; x++) { int asInt = BitConverter.ToInt32(c.Value.Skip(offset + (4 * x)).Take(4).ToArray(), 0); if (asInt > 0) { ints.Add(asInt); if (FloatUtil.IsLikelyFloat(asInt)) { floats.Add(BitConverter.ToSingle(BitConverter.GetBytes(asInt), 0)); } } } } // remove 0's as they could be anything - if all removed then guess its an int ints.RemoveAll(x => x == 0); if (ints.Count == 0) { fields[i].Type = FieldType.INT; offset += (4 * fields[i].ArraySize); continue; } // stringtable doesn't contain string so cant be a string if (options.Contains(FieldType.STRING) && ints.Any(x => !StringTable.ContainsKey(x))) { options.Remove(FieldType.STRING); } if (floats.Count / (float)ints.Count >= 0.85) { fields[i].Type = FieldType.FLOAT; } else if (options.Contains(FieldType.STRING)) { fields[i].Type = FieldType.STRING; } else if (header.ColumnMeta[i].CompressionType == CompressionType.Immediate && header.ColumnMeta[i].Cardinality == 0) { fields[i].Type = FieldType.UINT; } else { fields[i].Type = FieldType.INT; } offset += (4 * fields[i].ArraySize); } Table table = new Table(); table.Name = Path.GetFileNameWithoutExtension(file); table.Fields = new List <Field>(); string format = $"X{fields.Count.ToString("X").Length}"; //X2, X3 etc for (int i = 0; i < fields.Count; i++) { if (header.RelationshipCount > 0 && i == fields.Count - 1) { continue; } Field field = new Field(); field.Name = (i == header.IdIndex ? "ID" : $"field{i.ToString(format)}"); field.IsIndex = (i == header.IdIndex); field.ArraySize = (field.IsIndex ? 1 : fields[i].ArraySize); field.Type = fields[i].Type.ToString().ToLower(); table.Fields.Add(field); Console.WriteLine($"Name: {field.Name} | Array: {field.ArraySize} | Type: {field.Type}"); } tables.Add(table); Database.ForceGC(); } }
public static string ToKmphPreciseString(SpeedValue speed) { return(FloatUtil.IsZero(speed.GameUnits) ? Translation.GetString("Speed_limit_unlimited") : speed.ToKmphPrecise().ToString()); }
public bool IsDefined() { return(FloatUtil.IsDefined(value)); }
private static void GetParsedArrayOfBytes(XmlNode node, byte[] data, MetaStructureEntryInfo_s entry, MetaStructureEntryInfo_s arrEntry) { int offset = entry.DataOffset; string[] split; switch (arrEntry.DataType) { default: split = Split(node.InnerText, 2); for (int j = 0; j < split.Length; j++) { byte val = Convert.ToByte(split[j], 16); data[offset] = val; offset += sizeof(byte); } break; case MetaStructureEntryDataType.SignedByte: split = node.InnerText.Split(); //split = Split(node.InnerText, 2); to read as unsplitted HEX for (int j = 0; j < split.Length; j++) { sbyte val = Convert.ToSByte(split[j], 10); data[offset] = (byte)val; offset += sizeof(sbyte); } break; case MetaStructureEntryDataType.UnsignedByte: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { byte val = Convert.ToByte(split[j], 10); data[offset] = val; offset += sizeof(byte); } break; case MetaStructureEntryDataType.SignedShort: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { short val = Convert.ToInt16(split[j], 10); Write(val, data, offset); offset += sizeof(short); } break; case MetaStructureEntryDataType.UnsignedShort: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { ushort val = Convert.ToUInt16(split[j], 10); Write(val, data, offset); offset += sizeof(ushort); } break; case MetaStructureEntryDataType.SignedInt: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { int val = Convert.ToInt32(split[j], 10); Write(val, data, offset); offset += sizeof(int); } break; case MetaStructureEntryDataType.UnsignedInt: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { uint val = Convert.ToUInt32(split[j], 10); Write(val, data, offset); offset += sizeof(uint); } break; case MetaStructureEntryDataType.Float: split = node.InnerText.Split(); for (int j = 0; j < split.Length; j++) { float val = FloatUtil.Parse(split[j]); Write(val, data, offset); offset += sizeof(float); } break; } }
public static string ToMphPreciseString(SpeedValue speed) { return(FloatUtil.IsZero(speed.GameUnits) ? Translation.SpeedLimits.Get("Unlimited") : speed.ToMphPrecise().ToString()); }
public string GetXml() { StringBuilder sb = new StringBuilder(); sb.AppendLine(MetaXmlBase.XmlHeader); sb.AppendLine(string.Format("<CacheDatFile version=\"{0}\">", Version)); sb.AppendLine(" <fileDates>"); if (FileDates != null) { foreach (var date in FileDates) { sb.AppendLine(string.Format(" <fileDate>{0}</fileDate>", date.ToCacheFileString())); } } sb.AppendLine(" </fileDates>"); sb.AppendLine(" <module type=\"fwMapDataStore\">"); if (AllMapNodes != null) { foreach (var mapnode in AllMapNodes) { sb.AppendLine(" <Item>"); sb.AppendLine(string.Format(" <name>{0}</name>", mapnode.Name.ToCleanString())); sb.AppendLine(string.Format(" <parent>{0}</parent>", mapnode.ParentName.ToCleanString())); sb.AppendLine(string.Format(" <contentFlags value=\"{0}\" />", mapnode.ContentFlags.ToString())); sb.AppendLine(string.Format(" <streamingExtentsMin {0} />", FloatUtil.GetVector3XmlString(mapnode.streamingExtentsMin))); sb.AppendLine(string.Format(" <streamingExtentsMax {0} />", FloatUtil.GetVector3XmlString(mapnode.streamingExtentsMax))); sb.AppendLine(string.Format(" <entitiesExtentsMin {0} />", FloatUtil.GetVector3XmlString(mapnode.entitiesExtentsMin))); sb.AppendLine(string.Format(" <entitiesExtentsMax {0} />", FloatUtil.GetVector3XmlString(mapnode.entitiesExtentsMax))); sb.AppendLine(string.Format(" <flags unk1=\"{0}\" unk2=\"{1}\" unk3=\"{2}\" />", mapnode.Unk1, mapnode.Unk2, mapnode.Unk3)); sb.AppendLine(" </Item>"); } } sb.AppendLine(" </module>"); sb.AppendLine(" <module type=\"CInteriorProxy\">"); if (AllCInteriorProxies != null) { foreach (var intprox in AllCInteriorProxies) { sb.AppendLine(" <Item>"); sb.AppendLine(string.Format(" <name>{0}</name>", intprox.Name.ToCleanString())); sb.AppendLine(string.Format(" <parent>{0}</parent>", intprox.Parent.ToCleanString())); sb.AppendLine(string.Format(" <position {0} />", FloatUtil.GetVector3XmlString(intprox.Position))); sb.AppendLine(string.Format(" <rotation {0} />", FloatUtil.GetQuaternionXmlString(intprox.Orientation))); sb.AppendLine(string.Format(" <aabbMin {0} />", FloatUtil.GetVector3XmlString(intprox.BBMin))); sb.AppendLine(string.Format(" <aabbMax {0} />", FloatUtil.GetVector3XmlString(intprox.BBMax))); sb.AppendLine(string.Format(" <unknowns1 unk01=\"{0}\" unk03=\"{1}\" />", intprox.Unk01, intprox.Unk03)); sb.AppendLine(string.Format(" <unknowns2 unk11=\"{0}\" unk12=\"{1}\" unk13=\"{1}\" unk14=\"{1}\" />", intprox.Unk11, intprox.Unk12, intprox.Unk13, intprox.Unk14)); sb.AppendLine(string.Format(" <unknowns3 unk15=\"{0}\" unk16=\"{1}\" unk17=\"{1}\" unk18=\"{1}\" />", intprox.Unk15, intprox.Unk16, intprox.Unk17, intprox.Unk18)); sb.AppendLine(" </Item>"); } } sb.AppendLine(" </module>"); sb.AppendLine(" <module type=\"BoundsStore\">"); if (AllBoundsStoreItems != null) { foreach (var bndstore in AllBoundsStoreItems) { sb.AppendLine(" <Item>"); sb.AppendLine(string.Format(" <name>{0}</name>", bndstore.Name.ToCleanString())); sb.AppendLine(string.Format(" <aabbMin {0} />", FloatUtil.GetVector3XmlString(bndstore.Min))); sb.AppendLine(string.Format(" <aabbMax {0} />", FloatUtil.GetVector3XmlString(bndstore.Max))); sb.AppendLine(string.Format(" <layer value=\"{0}\" />", bndstore.Layer)); sb.AppendLine(" </Item>"); } } sb.AppendLine(" </module>"); sb.AppendLine("</CacheDatFile>"); return(sb.ToString()); }
private void SynthsComboBox_SelectedIndexChanged(object sender, EventArgs e) { Dat10Synth synth = (Dat10Synth)SynthsComboBox.SelectedItem; if (synth == null) { return; } loadingSynth = true; SynthTextBox.Text = Dat10Synth.Disassemble(synth.Bytecode, synth.Constants, synth.Variables, false).Disassembly; SynthTextBox.ClearUndo(); SynthAssemblySyntaxHighlight(SynthTextBox.Range); SynthVariablesTextBox.Clear(); SynthVariablesTextBox.Text = string.Join(Environment.NewLine, synth.Variables.Select(v => $"{RelXml.HashString(v.Name)} {FloatUtil.ToString(v.Value)}")); SynthOutputsTextBox.Clear(); SynthOutputsTextBox.Text = string.Join(" ", synth.OutputsIndices.Take(synth.OutputsCount).Select(bufferIdx => $"B{bufferIdx}")); currentSynth = synth; loadingSynth = false; }
private static byte[] Traverse(XmlNode node, MetaBuilder mb, MetaName type = 0, bool isRoot = false) { if (type == 0) { type = (MetaName)(uint)GetHash(node.Name); } var infos = MetaTypes.GetStructureInfo(type); if (infos != null) { byte[] data = new byte[infos.StructureSize]; var arrayResults = new ArrayResults(); arrayResults.Structures = new Dictionary <int, Array_Structure>(); arrayResults.StructurePointers = new Dictionary <int, Array_StructurePointer>(); arrayResults.UInts = new Dictionary <int, Array_uint>(); arrayResults.UShorts = new Dictionary <int, Array_ushort>(); arrayResults.UBytes = new Dictionary <int, Array_byte>(); arrayResults.Floats = new Dictionary <int, Array_float>(); arrayResults.Float_XYZs = new Dictionary <int, Array_Vector3>(); arrayResults.Hashes = new Dictionary <int, Array_uint>(); Array.Clear(data, 0, infos.StructureSize); MetaStructureEntryInfo_s arrEntry = new MetaStructureEntryInfo_s(); if (isRoot) { mb.EnsureBlock(type); } for (int i = 0; i < infos.Entries.Length; i++) { var entry = infos.Entries[i]; var cnode = GetEntryNode(node.ChildNodes, entry); if (entry.EntryNameHash == MetaName.ARRAYINFO) { arrEntry = entry; continue; } if (cnode == null) { continue; } switch (entry.DataType) { case MetaStructureEntryDataType.Array: { TraverseArray(cnode, mb, arrEntry, entry.DataOffset, arrayResults); break; } case MetaStructureEntryDataType.ArrayOfBytes: { GetParsedArrayOfBytes(cnode, data, entry, arrEntry); break; } case MetaStructureEntryDataType.ArrayOfChars: { int offset = entry.DataOffset; var split = cnode.InnerText; // Split(cnode.InnerText, 1); for (int j = 0; j < split.Length; j++) { byte val = (byte)split[j]; // Convert.ToByte(split[j], 16); data[offset] = val; offset += sizeof(byte); } break; } case MetaStructureEntryDataType.Boolean: { byte val = (cnode.Attributes["value"].Value == "false") ? (byte)0 : (byte)1; data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.ByteEnum: { byte val = Convert.ToByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.CharPointer: { if (!string.IsNullOrEmpty(cnode.InnerText)) { var ptr = mb.AddStringPtr(cnode.InnerText); var val = MetaTypes.ConvertToBytes(ptr); Buffer.BlockCopy(val, 0, data, entry.DataOffset, val.Length); } break; } case MetaStructureEntryDataType.DataBlockPointer: { var ns = NumberStyles.HexNumber; var ic = CultureInfo.InvariantCulture; var sa = new[] { ' ', '\n' }; var so = StringSplitOptions.RemoveEmptyEntries; var split = cnode.InnerText.Trim().Split(sa, so); //split = Split(node.InnerText, 2); to read as unsplitted HEX var bytes = new List <byte>(); for (int j = 0; j < split.Length; j++) { byte val; // = Convert.ToByte(split[j], 10); if (byte.TryParse(split[j].Trim(), ns, ic, out val)) { bytes.Add(val); } } var ptr = mb.AddDataBlockPtr(bytes.ToArray(), MetaName.BYTE); var byt = MetaTypes.ConvertToBytes(ptr); Buffer.BlockCopy(byt, 0, data, entry.DataOffset, byt.Length); break; } case MetaStructureEntryDataType.Float: { float val = FloatUtil.Parse(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.Float_XYZ: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); break; } case MetaStructureEntryDataType.Float_XYZW: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); float w = FloatUtil.Parse(cnode.Attributes["w"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); Write(w, data, entry.DataOffset + sizeof(float) * 3); break; } case MetaStructureEntryDataType.Hash: { var hash = GetHash(cnode.InnerText); Write(hash, data, entry.DataOffset); break; } case MetaStructureEntryDataType.IntEnum: case MetaStructureEntryDataType.IntFlags1: case MetaStructureEntryDataType.IntFlags2: { if (entry.ReferenceKey != 0) { var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); mb.AddEnumInfo(_infos.EnumNameHash); } int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText, entry.DataType); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.ShortFlags: { if (entry.ReferenceKey != 0) { var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); mb.AddEnumInfo(_infos.EnumNameHash); } int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText, entry.DataType); Write((short)val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.SignedByte: { var val = Convert.ToSByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = (byte)val; break; } case MetaStructureEntryDataType.SignedInt: { var val = Convert.ToInt32(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.SignedShort: { var val = Convert.ToInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.Structure: { var struc = Traverse(cnode, mb, entry.ReferenceKey); if (struc != null) { Buffer.BlockCopy(struc, 0, data, entry.DataOffset, struc.Length); } break; } case MetaStructureEntryDataType.StructurePointer: { // TODO break; } case MetaStructureEntryDataType.UnsignedByte: { var val = Convert.ToByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.UnsignedInt: { switch (entry.EntryNameHash) { case MetaName.color: { var val = Convert.ToUInt32(cnode.Attributes["value"].Value, 16); Write(val, data, entry.DataOffset); break; } default: { var val = Convert.ToUInt32(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } } break; } case MetaStructureEntryDataType.UnsignedShort: { var val = Convert.ToUInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } default: break; } } arrayResults.WriteArrays(data); mb.AddStructureInfo(infos.StructureNameHash); if (isRoot) { mb.AddItem(type, data); } return(data); } return(null); }
private void ReCalculateAmount(StockTemplate template) { double[] weights = _spotDataSource.Select(p => p.SettingWeight / 100).ToArray(); double totalWeight = weights.Sum(); double minusResult = 1.0 - totalWeight; //如果不为100%,则根据数量调整比例;这种调整方式是否可以改进, 通过市值调整? if (minusResult > 0.001) { int[] origAmounts = new int[_spotDataSource.Count]; for (int i = 0, count = _spotDataSource.Count; i < count; i++) { var stock = _spotDataSource[i]; origAmounts[i] = stock.Amount; } weights = CalcUtil.CalcStockWeightByAmount(origAmounts); for (int i = 0, count = weights.Length; i < count; i++) { double weight = weights[i]; var stock = _spotDataSource[i]; stock.SettingWeight = 100 * weight; } } List <SecurityItem> secuList = GetSecurityItems(template); var benchmarkItem = _securityInfoList.Find(p => p.SecuCode.Equals(template.Benchmark) && p.SecuType == SecurityType.Index); var benchmarkData = QuoteCenter2.Instance.GetMarketData(benchmarkItem); var benchmark = _benchmarkList.Find(p => p.BenchmarkId.Equals(benchmarkItem.SecuCode)); double bmkPrice = 0f; double totalValue = 0f; if (!FloatUtil.IsZero(benchmarkData.CurrentPrice)) { bmkPrice = benchmarkData.CurrentPrice; } else if (!FloatUtil.IsZero(benchmarkData.PreClose)) { bmkPrice = benchmarkData.PreClose; } //指数基准当期总市值 //上证50、沪深300、中证500每一个点数对应不同的价格 totalValue = bmkPrice * benchmark.ContractMultiple; totalValue = totalValue * template.MarketCapOpt / 100; var prices = GetPrices(secuList); var amounts = CalcUtil.CalcStockAmountPerCopyRound(totalValue, weights, prices); var mktCaps = GetMarketCap(prices, amounts); switch (template.EWeightType) { case Model.EnumType.WeightType.ProportionalWeight: { double totalCap = mktCaps.Sum(); for (int i = 0, count = _spotDataSource.Count; i < count; i++) { var stock = _spotDataSource[i]; stock.Amount = amounts[i]; stock.MarketCap = mktCaps[i]; stock.MarketCapWeight = 100 * stock.MarketCap / totalCap; } } break; case Model.EnumType.WeightType.AmountWeight: { var totalAmount = amounts.Sum(); double totalCap = mktCaps.Sum(); for (int i = 0, count = _spotDataSource.Count; i < count; i++) { var stock = _spotDataSource[i]; stock.Amount = amounts[i]; stock.MarketCap = mktCaps[i]; stock.MarketCapWeight = 100 * stock.MarketCap / totalCap; stock.SettingWeight = 100 * (double)stock.Amount / (double)totalAmount; } } break; default: break; } }