Example #1
0
        public override bool Execute(List<string> args)
        {
            if (args.Count < 1 || args.Count > 2)
                return false;

            var blockName = args[0];
            var ownerType = Owner.GetType();

            var enumerator = new TagFieldEnumerator(Structure);

            var deferredNames = new List<string>();
            var deferredArgs = new List<string>();

            if (blockName.Contains("."))
            {
                deferredNames.AddRange(blockName.Split('.'));
                blockName = deferredNames[0];
                deferredNames = deferredNames.Skip(1).ToList();
                deferredArgs.AddRange(args.Skip(1));
                args = new List<string> { blockName };
            }

            if (blockName.Contains("]"))
            {
                var openBracketIndex = blockName.IndexOf('[');
                var closeBracketIndex = blockName.IndexOf(']');
                var name = blockName.Substring(0, openBracketIndex);
                var index = blockName.Substring(openBracketIndex + 1, (closeBracketIndex - openBracketIndex) - 1);

                blockName = name;
                args = new List<string> { name, index };
            }

            var blockNameLow = blockName.ToLower();
            var field = enumerator.Find(f => f.Name == blockName || f.Name.ToLower() == blockNameLow);

            if (field == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName);
                return false;
            }

            var contextName = "";
            object blockValue = null;

            var structureAttribute = field.FieldType.CustomAttributes.ToList().Find(a => a.AttributeType == typeof(TagStructureAttribute));

            if (structureAttribute != null)
            {
                if (args.Count != 1)
                    return false;

                blockValue = field.GetValue(Owner);
                contextName = $"{blockName}";
            }
            else
            {
                if (args.Count != 2)
                    return false;

                IList fieldValue = null;

                if (field.FieldType.GetInterface("IList") == null || (fieldValue = (IList)field.GetValue(Owner)) == null)
                {
                    Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName);
                    return false;
                }

                int blockIndex = 0;

                if (args[1] == "*")
                    blockIndex = fieldValue.Count - 1;
                else if (!int.TryParse(args[1], out blockIndex))
                {
                    Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex);
                    return false;
                }

                if (blockIndex >= fieldValue.Count || blockIndex < 0)
                {
                    Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex);
                    return false;
                }

                blockValue = fieldValue[blockIndex];
                contextName = $"{blockName}[{blockIndex}]";
            }

            var blockStructure = new TagStructureInfo(blockValue.GetType());

            var blockContext = new CommandContext(Stack.Context, contextName);
            blockContext.AddCommand(new ListFieldsCommand(Info, blockStructure, blockValue));
            blockContext.AddCommand(new SetFieldCommand(Stack, Info, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new EditBlockCommand(Stack, Info, Tag, blockValue));
            blockContext.AddCommand(new AddToCommand(Stack, Info, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new RemoveFromCommand(Stack, Info, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new CopyElementsCommand(Stack, Info, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new PasteElementsCommand(Stack, Info, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new ExitToCommand(Stack));
            Stack.Push(blockContext);

            if (deferredNames.Count != 0)
            {
                var name = deferredNames[0];
                deferredNames = deferredNames.Skip(1).ToList();

                foreach (var deferredName in deferredNames)
                    name += '.' + deferredName;

                args = new List<string> { name };
                args.AddRange(deferredArgs);

                var command = new EditBlockCommand(Stack, Info, Tag, blockValue);
                return command.Execute(args);
            }

            return true;
        }
Example #2
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 1)
            {
                return(false);
            }

            var fieldName      = args[0];
            var fieldNameLow   = fieldName.ToLower();
            var fieldNameSnake = fieldName.ToSnakeCase();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            var blockName = "";

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                blockName      = fieldName.Substring(0, lastIndex);
                fieldName      = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow   = fieldName.ToLower();
                fieldNameSnake = fieldName.ToSnakeCase();

                var command = new EditBlockCommand(ContextStack, Cache, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f =>
                              f.Name == fieldName ||
                              f.Name.ToLower() == fieldNameLow ||
                              f.Name.ToSnakeCase() == fieldNameSnake);

            var ownerType = Owner.GetType();

            if (field == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, fieldName);
                return(false);
            }

            IList fieldValue = null;

            if (field.FieldType.GetInterface("IList") == null || (fieldValue = (IList)field.GetValue(Owner)) == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, fieldName);
                return(false);
            }

            string fromName = null;
            int?   from     = null;

            string toName = null;
            int?   to     = null;

            while (args.Count > 1)
            {
                var found = false;

                switch (args[1].ToLower())
                {
                case "from:":
                    if (char.IsNumber(args[2][0]))
                    {
                        from = int.Parse(args[2]);
                    }
                    else
                    {
                        fromName = args[2];
                        from     = FindLabelIndex(fieldValue, fromName);
                    }
                    args.RemoveRange(1, 2);
                    found = true;
                    break;

                case "to:":
                    if (char.IsNumber(args[2][0]))
                    {
                        to = int.Parse(args[2]);
                    }
                    else
                    {
                        toName = args[2];
                        to     = FindLabelIndex(fieldValue, toName);
                    }
                    args.RemoveRange(1, 2);
                    found = true;
                    break;
                }

                if (!found)
                {
                    break;
                }
            }

            blockName = args[0];
            args.RemoveRange(0, 1);

            var commandsToExecute = new List <List <string> >();

            // if no command is given, keep reading commands from stdin until an empty line encountered
            if (args.Count < 1)
            {
                string line;
                while (!string.IsNullOrWhiteSpace(line = Console.ReadLine()))
                {
                    var commandsArgs = ArgumentParser.ParseCommand(line, out string redirectFile);
                    commandsToExecute.Add(commandsArgs);
                }
            }
            else
            {
                commandsToExecute.Add(args);
            }

            for (var i = (from ?? 0);
                 i < (to.HasValue ? to.Value + 1 : fieldValue.Count);
                 i++)
            {
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }

                Owner     = previousOwner;
                Structure = previousStructure;

                if (blockName != "" && new EditBlockCommand(ContextStack, Cache, Tag, Owner)
                    .Execute(new List <string> {
                    $"{blockName}[{i}]"
                })
                    .Equals(false))
                {
                    return(false);
                }

                var label = GetLabel(fieldValue, i);

                Console.Write(label == null ? $"[{i}] " : $"[{label} ({i})] ");
                foreach (var command in commandsToExecute)
                {
                    ContextStack.Context.GetCommand(command[0]).Execute(command.Skip(1).ToList());
                }
            }

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }

            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 2)
            {
                return(false);
            }

            if (CopyBlockElementsCommand.Elements == null)
            {
                Console.WriteLine("ERROR: No elements are available in the clipboard.");
                return(false);
            }

            var fieldName    = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName    = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(ContextStack, Cache, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var index = -1;

            if (args.Count > 1)
            {
                if (args[1] != "*" && (!int.TryParse(args[1], out index) || index < 0))
                {
                    Console.WriteLine($"Invalid index specified: {args[1]}");
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);

            var fieldType = field.FieldType;

            if ((field == null) ||
                (!fieldType.IsGenericType) ||
                (fieldType.GetInterface("IList") == null))
            {
                Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]);
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var elementType = field.FieldType.GenericTypeArguments[0];

            if (elementType != CopyBlockElementsCommand.ElementType)
            {
                Console.WriteLine("Invalid block element type!");
                return(false);
            }

            var blockValue = field.GetValue(Owner) as IList;

            if (blockValue == null)
            {
                blockValue = Activator.CreateInstance(field.FieldType) as IList;
                field.SetValue(Owner, blockValue);
            }

            if (index > blockValue.Count)
            {
                Console.WriteLine($"Invalid index specified: {index}");
                return(false);
            }

            for (var i = 0; i < CopyBlockElementsCommand.Elements.Count; i++)
            {
                var element = CopyBlockElementsCommand.Elements[i];

                if (index == -1)
                {
                    blockValue.Add(element);
                }
                else
                {
                    blockValue.Insert(index + i, element);
                }
            }

            field.SetValue(Owner, blockValue);

            var typeString =
                fieldType.IsGenericType ?
                $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var itemString = CopyBlockElementsCommand.Elements.Count < 2 ? "element" : "elements";

            var valueString =
                ((IList)blockValue).Count != 0 ?
                $"{{...}}[{((IList)blockValue).Count}]" :
                "null";

            Console.WriteLine($"Successfully pasted {CopyBlockElementsCommand.Elements.Count} {itemString} to {field.Name}: {typeString}");
            Console.WriteLine(valueString);

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
Example #4
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }

            var fieldName      = args[0];
            var fieldNameLow   = fieldName.ToLower();
            var fieldNameSnake = fieldName.ToSnakeCase();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName      = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow   = fieldName.ToLower();
                fieldNameSnake = fieldName.ToSnakeCase();

                var command = new EditBlockCommand(ContextStack, CacheContext, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f =>
                              f.Name == fieldName ||
                              f.Name.ToLower() == fieldNameLow ||
                              f.Name.ToSnakeCase() == fieldNameSnake);

            if (field == null)
            {
                Console.WriteLine("ERROR: {0} does not contain a field named \"{1}\".", Structure.Types[0].Name, fieldName);
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var fieldType  = field.FieldType;
            var fieldAttrs = field.GetCustomAttributes(typeof(TagFieldAttribute), false);
            var fieldAttr  = fieldAttrs?.Length < 1 ? new TagFieldAttribute() : (TagFieldAttribute)fieldAttrs[0];
            var fieldInfo  = new TagFieldInfo(field, fieldAttr, uint.MaxValue, uint.MaxValue);
            var fieldValue = ParseArgs(field.FieldType, fieldInfo, args.Skip(1).ToList());

            if (fieldValue != null && fieldValue.Equals(false))
            {
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            if (field.FieldType == typeof(PageableResource))
            {
                var ownerValue = field.GetValue(Owner);

                if (fieldValue == null)
                {
                    field.SetValue(Owner, null);
                }
                else if (ownerValue is PageableResource pageable)
                {
                    var newLocation = ResourceLocation.None;

                    FileInfo resourceFile = null;

                    switch (fieldValue)
                    {
                    case FileInfo file:
                        if (!pageable.GetLocation(out newLocation))
                        {
                            newLocation = ResourceLocation.ResourcesB;
                        }
                        resourceFile = file;
                        break;

                    case ValueTuple <ResourceLocation, FileInfo> tuple:
                        newLocation  = tuple.Item1;
                        resourceFile = tuple.Item2;
                        break;

                    default:
                        throw new FormatException(fieldValue.ToString());
                    }

                    ResourceCache oldCache = null;

                    if (pageable.GetLocation(out var oldLocation))
                    {
                        oldCache = CacheContext.GetResourceCache(oldLocation);
                    }

                    var newCache = CacheContext.GetResourceCache(newLocation);

                    var data = File.ReadAllBytes(resourceFile.FullName);

                    pageable.Page.UncompressedBlockSize = (uint)data.Length;

                    if (oldLocation == newLocation && pageable.Page.Index != -1)
                    {
                        using (var stream = CacheContext.OpenResourceCacheReadWrite(oldLocation))
                        {
                            pageable.Page.CompressedBlockSize = oldCache.Compress(stream, pageable.Page.Index, data);
                        }
                    }
                    else
                    {
                        using (var destStream = CacheContext.OpenResourceCacheReadWrite(newLocation))
                        {
                            pageable.Page.Index = newCache.Add(destStream, data, out pageable.Page.CompressedBlockSize);
                        }

                        pageable.ChangeLocation(newLocation);
                    }

                    pageable.DisableChecksum();

                    field.SetValue(Owner, fieldValue = pageable);
                }
            }
            else
            {
                field.SetValue(Owner, fieldValue);
            }

            var typeString =
                fieldType.IsGenericType ?
                $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            string valueString;

#if !DEBUG
            try
            {
#endif
            if (fieldValue == null)
            {
                valueString = "null";
            }
            else if (fieldType == typeof(StringId))
            {
                valueString = CacheContext.GetString((StringId)fieldValue);
            }
            else if (fieldType == typeof(CachedTagInstance))
            {
                var instance = (CachedTagInstance)fieldValue;

                var tagName = instance?.Name ?? $"0x{instance.Index:X4}";

                valueString = $"[0x{instance.Index:X4}] {tagName}.{CacheContext.GetString(instance.Group.Name)}";
            }
            else if (fieldType == typeof(TagFunction))
            {
                var function = (TagFunction)fieldValue;
                valueString = "";
                foreach (var datum in function.Data)
                {
                    valueString += datum.ToString("X2");
                }
            }
            else if (fieldType == typeof(PageableResource))
            {
                var pageable = (PageableResource)fieldValue;
                pageable.GetLocation(out var location);
                valueString = pageable == null ? "null" : $"{{ Location: {location}, Index: 0x{pageable.Page.Index:X4}, CompressedSize: 0x{pageable.Page.CompressedBlockSize:X8} }}";
            }
            else if (fieldInfo.FieldType.IsArray && fieldInfo.Attribute.Length != 0)
            {
                valueString = fieldValue == null ? "null" : $"[{fieldInfo.Attribute.Length}] {{ ";
                var valueArray = (Array)fieldValue;

                if (fieldValue != null)
                {
                    for (var i = 0; i < fieldInfo.Attribute.Length; i++)
                    {
                        valueString += $"{valueArray.GetValue(i)}{((i + 1) < fieldInfo.Attribute.Length ? "," : "")} ";
                    }

                    valueString += "}";
                }
            }
            else if (fieldType.GetInterface(typeof(IList).Name) != null)
            {
                valueString =
                    ((IList)fieldValue).Count != 0 ?
                    $"{{...}}[{((IList)fieldValue).Count}]" :
                    "null";
            }
            else
            {
                valueString = fieldValue.ToString();
            }
#if !DEBUG
        }

        catch (Exception e)
        {
            valueString = $"<ERROR MESSAGE=\"{e.Message}\" />";
        }
#endif

            var fieldFullName     = $"{field.DeclaringType.FullName}.{field.Name}".Replace("+", ".");
            var documentationNode = EditTagContextFactory.Documentation.SelectSingleNode($"//member[starts-with(@name, 'F:{fieldFullName}')]");

            Console.WriteLine("{0}: {1} = {2} {3}", field.Name, typeString, valueString,
                              documentationNode != null ?
                              $":: {documentationNode.FirstChild.InnerText.Replace("\r\n", "").TrimStart().TrimEnd()}" :
                              "");

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
Example #5
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 2)
            {
                return(false);
            }

            var blockName = args[0];
            var ownerType = Owner.GetType();

            var deferredNames = new List <string>();
            var deferredArgs  = new List <string>();

            if (blockName.Contains("."))
            {
                deferredNames.AddRange(blockName.Split('.'));
                blockName     = deferredNames[0];
                deferredNames = deferredNames.Skip(1).ToList();
                deferredArgs.AddRange(args.Skip(1));
                args = new List <string> {
                    blockName
                };
            }

            if (blockName.Contains("]"))
            {
                var openBracketIndex  = blockName.IndexOf('[');
                var closeBracketIndex = blockName.IndexOf(']');
                var name  = blockName.Substring(0, openBracketIndex);
                var index = blockName.Substring(openBracketIndex + 1, (closeBracketIndex - openBracketIndex) - 1);

                blockName = name;
                args      = new List <string> {
                    name, index
                };
            }

            var blockNameLow   = blockName.ToLower();
            var blockNameSnake = blockName.ToSnakeCase();

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f =>
                              f.Name == blockName ||
                              f.Name.ToLower() == blockNameLow ||
                              f.Name.ToSnakeCase() == blockNameSnake);

            if (field == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName);
                return(false);
            }

            var    contextName = "";
            object blockValue  = null;

            var structureAttribute = field.FieldType.CustomAttributes.ToList().Find(a => a.AttributeType == typeof(TagStructureAttribute));

            if (structureAttribute != null)
            {
                if (args.Count != 1)
                {
                    return(false);
                }

                blockValue  = field.GetValue(Owner);
                contextName = $"{blockName}";
            }
            else
            {
                if (args.Count != 2)
                {
                    return(false);
                }

                IList fieldValue = null;

                if (field.FieldType.GetInterface("IList") == null || (fieldValue = (IList)field.GetValue(Owner)) == null)
                {
                    Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName);
                    return(false);
                }

                int blockIndex = 0;

                if (args[1] == "*")
                {
                    blockIndex = fieldValue.Count - 1;
                }
                else if (!int.TryParse(args[1], out blockIndex))
                {
                    Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex);
                    return(false);
                }

                if (blockIndex >= fieldValue.Count || blockIndex < 0)
                {
                    Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex);
                    return(false);
                }

                blockValue  = fieldValue[blockIndex];
                contextName = $"{blockName}[{blockIndex}]";
            }

            var blockStructure = TagStructure.GetTagStructureInfo(blockValue.GetType(), Cache.Version);

            var blockContext = new CommandContext(ContextStack.Context, contextName);

            blockContext.AddCommand(new ListFieldsCommand(Cache, blockStructure, blockValue));
            blockContext.AddCommand(new SetFieldCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            //blockContext.AddCommand(new ExtractResourceCommand(ContextStack, CacheContext, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new EditBlockCommand(ContextStack, Cache, Tag, blockValue));
            blockContext.AddCommand(new AddBlockElementsCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new RemoveBlockElementsCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new CopyBlockElementsCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new PasteBlockElementsCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new ForEachCommand(ContextStack, Cache, Tag, blockStructure, blockValue));
            blockContext.AddCommand(new ExitToCommand(ContextStack));
            ContextStack.Push(blockContext);

            if (deferredNames.Count != 0)
            {
                var name = deferredNames[0];
                deferredNames = deferredNames.Skip(1).ToList();

                foreach (var deferredName in deferredNames)
                {
                    name += '.' + deferredName;
                }

                args = new List <string> {
                    name
                };
                args.AddRange(deferredArgs);

                var command = new EditBlockCommand(ContextStack, Cache, Tag, blockValue);
                return(command.Execute(args));
            }

            return(true);
        }
