Beispiel #1
0
        public static TagMatchingRuleDescriptorBuilder RequireTagStructure(this TagMatchingRuleDescriptorBuilder builder, TagStructure tagStructure)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.TagStructure = tagStructure;

            return(builder);
        }
Beispiel #2
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);
        }
Beispiel #3
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(CacheContext, 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);
        }
        public static RazorDiagnostic CreateParsing_TagHelperMustNotHaveAnEndTag(SourceSpan location, string tagName, string displayName, TagStructure tagStructure)
        {
            var diagnostic = RazorDiagnostic.Create(
                Parsing_TagHelperMustNotHaveAnEndTag,
                location,
                tagName,
                displayName,
                tagStructure);

            return(diagnostic);
        }
Beispiel #5
0
        /// <summary>
        /// Deserializes a complex value.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="valueInfo">The value information. Can be <c>null</c>.</param>
        /// <param name="valueType">The type of the value to deserialize.</param>
        /// <returns>The deserialized value.</returns>
        public object DeserializeComplexValue(EndianReader reader, ISerializationContext context, TagFieldAttribute valueInfo, Type valueType)
        {
            // Indirect objects
            // TODO: Remove ResourceReference hax, the Indirect flag wasn't available when I generated the tag structures
            if (valueInfo != null && valueInfo.Flags.HasFlag(TagFieldFlags.Pointer))
            {
                return(DeserializeIndirectValue(reader, context, valueType));
            }

            // enum = Enum type
            if (valueType.IsEnum)
            {
                return(DeserializePrimitiveValue(reader, valueType.GetEnumUnderlyingType()));
            }

            // string = ASCII string
            if (valueType == typeof(string))
            {
                return(DeserializeString(reader, valueInfo));
            }

            if (valueType == typeof(Tag))
            {
                return(new Tag(reader.ReadInt32()));
            }

            // TagInstance = Tag reference
            if (valueType == typeof(CachedTagInstance))
            {
                return(DeserializeTagReference(reader, context, valueInfo));
            }

            // ResourceAddress = Resource address
            if (valueType == typeof(CacheAddress))
            {
                return(new CacheAddress(reader.ReadUInt32()));
            }

            // Byte array = Data reference
            // TODO: Allow other types to be in data references, since sometimes they can point to a structure
            if (valueType == typeof(byte[]) && valueInfo.Length == 0)
            {
                return(DeserializeDataReference(reader, context));
            }

            // Color types
            if (valueType == typeof(RealRgbColor))
            {
                return(new RealRgbColor(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            else if (valueType == typeof(RealArgbColor))
            {
                return(new RealArgbColor(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            else if (valueType == typeof(ArgbColor))
            {
                return(new ArgbColor(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()));
            }

            if (valueType == typeof(Point2d))
            {
                return(new Point2d(reader.ReadInt16(), reader.ReadInt16()));
            }
            if (valueType == typeof(Rectangle2d))
            {
                return(new Rectangle2d(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16()));
            }

            if (valueType == typeof(RealEulerAngles2d))
            {
                var i = Angle.FromRadians(reader.ReadSingle());
                var j = Angle.FromRadians(reader.ReadSingle());
                return(new RealEulerAngles2d(i, j));
            }
            else if (valueType == typeof(RealEulerAngles3d))
            {
                var i = Angle.FromRadians(reader.ReadSingle());
                var j = Angle.FromRadians(reader.ReadSingle());
                var k = Angle.FromRadians(reader.ReadSingle());
                return(new RealEulerAngles3d(i, j, k));
            }

            if (valueType == typeof(RealPoint2d))
            {
                return(new RealPoint2d(reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealPoint3d))
            {
                return(new RealPoint3d(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealVector2d))
            {
                return(new RealVector2d(reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealVector3d))
            {
                return(new RealVector3d(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealQuaternion))
            {
                return(new RealQuaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealPlane2d))
            {
                return(new RealPlane2d(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealPlane3d))
            {
                return(new RealPlane3d(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }
            if (valueType == typeof(RealMatrix4x3))
            {
                return(new RealMatrix4x3(
                           reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                           reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                           reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                           reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }

            // StringID
            if (valueType == typeof(StringId))
            {
                return(new StringId(reader.ReadUInt32(), Version));
            }

            // Angle (radians)
            if (valueType == typeof(Angle))
            {
                return(Angle.FromRadians(reader.ReadSingle()));
            }

            // Non-byte array = Inline array
            // TODO: Define more clearly in general what constitutes a data reference and what doesn't
            if (valueType.IsArray)
            {
                return(DeserializeInlineArray(reader, context, valueInfo, valueType));
            }

            // List = Tag block
            if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(List <>))
            {
                return(DeserializeTagBlock(reader, context, valueType));
            }

            // Ranges
            if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(Bounds <>))
            {
                return(DeserializeRange(reader, context, valueType));
            }

            if (valueType == typeof(VertexShaderReference))
            {
                return(DeserializeVertexShaderReference(reader, context));
            }

            if (valueType == typeof(PixelShaderReference))
            {
                return(DeserializePixelShaderReference(reader, context));
            }

            // Assume the value is a structure
            return(DeserializeStruct(reader, context, TagStructure.GetTagStructureInfo(valueType, Version)));
        }
Beispiel #6
0
        private Dictionary <string, IFieldControl> CreateFieldControls(CacheForm form, Control parent, Type type)
        {
            Enabled = false;

            var result     = new Dictionary <string, IFieldControl>();
            var enumerator = TagStructure.GetTagFieldEnumerable(new TagStructureInfo(type, CacheContext.Version));

            var currentLocation = new Point(parent is GroupBox ? 3 : 0, parent is GroupBox ? 16 : 0);

            foreach (var fieldInfo in enumerator)
            {
                if (fieldInfo.Attribute.Flags.HasFlag(TagFieldFlags.Padding))
                {
                    continue;
                }

                var fieldType   = fieldInfo.FieldInfo.FieldType;
                var isFlagsEnum = (fieldType.GetCustomAttributes(typeof(FlagsAttribute), false).FirstOrDefault() as FlagsAttribute ?? null) != null;
                var isTagBlock  = (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List <>));
                var isStruct    = (fieldType.GetCustomAttributes(typeof(TagStructureAttribute), false).FirstOrDefault() as TagStructureAttribute ?? null) != null;
                var isBounds    = (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bounds <>));

                Control control = null;

                if (fieldType == typeof(StringId))
                {
                    control = new StringIdControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType.IsEnum)
                {
                    if (isFlagsEnum)
                    {
                        control = new FlagsControl(fieldInfo.FieldInfo);
                    }
                    else
                    {
                        control = new EnumControl(fieldInfo.FieldInfo);
                    }
                }
                else if (fieldType == typeof(Point2d))
                {
                    control = new Point2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(Rectangle2d))
                {
                    control = new Rectangle2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(ArgbColor))
                {
                    control = new ArgbColorControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealPoint2d))
                {
                    control = new RealPoint2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealPoint3d))
                {
                    control = new RealPoint3dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealVector2d))
                {
                    control = new RealVector2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealVector3d))
                {
                    control = new RealVector3dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealQuaternion))
                {
                    control = new RealQuaternionControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealRgbColor))
                {
                    control = new RealRgbColorControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealArgbColor))
                {
                    control = new RealArgbColorControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealEulerAngles2d))
                {
                    control = new RealEulerAngles2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealEulerAngles3d))
                {
                    control = new RealEulerAngles3dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealPlane2d))
                {
                    control = new RealPlane2dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(RealPlane3d))
                {
                    control = new RealPlane3dControl(CacheContext, fieldInfo.FieldInfo);
                }
                else if (fieldType == typeof(CachedTagInstance))
                {
                    control = new TagReferenceControl(form, CacheContext, fieldInfo.FieldInfo);
                }
                else if (isTagBlock)
                {
                    control = new BlockControl(form, CacheContext, fieldType, fieldInfo.FieldInfo);

                    if (((BlockControl)control).Struct.FieldControls.Count == 0)
                    {
                        continue;
                    }
                }
                else if (isStruct)
                {
                    control = new StructControl(form, CacheContext, fieldType, fieldInfo.FieldInfo);

                    if (((StructControl)control).FieldControls.Count == 0)
                    {
                        continue;
                    }
                }
                else if (isBounds)
                {
                    control = new BoundsControl(CacheContext, fieldInfo.FieldInfo);
                }
                else
                {
                    control = new ValueControl(CacheContext, fieldInfo.FieldInfo);
                }

                control.Location = new Point(currentLocation.X, currentLocation.Y);
                parent.Controls.Add(control);

                currentLocation.Y = control.Bottom;

                if (parent is GroupBox gb && gb.AutoSize == false)
                {
                    parent.Width  = control.Right + 8;
                    parent.Height = control.Bottom + 6;
                }

                if (isStruct || isTagBlock)
                {
                    control.BringToFront();
                }

                result[fieldInfo.FieldInfo.Name] = (IFieldControl)control;

                Application.DoEvents();
            }

            Enabled = true;

            return(result);
        }
Beispiel #7
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);
            }

            string fromName = null;
            int?   from     = null;

            string toName = null;
            int?   to     = null;

            while (true)
            {
                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      = args.Skip(1).ToList();

            for (var i = (from.HasValue ? from.Value : 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, CacheContext, Tag, Owner)
                    .Execute(new List <string> {
                    $"{blockName}[{i}]"
                })
                    .Equals(false))
                {
                    return(false);
                }

                var label = GetLabel(fieldValue, i);

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

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

            Owner     = previousOwner;
            Structure = previousStructure;

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

            var match = (args.Count == 1);
            var token = match ? args[0].ToLower() : "";

			foreach (var tagFieldInfo in TagStructure.GetTagFieldEnumerable(Structure))
			{
				if (tagFieldInfo.Attribute != null && tagFieldInfo.Attribute.Flags.HasFlag(Padding))
					continue;

				var nameString = tagFieldInfo.Name;

				if (match && !nameString.ToLower().Contains(token))
					continue;

				var fieldType = tagFieldInfo.FieldType;
				var fieldValue = tagFieldInfo.GetValue(Value);

				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 (tagFieldInfo.FieldType.IsArray && tagFieldInfo.Attribute.Length != 0)
                {
                    valueString = fieldValue == null ? "null" : $"[{tagFieldInfo.Attribute.Length}] {{ ";
                    var valueArray = (Array)fieldValue;

                    if (fieldValue != null)
                    {
                        for (var i = 0; i < tagFieldInfo.Attribute.Length; i++)
                            valueString += $"{valueArray.GetValue(i)}{((i + 1) < tagFieldInfo.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 fieldName = $"{tagFieldInfo.DeclaringType.FullName}.{tagFieldInfo.Name}".Replace("+", ".");
				var documentationNode = EditTagContextFactory.Documentation.SelectSingleNode($"//member[starts-with(@name, 'F:{fieldName}')]");

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

			return true;
        }
 private static TagFieldInfo FindLabelField(Type type, CacheVersion version)
 {
     return(TagStructure.GetTagFieldEnumerable(type, version)
            .FirstOrDefault(field => field.Attribute != null && field.Attribute.Flags.HasFlag(TagFieldFlags.Label)));
 }
Beispiel #10
0
        public VertexShaderReference DeserializeVertexShaderReference(EndianReader reader, ISerializationContext context)
        {
            // This reference is a uint32 pointer, we'll be moving the stream position around. Right before returning
            // from this method 'reader.SeekTo(endPosition)' will bring us to where the serializer expects the next
            // bit of data to be.
            var endPosition = reader.BaseStream.Position + 0x04;

            var headerAddress = reader.ReadUInt32();

            if (headerAddress < 1)
            {
                return(null);
            }

            var headerOffset = context.AddressToOffset((uint)(reader.BaseStream.Position - 4), headerAddress);

            reader.SeekTo(headerOffset);

            var header = (VertexShaderHeader)DeserializeStruct(reader, context, TagStructure.GetTagStructureInfo(typeof(VertexShaderHeader)));

            if (header.ShaderDataAddress == 0)
            {
                return(null);
            }

            var debugHeaderOffset = reader.Position;
            var debugHeader       = (ShaderDebugHeader)DeserializeStruct(reader, context, TagStructure.GetTagStructureInfo(typeof(ShaderDebugHeader)));

            if ((debugHeader.Magic >> 16) != 0x102A)
            {
                return(null);
            }

            if (debugHeader.StructureSize == 0)
            {
                return(null);
            }

            reader.SeekTo(debugHeaderOffset);
            var debugData = reader.ReadBytes((int)debugHeader.StructureSize);

            var updbName = "";

            if (debugHeader.UpdbPointerOffset != 0)
            {
                reader.SeekTo(debugHeaderOffset + (long)debugHeader.UpdbPointerOffset);
                var updbNameLength = reader.ReadUInt64();

                if (updbNameLength > 0)
                {
                    updbName = new string(reader.ReadChars((int)updbNameLength));
                }
            }

            var totalSize    = debugHeader.ShaderDataSize;
            var constantSize = 0U;
            var codeSize     = totalSize;

            if (debugHeader.CodeHeaderOffset != 0)
            {
                reader.SeekTo(debugHeaderOffset + debugHeader.CodeHeaderOffset);
                constantSize = reader.ReadUInt32();
                codeSize     = reader.ReadUInt32();
            }

            var constant_block_offset = context.AddressToOffset(headerOffset + 0x10, header.ShaderDataAddress);

            reader.SeekTo(constant_block_offset);
            var constantData = reader.ReadBytes((int)constantSize);

            var shader_data_block_offset = constant_block_offset + constantSize;

            reader.SeekTo(shader_data_block_offset);
            var shaderData = reader.ReadBytes((int)codeSize);

            reader.SeekTo(endPosition);

            var info = new XboxShaderInfo
            {
                DataAddress      = shader_data_block_offset,
                DebugInfoOffset  = (uint)debugHeaderOffset,
                DebugInfoSize    = debugHeader.StructureSize,
                DatabasePath     = updbName,
                DataSize         = totalSize,
                ConstantDataSize = constantSize,
                CodeDataSize     = codeSize
            };

            return(new VertexShaderReference
            {
                Info = info,
                UpdbName = updbName,
                Header = header,
                DebugHeader = debugHeader,
                DebugData = debugData,
                ShaderData = shaderData,
                ConstantData = constantData
            });
        }
        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, 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 = -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);
        }
        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);
        }
        public override object Execute(List <string> args)
        {
            if (args.Count > 1)
            {
                return(false);
            }

            var match = (args.Count == 1);
            var token = match ? args[0].ToLower() : "";

            foreach (var tagFieldInfo in TagStructure.GetTagFieldEnumerable(Structure))
            {
                if (tagFieldInfo.Attribute != null && tagFieldInfo.Attribute.Flags.HasFlag(TagFieldFlags.Padding))
                {
                    continue;
                }

                var nameString = tagFieldInfo.Name;

                if (match && !nameString.ToLower().Contains(token))
                {
                    continue;
                }

                var fieldType  = tagFieldInfo.FieldType;
                var fieldValue = tagFieldInfo.GetValue(Value);

                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.GetInterface(typeof(IList).Name) != null)
                {
                    valueString =
                        ((IList)fieldValue).Count != 0 ?
                        $"{{...}}[{((IList)fieldValue).Count}]" :
                        "null";
                }
                else if (fieldValue is StringId stringId)
                {
                    valueString = BlamCache.Version < CacheVersion.Halo3Retail ?
                                  BlamCache.Strings.GetItemByID((int)(stringId.Value & 0xFFFF)) :
                                  BlamCache.Strings.GetString(stringId);
                }
                else if (fieldType == typeof(CachedTagInstance))
                {
                    var instance = (CachedTagInstance)fieldValue;

                    var item = BlamCache.IndexItems.GetItemByID(instance.Index);

                    valueString = item == null ? "<null>" : $"[0x{instance.Index:X8}] {item.Name}.{item.GroupName}";
                }
                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
                {
                    valueString = fieldValue.ToString();
                }
#if !DEBUG
            }
            catch (Exception e)
            {
                valueString = $"<ERROR MESSAGE=\"{e.Message}\" />";
            }
