public ArrayItemProperty(VLTCollection collection, VLTClassField field, VLTArrayType array, VLTBaseType item) : base(array.GetType(), $"[{Array.IndexOf(array.Items, item)}]", array.ItemType) { _collection = collection; _field = field; _array = array; _item = item; }
public override void Execute(ModScriptDatabaseHelper database) { VltCollection collection = GetCollection(database, ClassName, CollectionName); VltClassField field = GetField(collection.Class, FieldName); if (!field.IsArray) { throw new ModScriptCommandExecutionException($"Field {ClassName}[{FieldName}] is not an array!"); } if (!collection.HasEntry(FieldName)) { throw new ModScriptCommandExecutionException($"Collection {collection.ShortPath} does not have an entry for {FieldName}."); } VLTArrayType array = collection.GetRawValue <VLTArrayType>(FieldName); if (array.Items.Count == array.Capacity && field.IsInLayout) { throw new ModScriptCommandExecutionException("Cannot append to a full array when it is a layout field"); } if (array.Items.Count + 1 > field.MaxCount) { throw new ModScriptCommandExecutionException("Appending to this array would cause it to exceed the maximum number of allowed elements."); } var itemToEdit = TypeRegistry.ConstructInstance(array.ItemType, collection.Class, field, collection); if (_hasValue) { switch (itemToEdit) { case PrimitiveTypeBase primitiveTypeBase: ValueConversionUtils.DoPrimitiveConversion(primitiveTypeBase, Value); break; case IStringValue stringValue: stringValue.SetString(Value); break; case BaseRefSpec refSpec: // NOTE: This is a compatibility feature for certain types, such as GCollectionKey, which are technically a RefSpec. refSpec.CollectionKey = Value; break; default: throw new ModScriptCommandExecutionException($"Object stored in {collection.Class.Name}[{field.Name}] is not a simple type and cannot be used in a value-append command"); } } array.Items.Add(itemToEdit); if (!field.IsInLayout) { array.Capacity++; } }
/// <summary> /// Gets the value of type <typeparamref name="T"/> mapped to <paramref name="key"/> in the collection's data dictionary. /// </summary> /// <typeparam name="T">The data type to be obtained.</typeparam> /// <param name="key">The mapping key.</param> /// <param name="index">The array index to retrieve the value from.</param> /// <returns>The mapping value.</returns> public T GetRawValue <T>(string key, int index) where T : VLTBaseType { VLTArrayType array = GetRawValue <VLTArrayType>(key); if (index < 0 || index >= array.Items.Count) { throw new ArgumentException($"Failed condition: 0 <= {index} < {array.Items.Count}"); } return((T)array.Items[index]); }
private object BaseTypeToData(VLTBaseType baseType) { // if we have a primitive or string value, return that // if we have an array, return a list where each item in the array has been converted (recursion FTW) // otherwise, just return the original data return(baseType switch { PrimitiveTypeBase ptb => ptb.GetValue(), IStringValue sv => sv.GetString(), VLTArrayType array => array.Items.Select(BaseTypeToData).ToList(), _ => baseType });
/// <summary> /// Updates or creates a mapping in the data dictionary between <paramref name="key"/> and <paramref name="data"/>. /// </summary> /// <param name="key">The mapping key. (Typically the VLT field name.)</param> /// <param name="index"></param> /// <param name="data">The mapping value.</param> public void SetRawValue <T>(string key, int index, T data) where T : VLTBaseType { VLTArrayType array = GetRawValue <VLTArrayType>(key); if (index < 0 || index >= array.Items.Count) { throw new ArgumentException($"Failed condition: 0 <= {index} < {array.Items.Count}"); } if (data.GetType() != array.ItemType) { throw new ArgumentException($"Type mismatch: T={data.GetType()} A={array.ItemType}"); } array.Items[index] = data; }
public override void Execute(ModScriptDatabaseHelper database) { VltCollection collection = GetCollection(database, ClassName, CollectionName); VltClassField field = GetField(collection.Class, FieldName); if (!field.IsArray) { throw new ModScriptCommandExecutionException($"Field {ClassName}[{FieldName}] is not an array!"); } if (field.MaxCount < NewCapacity) { throw new ModScriptCommandExecutionException( $"Cannot resize field {ClassName}[{FieldName}] beyond maximum count (requested {NewCapacity} but limit is {field.MaxCount})"); } if (!collection.HasEntry(FieldName)) { throw new ModScriptCommandExecutionException($"Collection {collection.ShortPath} does not have an entry for {FieldName}."); } VLTArrayType array = collection.GetRawValue <VLTArrayType>(FieldName); if (NewCapacity < array.Items.Count) { while (NewCapacity < array.Items.Count) { array.Items.RemoveAt(array.Items.Count - 1); } } else if (NewCapacity > array.Items.Count) { while (NewCapacity > array.Items.Count) { array.Items.Add(TypeRegistry.ConstructInstance(array.ItemType, collection.Class, field, collection)); } } if (!field.IsInLayout) { array.Capacity = NewCapacity; } }
private VLTArrayType DoArrayConversion(string gameId, string dir, VltClass vltClass, VltClassField field, VltCollection vltCollection, VLTArrayType array, Dictionary <object, object> dictionary) { var capacity = ushort.Parse(dictionary["Capacity"].ToString()); var rawItemList = (List <object>)dictionary["Data"]; array.Capacity = capacity; array.Items = new List <VLTBaseType>(); array.ItemAlignment = field.Alignment; array.FieldSize = field.Size; foreach (var o in rawItemList) { var newArrayItem = ConvertSerializedValueToDataValue(gameId, dir, vltClass, field, vltCollection, o, false); array.Items.Add(newArrayItem); } return(array); }
/// <summary> /// Creates the appropriate instance type for the given field. /// </summary> /// <remarks>Returns a <see cref="VLTArrayType" /> if the field is an array.</remarks> /// <param name="gameId"></param> /// <param name="vltClass"></param> /// <param name="vltClassField"></param> /// <param name="collection"></param> /// <returns></returns> public static VLTBaseType CreateInstance(string gameId, VltClass vltClass, VltClassField vltClassField, VltCollection collection) { var type = ResolveType(gameId, vltClassField.TypeName); VLTBaseType instance; if (vltClassField.IsArray) { instance = new VLTArrayType(vltClass, vltClassField, collection, type) { ItemAlignment = vltClassField.Alignment } } ; else { instance = ConstructInstance(type, vltClass, vltClassField, collection); } return(instance); }
public ArrayLengthProperty(VLTArrayType array) : base("Length", null) { _array = array; }
// This is where our problems with Carbon and up appear to stem from. public void a(RowRecord A_0, UnknownB0 A_1) { BinaryReader binaryReader = new BinaryReader(A_1.ms1); BinaryReader binaryReader2 = new BinaryReader(A_1.ms2); UnknownDR dr = new UnknownDR(this.vltClass.classRecord.i2); UnknownA8 a = A_1.a(VLTOtherValue.TABLE_END) as UnknownA8; int num; if (a.genht1.ContainsKey(A_0.position)) { num = a.genht1[A_0.position].i2; } else { // NOTE: THIS IS A BUG, IT SHOULD NOT HAPPEN. // The ONLY reason I'm checking ContainsKey instead of using exception handling, // is because exception handling causes huge slowdowns in Visual Studio debugging. if (BuildConfig.DEBUG) { ++numFails; Console.WriteLine("VLTClass.a(): num fail (num" + numFails + ",b" + b8Fails + ")"); } return; } dr.b01 = A_1; dr.dq1 = this.vltClass; dr.c1 = A_0; for (int i = 0; i < this.vltClass.classRecord.i2; ++i) { VLTClass.aclz1 a2 = this.vltClass.fields[i]; BinaryReader binaryReader3; if (!a2.c()) { binaryReader3 = binaryReader; binaryReader3.BaseStream.Seek(num + a2.us1, SeekOrigin.Begin); } else { binaryReader3 = null; for (int j = 0; j < A_0.i1; ++j) { if (A_0.caa1[j].hash == a2.hash) { if (A_0.caa1[j].a()) { binaryReader3 = binaryReader2; binaryReader3.BaseStream.Seek(A_0.caa1[j].position, SeekOrigin.Begin); } else { binaryReader3 = binaryReader; binaryReader3.BaseStream.Seek(a.genht1[A_0.caa1[j].position].i2, SeekOrigin.Begin); } } } if (binaryReader3 == null) { continue; } } Type type = TypeMap.instance.getTypeForKey(a2.ui2); if (type == null) { type = typeof(VLTRawType); } VLTBaseType bb; if (a2.isArray()) { bb = new VLTArrayType(a2, type); } else { bb = VLTBaseType.a(type); bb.size = a2.len; if (bb is VLTRawType) { (bb as VLTRawType).len = a2.len; } } bb.ui1 = (uint)binaryReader3.BaseStream.Position; bb.isVltOffset = (binaryReader3 == binaryReader2); bb.typeHash = a2.ui2; bb.ui3 = a2.hash; bb.dr1 = dr; bb.read(binaryReader3); dr.a(i, bb); } this.drList.Add(dr); }
/* * private void e( object A_0, EventArgs A_1 ) * { * if( this.tvFields.SelectedNode != null ) * { * TreeNode treeNode = this.tvFields.SelectedNode; * if( treeNode.Parent != null ) * { * treeNode = treeNode.Parent; * } * VLTBaseType bb = treeNode.Tag as VLTBaseType; * this.a( bb.dr1, bb.ui3 ); * } * } */ // TODO: opt private void tv_AfterSelect(object A_0, TreeViewEventArgs A_1) { object tag = A_1.Node.Tag; if (tag is VLTClass) { this.classGrid.Visible = true; this.pnlData.Visible = false; VLTClass dq = tag as VLTClass; DataSet dataSet = new DataSet("VLT"); DataTable dataTable = dataSet.Tables.Add("Fields"); dataTable.Columns.Add("Name", typeof(string)); dataTable.Columns.Add("Type", typeof(string)); dataTable.Columns.Add("Length", typeof(ushort)); dataTable.Columns.Add("Count", typeof(short)); foreach (VLTClass.aclz1 a in dq) { DataRow dataRow = dataTable.NewRow(); dataRow[0] = HashTracker.getValueForHash(a.hash); dataRow[1] = HashTracker.getValueForHash(a.ui2); dataRow[2] = a.len; dataRow[3] = a.count; dataTable.Rows.Add(dataRow); } this.classGrid.DataSource = dataSet; this.classGrid.DataMember = "Fields"; // This gets rid of the extra row in the table that appears when viewing a root node (e.x. junkman, pvehicle) CurrencyManager currencyManager = (CurrencyManager)this.BindingContext[dataSet, "Fields"]; ((DataView)currencyManager.List).AllowNew = false; ((DataView)currencyManager.List).AllowEdit = false; ((DataView)currencyManager.List).AllowDelete = false; UnknownA8 a2 = dq.b01.a(VLTOtherValue.TABLE_END) as UnknownA8; this.classGrid.Update(); } else if (tag is UnknownDR) { this.lblFieldType.Text = ""; this.lblFieldOffset.Text = ""; this.dataGrid.DataSource = null; this.dataGrid.Update(); this.classGrid.Visible = false; this.pnlData.Visible = true; string text = ""; string text2 = ""; TreeNode treeNode = null; if (this.tvFields.SelectedNode != null) { if (this.tvFields.SelectedNode.Parent != null && this.tvFields.SelectedNode.Parent.Tag == null) { text = this.tvFields.SelectedNode.Parent.Text; text2 = this.tvFields.SelectedNode.Text; } else { text = this.tvFields.SelectedNode.Text; } } UnknownDR dr = tag as UnknownDR; VLTClass dq2 = dr.dq1; this.tvFields.BeginUpdate(); this.tvFields.Nodes.Clear(); int num = 0; foreach (VLTClass.aclz1 a3 in dq2) { VLTBaseType bb = dr.bba1[num++]; if (!a3.c() || dr.booa1[num - 1]) { if (a3.isArray()) { VLTArrayType m = bb as VLTArrayType; string text3 = string.Concat(new object[] { HashTracker.getValueForHash(a3.hash), " [", m.getMaxEntryCount(), "/", m.getCurrentEntryCount(), "]" }); TreeNode treeNode2 = this.tvFields.Nodes.Add(text3); treeNode2.Tag = bb; for (int i = 0; i < m.getMaxEntryCount(); ++i) { TreeNode treeNode3 = treeNode2.Nodes.Add("[" + i + "]"); treeNode3.Tag = m.genlist[i]; if (treeNode2.Text == text && treeNode3.Text == text2) { treeNode = treeNode3; } } if (treeNode2.Text == text && treeNode == null) { treeNode = treeNode2; } } else { TreeNode treeNode4 = this.tvFields.Nodes.Add(HashTracker.getValueForHash(a3.hash)); treeNode4.Tag = bb; if (treeNode4.Text == text) { treeNode = treeNode4; } } } } if (this.tvFields.Nodes.Count > 0) { if (treeNode == null) { this.tvFields.SelectedNode = this.tvFields.Nodes[0]; } else { this.tvFields.SelectedNode = treeNode; } } this.tvFields.EndUpdate(); UnknownA8 a4 = dr.b01.a(VLTOtherValue.TABLE_END) as UnknownA8; } else { this.classGrid.Visible = false; this.pnlData.Visible = false; } }
private void classdump() { using (StreamWriter streamWriter = new StreamWriter((new FileInfo(Application.ExecutablePath)).Directory.FullName + "\\temp.cs", false, Encoding.ASCII)) { streamWriter.WriteLine("using System;"); streamWriter.WriteLine("using mwperf;"); streamWriter.WriteLine("namespace mwperf.VLTTables {"); foreach (VLTClass dq in this.av) { string text = this.bThree(HashTracker.getValueForHash(dq.classHash)); if (this.c(text)) { streamWriter.WriteLine("\tnamespace " + text + " {"); streamWriter.WriteLine("\t\tpublic abstract class " + this.bThree(text + "_base") + " {"); foreach (VLTClass.aclz1 a in dq) { string text2 = this.bThree(HashTracker.getValueForHash(a.hash)); if (this.c(text2)) { streamWriter.WriteLine(string.Concat(new string[] { "\t\t\tpublic static VLTOffsetData", a.isArray() ? "[]" : "", " ", text2, ";" })); } } streamWriter.WriteLine("\t\t}"); foreach (UnknownDR dr in dq.dqb1) { int num = 0; string text3 = this.bThree(HashTracker.getValueForHash(dr.c1.hash)); if (this.c(text3)) { streamWriter.WriteLine(string.Concat(new string[] { "\t\tpublic class ", text3, " : ", text, "_base {" })); streamWriter.WriteLine("\t\t\tstatic " + text3 + "() {"); foreach (VLTClass.aclz1 a2 in dq) { VLTBaseType bb = dr.bba1[num++]; if (!a2.c() || dr.booa1[num - 1]) { string text4 = this.bThree(HashTracker.getValueForHash(a2.hash)); if (this.c(text4)) { streamWriter.Write("\t\t\t\t" + text4 + " = "); if (a2.isArray()) { VLTArrayType m = bb as VLTArrayType; streamWriter.WriteLine("new VLTOffsetData[] {"); for (int i = 0; i < m.getMaxEntryCount(); ++i) { bb = m.genlist[i]; streamWriter.WriteLine(string.Concat(new string[] { "\t\t\t\t\tnew VLTOffsetData(VLTOffsetType.", bb.isVltOffset ? "Vlt" : "Bin", ", ", string.Format("0x{0:x}", bb.ui1), ")", (i != (int)(m.getMaxEntryCount() - 1)) ? "," : "" })); } streamWriter.WriteLine("\t\t\t\t};"); } else { streamWriter.WriteLine(string.Concat(new string[] { "new VLTOffsetData(VLTOffsetType.", bb.isVltOffset ? "Vlt" : "Bin", ", ", string.Format("0x{0:x}", bb.ui1), ");" })); } } } } streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine("\t\t}"); } } streamWriter.WriteLine("\t}"); } } streamWriter.WriteLine("}"); } }
private void tv_AfterSelect(object sender, TreeViewEventArgs e) { object tag = e.Node.Tag; if (tag is VLTClass) { this.classGrid.Visible = true; this.pnlData.Visible = false; VLTClass dq = tag as VLTClass; if (!this.classGridDataSet.Tables.Contains(dq.classHash.ToString())) { DataTable dataTable = this.classGridDataSet.Tables.Add(dq.classHash.ToString()); dataTable.Columns.Add("Name", typeof(string)); dataTable.Columns.Add("Type", typeof(string)); dataTable.Columns.Add("Length", typeof(ushort)); dataTable.Columns.Add("Count", typeof(short)); foreach (VLTClass.aclz1 a in dq) { /* * object[] rowData = * { * HashTracker.getValueForHash( a.hash ), * HashTracker.getValueForHash( a.ui2 ), * a.len, * a.count * }; * dataTable.Rows.Add( rowData );*/ dataTable.Rows.Add(new object[] { HashTracker.getValueForHash(a.hash), HashTracker.getValueForHash(a.ui2), a.len, a.count }); /* * DataRow dataRow = dataTable.NewRow(); * dataRow[0] = HashTracker.getValueForHash( a.hash ); * dataRow[1] = HashTracker.getValueForHash( a.ui2 ); * dataRow[2] = a.len; * dataRow[3] = a.count; * dataTable.Rows.Add( dataRow );*/ } } this.classGrid.DataMember = dq.classHash.ToString(); //this.classGrid.Columns["Name"].Width = 80; //this.classGrid.Columns["Type"].Width = 150; //this.classGrid.Columns["Length"].Width = 60; //this.classGrid.Columns["Count"].Width = 60; this.classGrid.Update(); } else if (tag is UnknownDR) // TODO { this.lblFieldType.Text = ""; this.lblFieldOffset.Text = ""; this.dataGrid.DataSource = null; this.dataGrid.Update(); this.classGrid.Visible = false; this.pnlData.Visible = true; string text = ""; string text2 = ""; TreeNode treeNode = null; if (this.tvFields.SelectedNode != null) { if (this.tvFields.SelectedNode.Parent != null && this.tvFields.SelectedNode.Parent.Tag == null) { text = this.tvFields.SelectedNode.Parent.Text; text2 = this.tvFields.SelectedNode.Text; } else { text = this.tvFields.SelectedNode.Text; } } UnknownDR dr = tag as UnknownDR; VLTClass dq2 = dr.dq1; this.tvFields.BeginUpdate(); this.tvFields.Nodes.Clear(); int num = 0; foreach (VLTClass.aclz1 a3 in dq2) { VLTBaseType bb = dr.bba1[num++]; if (!a3.c() || dr.booa1[num - 1]) { if (a3.isArray()) { VLTArrayType m = bb as VLTArrayType; string text3 = string.Concat(new object[] { HashTracker.getValueForHash(a3.hash), " [", m.getMaxEntryCount(), "/", m.getCurrentEntryCount(), "]" }); TreeNode treeNode2 = this.tvFields.Nodes.Add(text3); treeNode2.Tag = bb; for (int i = 0; i < m.getMaxEntryCount(); ++i) { TreeNode treeNode3 = treeNode2.Nodes.Add("[" + i + "]"); treeNode3.Tag = m.genlist[i]; if (treeNode2.Text == text && treeNode3.Text == text2) { treeNode = treeNode3; } } if (treeNode2.Text == text && treeNode == null) { treeNode = treeNode2; } } else { TreeNode treeNode4 = this.tvFields.Nodes.Add(HashTracker.getValueForHash(a3.hash)); treeNode4.Tag = bb; if (treeNode4.Text == text) { treeNode = treeNode4; } } } } if (this.tvFields.Nodes.Count > 0) { if (treeNode == null) { this.tvFields.SelectedNode = this.tvFields.Nodes[0]; } else { this.tvFields.SelectedNode = treeNode; } } this.tvFields.EndUpdate(); } else { this.classGrid.Visible = false; this.pnlData.Visible = false; } }