Example #6
0
        public override object Execute(List <string> args)
        {
            if (args.Count > 4)
            {
                return(false);
            }


            if (args.Count < 1 || args.Count > 3)
            {
                return(false);
            }

            var fieldName    = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName    = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(ContextStack, CacheContext, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var index = 0;

            if (args.Count > 1 && args[1] != "*")
            {
                if (!int.TryParse(args[1], out index) || index < 0)
                {
                    Console.WriteLine($"Invalid index specified: {args[1]}");
                    return(false);
                }
            }

            var count = -1;

            if (args.Count > 2)
            {
                if (args[2] != "*" && (!int.TryParse(args[2], out count) || count < 1))
                {
                    Console.WriteLine($"Invalid count specified: {args[2]}");
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);

            var fieldType = field.FieldType;

            if ((field == null) ||
                (!fieldType.IsGenericType) ||
                (fieldType.GetInterface("IList") == null))
            {
                Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]);
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var blockValue = field.GetValue(Owner) as IList;

            if (blockValue == null)
            {
                Console.WriteLine($"Invalid index specified: {args[0]}");
                return(false);
            }

            if (count < 0)
            {
                count = blockValue.Count;
            }

            if ((index + count) < 0 || (index + count) > blockValue.Count)
            {
                Console.WriteLine($"Invalid index: {index}, and count: {count}");
                return(false);
            }

            ElementType = field.FieldType.GenericTypeArguments[0];
            Elements    = new List <object>();

            for (var i = index; i < (index + count); i++)
            {
                Elements.Add(blockValue[i]);
            }

            var itemString = index < 2 ? "element" : "elements";

            Console.WriteLine($"Successfully copied {count} {itemString}.");

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 3)
            {
                return(false);
            }

            var fieldName    = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName    = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(ContextStack, CacheContext, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);



            var fieldType = field.FieldType;

            if ((field == null) ||
                (!fieldType.IsGenericType) ||
                (fieldType.GetInterface("IList") == null))
            {
                Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]);
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var blockValue = field.GetValue(Owner) as IList;

            if (blockValue == null)
            {
                blockValue = Activator.CreateInstance(field.FieldType) as IList;
                field.SetValue(Owner, blockValue);
            }

            var elementType = field.FieldType.GenericTypeArguments[0];

            var index = blockValue.Count - 1;
            var count = 1;

            var genericIndex = false;
            var genericCount = false;

            if (args.Count == 1)
            {
                count = 1;
            }
            else
            {
                if (args.Count >= 2)
                {
                    if (args[1] == "*")
                    {
                        genericIndex = true;
                        index        = blockValue.Count;
                    }
                    else if (!int.TryParse(args[1], out index) || index < 0 || index >= blockValue.Count)
                    {
                        Console.WriteLine($"Invalid index specified: {args[1]}");
                        return(false);
                    }
                }

                if (args.Count == 3)
                {
                    if (args[2] == "*")
                    {
                        genericCount = true;
                        count        = blockValue.Count - index;
                    }
                    else if (!int.TryParse(args[2], out count) || count < 1)
                    {
                        Console.WriteLine($"Invalid number specified: {args[2]}");
                        return(false);
                    }
                }
            }

            if (genericIndex && genericCount)
            {
                index = 0;
                count = blockValue.Count;
            }
            else if (genericIndex)
            {
                index -= count;

                if (index < 0)
                {
                    index = 0;
                }
            }

            if (index + count > blockValue.Count)
            {
                Console.WriteLine($"ERROR: Too many block elements specified to be removed: {count}. Maximum at index {index} can be {blockValue.Count - index}");
                return(false);
            }

            for (var i = 0; i < count; i++)
            {
                blockValue.RemoveAt(index);
            }

            field.SetValue(Owner, blockValue);

            var typeString =
                fieldType.IsGenericType ?
                $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var itemString = count < 2 ? "element" : "elements";

            var valueString =
                ((IList)blockValue).Count != 0 ?
                $"{{...}}[{((IList)blockValue).Count}]" :
                "null";

            Console.WriteLine($"Successfully removed {count} {itemString} from {field.Name} at index {index}: {typeString}");
            Console.WriteLine(valueString);

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
Example #8
0
        public override bool Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }

            var fieldName    = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext   = Stack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName    = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(Stack, Info, Tag, Owner);

                if (!command.Execute(new List <string> {
                    blockName
                }))
                {
                    while (Stack.Context != previousContext)
                    {
                        Stack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (Stack.Context.GetCommand("Edit") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (Stack.Context != previousContext)
                    {
                        Stack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var enumerator = new TagFieldEnumerator(Structure);
            var field      = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);

            if (field == null)
            {
                Console.WriteLine("ERROR: {0} does not contain a field named \"{1}\".", Structure.Types[0].Name, fieldName);
                while (Stack.Context != previousContext)
                {
                    Stack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var fieldType  = field.FieldType;
            var fieldValue = ParseArgs(field.FieldType, args.Skip(1).ToList());

            if (fieldValue != null && fieldValue.Equals(false))
            {
                while (Stack.Context != previousContext)
                {
                    Stack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            field.SetValue(Owner, fieldValue);

            var typeString =
                fieldType.IsGenericType ?
                $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var valueString =
                fieldType == typeof(StringID) ?
                Info.StringIDs.GetString((StringID)fieldValue) :
                fieldType.GetInterface(typeof(IList).Name) != null ?
                (((IList)fieldValue).Count != 0 ?
                 $"{{...}}[{((IList)fieldValue).Count}]" :
                 "null") :
                fieldValue == null ?
                "null" :
                fieldValue.ToString();

            Console.WriteLine("{0}: {1} = {2}", field.Name, typeString, valueString);

            while (Stack.Context != previousContext)
            {
                Stack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
Example #9
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 1)
            {
                return(false);
            }

            var fieldName      = args[0];
            var fieldNameLow   = fieldName.ToLower();
            var fieldNameSnake = fieldName.ToSnakeCase();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            var blockName = "";

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                blockName      = fieldName.Substring(0, lastIndex);
                fieldName      = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow   = fieldName.ToLower();
                fieldNameSnake = fieldName.ToSnakeCase();

                var command = new EditBlockCommand(ContextStack, CacheContext, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f =>
                              f.Name == fieldName ||
                              f.Name.ToLower() == fieldNameLow ||
                              f.Name.ToSnakeCase() == fieldNameSnake);

            var ownerType = Owner.GetType();

            if (field == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, fieldName);
                return(false);
            }

            IList fieldValue = null;

            if (field.FieldType.GetInterface("IList") == null || (fieldValue = (IList)field.GetValue(Owner)) == null)
            {
                Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, fieldName);
                return(false);
            }

            blockName = args[0];
            args      = args.Skip(1).ToList();

            for (var i = 0; i < fieldValue.Count; i++)
            {
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }

                Owner     = previousOwner;
                Structure = previousStructure;

                if (blockName != "" && new EditBlockCommand(ContextStack, CacheContext, Tag, Owner)
                    .Execute(new List <string> {
                    $"{blockName}[{i}]"
                })
                    .Equals(false))
                {
                    return(false);
                }

                Console.Write($"[{i}] ");
                ContextStack.Context.GetCommand(args[0]).Execute(args.Skip(1).ToList());
            }

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }

            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }
Example #10
0
        public override bool Execute(List<string> args)
        {
            if (args.Count < 2)
                return false;

            var fieldName = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext = Stack.Context;
            var previousOwner = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(Stack, Info, Tag, Owner);

                if (!command.Execute(new List<string> { blockName }))
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }

                command = (Stack.Context.GetCommand("Edit") as EditBlockCommand);

                Owner = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }
            }

            var enumerator = new TagFieldEnumerator(Structure);
            var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);

            if (field == null)
            {
                Console.WriteLine("ERROR: {0} does not contain a field named \"{1}\".", Structure.Types[0].Name, fieldName);
                while (Stack.Context != previousContext) Stack.Pop();
                Owner = previousOwner;
                Structure = previousStructure;
                return false;
            }

            var fieldType = field.FieldType;
            var fieldValue = ParseArgs(field.FieldType, args.Skip(1).ToList());

            if (fieldValue != null && fieldValue.Equals(false))
            {
                while (Stack.Context != previousContext) Stack.Pop();
                Owner = previousOwner;
                Structure = previousStructure;
                return false;
            }

            field.SetValue(Owner, fieldValue);

            var typeString =
                fieldType.IsGenericType ?
                    $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var valueString =
                fieldType == typeof(StringID) ?
                    Info.StringIDs.GetString((StringID)fieldValue) :
                fieldType.GetInterface(typeof(IList).Name) != null ?
                    (((IList)fieldValue).Count != 0 ?
                        $"{{...}}[{((IList)fieldValue).Count}]" :
                    "null") :
                fieldValue == null ?
                    "null" :
                fieldValue.ToString();

            Console.WriteLine("{0}: {1} = {2}", field.Name, typeString, valueString);

            while (Stack.Context != previousContext) Stack.Pop();
            Owner = previousOwner;
            Structure = previousStructure;

            return true;
        }
