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++; } }
private VLTBaseType DoValueConversion(string gameId, string dir, VltClass vltClass, VltClassField field, VltCollection vltCollection, object serializedValue, object instance) { switch (serializedValue) { case string str: switch (instance) { case IStringValue stringValue: stringValue.SetString(str); return((VLTBaseType)instance); case PrimitiveTypeBase primitiveTypeBase: return(ValueConversionUtils.DoPrimitiveConversion(primitiveTypeBase, str)); case BaseBlob blob: { if (string.IsNullOrWhiteSpace(str)) { return(blob); } str = Path.Combine(dir, str); if (!File.Exists(str)) { throw new InvalidDataException( $"Could not locate blob data file for {vltCollection.ShortPath}[{field.Name}]"); } blob.Data = File.ReadAllBytes(str); return(blob); } } break; case Dictionary <object, object> dictionary: return((VLTBaseType)(instance is VLTArrayType array ? DoArrayConversion(gameId, dir, vltClass, field, vltCollection, array, dictionary) : DoDictionaryConversion(gameId, dir, vltClass, field, vltCollection, instance, dictionary))); } throw new InvalidDataException("Could not convert serialized value of type: " + serializedValue.GetType()); }