#endif

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

            return(true);
        }
Beispiel #14
0
        public static CommandContext Create(CommandContextStack contextStack, HaloOnlineCacheContext cacheContext, CachedTagInstance tag, object definition)
        {
            var documentationPath = $"{new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName}\\TagTool.xml";

            if (Documentation.ChildNodes.Count == 0 && File.Exists(documentationPath))
            {
                Documentation.Load(documentationPath);
            }

            var groupName = cacheContext.GetString(tag.Group.Name);
            var tagName   = tag?.Name ?? $"0x{tag.Index:X4}";

            var commandContext = new CommandContext(contextStack.Context, string.Format("{0}.{1}", tagName, groupName));

            switch (tag.Group.Tag.ToString())
            {
            case "bink":
                VideoContextFactory.Populate(commandContext, cacheContext, tag, (Bink)definition);
                break;

            case "bitm":     // bitmap
                BitmapContextFactory.Populate(commandContext, cacheContext, tag, (Bitmap)definition);
                break;

            case "coll":
                CollisionModelContextFactory.Populate(commandContext, cacheContext, tag, (CollisionModel)definition);
                break;

            case "hlmt":     // model
                ModelContextFactory.Populate(commandContext, cacheContext, tag, (Model)definition);
                break;

            case "jmad":
                AnimationContextFactory.Populate(commandContext, cacheContext, tag, (ModelAnimationGraph)definition);
                break;

            case "Lbsp":
                LightmapContextFactory.Populate(commandContext, cacheContext, tag, (ScenarioLightmapBspData)definition);
                break;

            case "mode":     // render_model
                RenderModelContextFactory.Populate(commandContext, cacheContext, tag, (RenderModel)definition);
                break;

            case "pmdf":
                ParticleModelContextFactory.Populate(commandContext, cacheContext, tag, (ParticleModel)definition);
                break;

            case "rm  ":     // render_method
            case "rmsh":     // shader
            case "rmd ":     // shader_decal
            case "rmfl":     // shader_foliage
            case "rmhg":     // shader_halogram
            case "rmss":     // shader_screen
            case "rmtr":     // shader_terrain
            case "rmw ":     // shader_water
            case "rmzo":     // shader_zonly
            case "rmcs":     // shader_custom
                RenderMethodContextFactory.Populate(commandContext, cacheContext, tag, (RenderMethod)definition);
                break;

            case "sbsp":
                BSPContextFactory.Populate(commandContext, cacheContext, tag, (ScenarioStructureBsp)definition);
                break;

            case "scnr":
                ScnrContextFactory.Populate(commandContext, cacheContext, tag, (Scenario)definition);
                break;

            case "snd!":
                SoundContextFactory.Populate(commandContext, cacheContext, tag, (Sound)definition);
                break;

            case "unic":     // multilingual_unicode_string_list
                UnicodeContextFactory.Populate(commandContext, cacheContext, tag, (MultilingualUnicodeStringList)definition);
                break;

            case "vfsl":     // vfiles_list
                VFilesContextFactory.Populate(commandContext, cacheContext, tag, (VFilesList)definition);
                break;

            case "pixl":
                Shaders.ShaderContextFactory <PixelShader> .Populate(commandContext, cacheContext, tag, (PixelShader)definition);

                break;

            case "vtsh":
                Shaders.ShaderContextFactory <VertexShader> .Populate(commandContext, cacheContext, tag, (VertexShader)definition);

                break;

            case "glps":
                Shaders.ShaderContextFactory <GlobalPixelShader> .Populate(commandContext, cacheContext, tag, (GlobalPixelShader)definition);

                break;

            case "glvs":
                Shaders.ShaderContextFactory <GlobalVertexShader> .Populate(commandContext, cacheContext, tag, (GlobalVertexShader)definition);

                break;

            case "rmt2":
                Shaders.RenderMethodTemplateContextFactory.Populate(commandContext, cacheContext, tag, (RenderMethodTemplate)definition);
                break;
            }

            var structure = TagStructure.GetTagStructureInfo(TagDefinition.Find(tag.Group.Tag), cacheContext.Version);

            commandContext.AddCommand(new ListFieldsCommand(cacheContext, structure, definition));
            commandContext.AddCommand(new SetFieldCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new EditBlockCommand(contextStack, cacheContext, tag, definition));
            commandContext.AddCommand(new AddBlockElementsCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new RemoveBlockElementsCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new CopyBlockElementsCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new PasteBlockElementsCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new ForEachCommand(contextStack, cacheContext, tag, structure, definition));
            commandContext.AddCommand(new SaveTagChangesCommand(cacheContext, tag, definition));
            commandContext.AddCommand(new PokeTagChangesCommand(cacheContext, tag, definition));
            commandContext.AddCommand(new ExitToCommand(contextStack));

            return(commandContext);
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
        /// <summary>
        /// Serializes a complex value.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="value">The value.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        /// <param name="valueType">Type of the value.</param>
        private void SerializeComplexValue(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object value, TagFieldAttribute valueInfo, Type valueType)
        {
            if (valueInfo != null && valueInfo.Flags.HasFlag(TagFieldFlags.Pointer))
            {
                SerializeIndirectValue(version, context, tagStream, block, value, valueType);
            }
            else if (valueType.IsEnum)
            {
                SerializePrimitiveValue(block.Writer, value, valueType.GetEnumUnderlyingType());
            }
            else if (valueType == typeof(string))
            {
                SerializeString(block.Writer, (string)value, valueInfo);
            }
            else if (valueType == typeof(Tag))
            {
                SerializeTag(block, (Tag)value);
            }
            else if (valueType == typeof(CachedTagInstance))
            {
                SerializeTagReference(context, block.Writer, (CachedTagInstance)value, valueInfo);
            }
            else if (valueType == typeof(CacheAddress))
            {
                block.Writer.Write(((CacheAddress)value).Value);
            }
            else if (valueType == typeof(byte[]))
            {
                if (valueInfo.Flags.HasFlag(TagFieldFlags.Padding) || (value == null && valueInfo.Length > 0))
                {
                    block.Writer.Write(new byte[valueInfo.Length]);
                }
                else if (valueInfo.Length > 0)
                {
                    block.Writer.Write((byte[])value);
                }
                else
                {
                    SerializeDataReference(tagStream, block, (byte[])value, valueInfo);
                }
            }
            else if (valueType == typeof(RealRgbColor))
            {
                SerializeColor(block, (RealRgbColor)value);
            }
            else if (valueType == typeof(RealArgbColor))
            {
                SerializeColor(block, (RealArgbColor)value);
            }
            else if (valueType == typeof(ArgbColor))
            {
                SerializeColor(block, (ArgbColor)value);
            }
            else if (valueType == typeof(ArgbColor))
            {
                SerializeColor(block, (ArgbColor)value);
            }
            else if (valueType == typeof(RealEulerAngles2d))
            {
                SerializeEulerAngles(block, (RealEulerAngles2d)value);
            }
            else if (valueType == typeof(RealEulerAngles3d))
            {
                SerializeEulerAngles(block, (RealEulerAngles3d)value);
            }
            else if (valueType == typeof(Point2d))
            {
                SerializePoint(block, (Point2d)value);
            }
            else if (valueType == typeof(Rectangle2d))
            {
                SerializeRectangle(block, (Rectangle2d)value);
            }
            else if (valueType == typeof(RealPoint2d))
            {
                SerializePoint(block, (RealPoint2d)value);
            }
            else if (valueType == typeof(RealPoint3d))
            {
                SerializePoint(block, (RealPoint3d)value);
            }
            else if (valueType == typeof(RealVector2d))
            {
                SerializeVector(block, (RealVector2d)value);
            }
            else if (valueType == typeof(RealVector3d))
            {
                SerializeVector(block, (RealVector3d)value);
            }
            else if (valueType == typeof(RealQuaternion))
            {
                SerializeVector(block, (RealQuaternion)value);
            }
            else if (valueType == typeof(RealPlane2d))
            {
                SerializePlane(block, (RealPlane2d)value);
            }
            else if (valueType == typeof(RealPlane3d))
            {
                SerializePlane(block, (RealPlane3d)value);
            }
            else if (valueType == typeof(RealMatrix4x3))
            {
                SerializeMatrix(block, (RealMatrix4x3)value);
            }
            else if (valueType == typeof(StringId))
            {
                block.Writer.Write(((StringId)value).Value);
            }
            else if (valueType == typeof(Angle))
            {
                block.Writer.Write(((Angle)value).Radians);
            }
            else if (valueType == typeof(DatumIndex))
            {
                block.Writer.Write(((DatumIndex)value).Value);
            }
            else if (valueType == typeof(VertexShaderReference))
            {
                block.Writer.Write(0); // TODO: fix  (not used in halo online)
            }
            else if (valueType == typeof(PixelShaderReference))
            {
                block.Writer.Write(0); // TODO: fix  (not used in halo online)
            }
            else if (valueType.IsArray)
            {
                SerializeInlineArray(version, context, tagStream, block, (Array)value, valueInfo, valueType);
            }
            else if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(List <>))
            {
                SerializeTagBlock(version, context, tagStream, block, value, valueType, valueInfo);
            }
            else if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(Bounds <>))
            {
                SerializeRange(version, context, tagStream, block, value);
            }
            else
            {
                if (value == null)
                {
                    value = Activator.CreateInstance(valueType);
                }

                SerializeStruct(context, tagStream, block, TagStructure.GetTagStructureInfo(valueType, version), value);
            }
        }
        public void Rewrite_AllowsCompatibleTagStructures(
            string documentContent,
            TagStructure structure1,
            TagStructure structure2,
            MarkupBlock expectedOutput)
        {
            // Arrange
            var factory = CreateDefaultSpanFactory();
            var blockFactory = new BlockFactory(factory);
            var descriptors = new TagHelperDescriptor[]
                {
                    new TagHelperDescriptor
                    {
                        TagName = "input",
                        TypeName = "InputTagHelper1",
                        AssemblyName = "SomeAssembly",
                        TagStructure = structure1
                    },
                    new TagHelperDescriptor
                    {
                        TagName = "input",
                        TypeName = "InputTagHelper2",
                        AssemblyName = "SomeAssembly",
                        TagStructure = structure2
                    }
                };
            var descriptorProvider = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
        }
        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);
        }
 private static TagHelperDescriptor BuildTagHelperDescriptor(
     string tagName,
     string typeName,
     string assemblyName,
     IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
     IEnumerable<string> requiredAttributes,
     IEnumerable<string> allowedChildren,
     TagStructure tagStructure,
     TagHelperDesignTimeDescriptor designTimeDescriptor)
 {
     return new TagHelperDescriptor
     {
         TagName = tagName,
         TypeName = typeName,
         AssemblyName = assemblyName,
         Attributes = attributeDescriptors,
         RequiredAttributes = requiredAttributes,
         AllowedChildren = allowedChildren,
         TagStructure = tagStructure,
         DesignTimeDescriptor = designTimeDescriptor
     };
 }