Example #11
0
        public override bool Execute(List<string> args)
        {
            if (args.Count < 1 || args.Count > 3)
                return false;

            var fieldName = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext = Stack.Context;
            var previousOwner = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(Stack, Info, Tag, Owner);

                if (!command.Execute(new List<string> { blockName }))
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }

                command = (Stack.Context.GetCommand("Edit") as EditBlockCommand);

                Owner = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }
            }

            var enumerator = new TagFieldEnumerator(Structure);
            var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);
            var fieldType = field.FieldType;

            if ((field == null) ||
                (!fieldType.IsGenericType) ||
                (fieldType.GetInterface("IList") == null))
            {
                Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]);
                while (Stack.Context != previousContext) Stack.Pop();
                Owner = previousOwner;
                Structure = previousStructure;
                return false;
            }

            var blockValue = field.GetValue(Owner) as IList;

            if (blockValue == null)
            {
                blockValue = Activator.CreateInstance(field.FieldType) as IList;
                field.SetValue(Owner, blockValue);
            }

            var elementType = field.FieldType.GenericTypeArguments[0];

            var index = blockValue.Count - 1;
            var count = 1;

            var genericIndex = false;
            var genericCount = false;

            if (args.Count == 1)
            {
                count = 1;
            }
            else
            {
                if (args.Count >= 2)
                {
                    if (args[1] == "*")
                    {
                        genericIndex = true;
                        index = blockValue.Count;
                    }
                    else if (!int.TryParse(args[1], out index) || index < 0 || index >= blockValue.Count)
                    {
                        Console.WriteLine($"Invalid index specified: {args[1]}");
                        return false;
                    }
                }

                if (args.Count == 3)
                {
                    if (args[2] == "*")
                    {
                        genericCount = true;
                        count = blockValue.Count - index;
                    }
                    else if (!int.TryParse(args[2], out count) || count < 1)
                    {
                        Console.WriteLine($"Invalid number specified: {args[2]}");
                        return false;
                    }
                }
            }

            if (genericIndex && genericCount)
            {
                index = 0;
                count = blockValue.Count;
            }
            else if (genericIndex)
            {
                index -= count;

                if (index < 0)
                    index = 0;
            }

            if (index + count > blockValue.Count)
            {
                Console.WriteLine($"ERROR: Too many block elements specified to be removed: {count}. Maximum at index {index} can be {blockValue.Count - index}");
                return false;
            }

            for (var i = 0; i < count; i++)
                blockValue.RemoveAt(index);

            field.SetValue(Owner, blockValue);

            var typeString =
                fieldType.IsGenericType ?
                    $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var itemString = count < 2 ? "element" : "elements";

            var valueString =
                ((IList)blockValue).Count != 0 ?
                    $"{{...}}[{((IList)blockValue).Count}]" :
                "null";

            Console.WriteLine($"Successfully removed {count} {itemString} from {field.Name} at index {index}: {typeString}");
            Console.WriteLine(valueString);

            while (Stack.Context != previousContext) Stack.Pop();
            Owner = previousOwner;
            Structure = previousStructure;

            return true;
        }
        public override bool Execute(List<string> args)
        {
            if (args.Count < 1 || args.Count > 2)
                return false;

            if (CopyElementsCommand.Elements == null)
            {
                Console.WriteLine("ERROR: No elements are available in the clipboard.");
                return false;
            }

            var fieldName = args[0];
            var fieldNameLow = fieldName.ToLower();

            var previousContext = Stack.Context;
            var previousOwner = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow = fieldName.ToLower();

                var command = new EditBlockCommand(Stack, Info, Tag, Owner);

                if (!command.Execute(new List<string> { blockName }))
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }

                command = (Stack.Context.GetCommand("Edit") as EditBlockCommand);

                Owner = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (Stack.Context != previousContext) Stack.Pop();
                    Owner = previousOwner;
                    Structure = previousStructure;
                    return false;
                }
            }

            var index = -1;

            if (args.Count > 1)
            {
                if (args[1] != "*" && (!int.TryParse(args[1], out index) || index < 0))
                {
                    Console.WriteLine($"Invalid index specified: {args[1]}");
                    return false;
                }
            }

            var enumerator = new TagFieldEnumerator(Structure);
            var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow);
            var fieldType = field.FieldType;

            if ((field == null) ||
                (!fieldType.IsGenericType) ||
                (fieldType.GetInterface("IList") == null))
            {
                Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]);
                while (Stack.Context != previousContext) Stack.Pop();
                Owner = previousOwner;
                Structure = previousStructure;
                return false;
            }

            var elementType = field.FieldType.GenericTypeArguments[0];

            if (elementType != CopyElementsCommand.ElementType)
            {
                Console.WriteLine("Invalid block element type!");
                return false;
            }

            var blockValue = field.GetValue(Owner) as IList;

            if (blockValue == null)
            {
                blockValue = Activator.CreateInstance(field.FieldType) as IList;
                field.SetValue(Owner, blockValue);
            }

            if (index > blockValue.Count)
            {
                Console.WriteLine($"Invalid index specified: {args[2]}");
                return false;
            }

            for (var i = 0; i < CopyElementsCommand.Elements.Count; i++)
            {
                var element = CopyElementsCommand.Elements[i];

                if (index == -1)
                    blockValue.Add(element);
                else
                    blockValue.Insert(index + i, element);
            }

            field.SetValue(Owner, blockValue);

            var typeString =
                fieldType.IsGenericType ?
                    $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" :
                fieldType.Name;

            var itemString = CopyElementsCommand.Elements.Count < 2 ? "element" : "elements";

            var valueString =
                ((IList)blockValue).Count != 0 ?
                    $"{{...}}[{((IList)blockValue).Count}]" :
                "null";

            Console.WriteLine($"Successfully pasted {CopyElementsCommand.Elements.Count} {itemString} to {field.Name}: {typeString}");
            Console.WriteLine(valueString);

            while (Stack.Context != previousContext) Stack.Pop();
            Owner = previousOwner;
            Structure = previousStructure;

            return true;
        }
        public override object Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }

            var fieldName = args[0];
            var file      = new FileInfo(args[1]);

            var fieldNameLow   = fieldName.ToLower();
            var fieldNameSnake = fieldName.ToSnakeCase();

            var previousContext   = ContextStack.Context;
            var previousOwner     = Owner;
            var previousStructure = Structure;

            if (fieldName.Contains("."))
            {
                var lastIndex = fieldName.LastIndexOf('.');
                var blockName = fieldName.Substring(0, lastIndex);
                fieldName      = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1);
                fieldNameLow   = fieldName.ToLower();
                fieldNameSnake = fieldName.ToSnakeCase();

                var command = new EditBlockCommand(ContextStack, CacheContext, Tag, Owner);

                if (command.Execute(new List <string> {
                    blockName
                }).Equals(false))
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }

                command = (ContextStack.Context.GetCommand("EditBlock") as EditBlockCommand);

                Owner     = command.Owner;
                Structure = command.Structure;

                if (Owner == null)
                {
                    while (ContextStack.Context != previousContext)
                    {
                        ContextStack.Pop();
                    }
                    Owner     = previousOwner;
                    Structure = previousStructure;
                    return(false);
                }
            }

            var field = TagStructure.GetTagFieldEnumerable(Structure)
                        .Find(f =>
                              f.Name == fieldName ||
                              f.Name.ToLower() == fieldNameLow ||
                              f.Name.ToSnakeCase() == fieldNameSnake);

            if (field == null)
            {
                Console.WriteLine($"ERROR: {Structure.Types[0].Name} does not contain a field named \"{fieldName}\".");
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }
            else if (field.FieldType != typeof(PageableResource))
            {
                Console.WriteLine($"ERROR: {Structure.Types[0].Name}.{field.Name} is not of type {nameof(PageableResource)}.");
                while (ContextStack.Context != previousContext)
                {
                    ContextStack.Pop();
                }
                Owner     = previousOwner;
                Structure = previousStructure;
                return(false);
            }

            var fieldType  = field.FieldType;
            var fieldAttrs = field.GetCustomAttributes(typeof(TagFieldAttribute), false);
            var fieldAttr  = fieldAttrs?.Length < 1 ? new TagFieldAttribute() : (TagFieldAttribute)fieldAttrs[0];
            var fieldInfo  = new TagFieldInfo(field, fieldAttr, uint.MaxValue, uint.MaxValue);
            var fieldValue = field.GetValue(Owner) as PageableResource;

            if (!file.Directory.Exists)
            {
                file.Directory.Create();
            }

            File.WriteAllBytes(file.FullName, CacheContext.ExtractRawResource(fieldValue));
            Console.WriteLine($"Wrote 0x{fieldValue.Page.CompressedBlockSize:X} bytes to \"{file.FullName}\".");

            while (ContextStack.Context != previousContext)
            {
                ContextStack.Pop();
            }
            Owner     = previousOwner;
            Structure = previousStructure;

            return(true);
        }