Beispiel #21
0
        public void GetFieldValue(object owner, object value = null, object definition = null)
        {
            if (value == null)
            {
                value = Field.GetValue(owner);
            }

            if (value == null)
            {
                value = Activator.CreateInstance(Field.FieldType);
            }

            Owner = owner;
            elementsComboBox.Items.Clear();

            Definition = definition;

            var elements = value as IList;

            FieldInfo labelField = null;

            var enumerator = TagStructure.GetTagFieldEnumerable(new TagStructureInfo((Field?.FieldType ?? value.GetType()).GenericTypeArguments[0], Struct.Cache.Version));

            foreach (var fieldInfo in enumerator)
            {
                if (fieldInfo.Attribute.Flags.HasFlag(TagFieldFlags.Label))
                {
                    labelField = fieldInfo.FieldInfo;
                    break;
                }
            }

            for (var i = 0; i < elements.Count; i++)
            {
                var label = "";

                if (labelField != null)
                {
                    if (labelField.FieldType == typeof(string))
                    {
                        label = (string)labelField.GetValue(elements[i]);
                    }
                    else if (labelField.FieldType == typeof(StringId))
                    {
                        label = Cache.StringTable.GetString((StringId)labelField.GetValue(elements[i]));
                    }
                    else if (labelField.FieldType.IsEnum)
                    {
                        label = labelField.GetValue(elements[i]).ToString().ToSnakeCase();
                    }
                    else if (labelField.FieldType == typeof(short))
                    {
                        if (definition != null)
                        {
                            if (definition.GetType() == typeof(Scenario))
                            {
                                var index = (short)labelField.GetValue(elements[i]);
                                var names = ((Scenario)definition).ObjectNames;

                                if (index >= 0 && index < names.Count)
                                {
                                    label = ((Scenario)definition).ObjectNames[index].Name;
                                }
                            }
                        }
                    }
                    else if (labelField.FieldType == typeof(CachedTag))
                    {
                        var instance = (CachedTag)labelField.GetValue(elements[i]);

                        if (instance != null)
                        {
                            var tagName = instance.Name ?? $"0x{instance.Index:X4}";

                            if (tagName.Contains("\\"))
                            {
                                var index = tagName.LastIndexOf('\\') + 1;
                                tagName = tagName.Substring(index, tagName.Length - index);
                            }

                            label = tagName;
                        }
                    }
                }

                elementsComboBox.Items.Add(new TagBlockElement(i, label, elements[i]));
            }

            if (elementsComboBox.Items.Count > 0)
            {
                elementsComboBox.SelectedIndex = 0;
            }
            else
            {
                Struct.Enabled = false;
            }
        }