Utility class for analyzing a tag structure type's inheritance hierarchy.
 public BinaryReader BeginDeserialize(TagStructureInfo info)
 {
     var data = _cache.ExtractTagRaw(_stream, Tag);
     var reader = new BinaryReader(new MemoryStream(data));
     reader.BaseStream.Position = Tag.MainStructOffset;
     return reader;
 }
 public void EndSerialize(TagStructureInfo info, byte[] data, uint mainStructOffset)
 {
     _resource.DefinitionFixups.Clear();
     _resource.D3DObjectFixups.Clear();
     _resource.DefinitionFixups.AddRange(_fixups);
     _resource.D3DObjectFixups.AddRange(_d3dFixups);
     _resource.DefinitionData = data;
     _resource.DefinitionAddress = new ResourceAddress(ResourceAddressType.Definition, (int)mainStructOffset);
 }
예제 #3
0
 public ListFieldsCommand(OpenTagCache info, TagStructureInfo structure, object value)
     : base(CommandFlags.Inherit,
           "listfields",
           $"Lists the fields in the current {structure.Types[0].Name} definition.",
           "listfields",
           $"Lists the fields in the current {structure.Types[0].Name} definition.")
 {
     Info = info;
     Structure = structure;
     Value = value;
 }
예제 #4
0
 public SetFieldCommand(CommandContextStack stack, OpenTagCache info, TagInstance tag, TagStructureInfo structure, object owner)
     : base(CommandFlags.Inherit,
           "setfield",
           $"Sets the value of a specific field in the current {structure.Types[0].Name} definition.",
           "setfield <field name> <field value>",
           $"Sets the value of a specific field in the current {structure.Types[0].Name} definition.")
 {
     Stack = stack;
     Info = info;
     Tag = tag;
     Structure = structure;
     Owner = owner;
 }
예제 #5
0
 public RemoveFromCommand(CommandContextStack stack, OpenTagCache info, TagInstance tag, TagStructureInfo structure, object owner)
     : base(CommandFlags.Inherit,
           "removefrom",
           $"Removes block element(s) from a specified index of a specific tag block in the current {structure.Types[0].Name} definition.",
           "removefrom <tag block name> [* | <tag block index> [* | amount = 1]]",
           $"Removes block element(s) from a specified index of a specific tag block in the current {structure.Types[0].Name} definition.")
 {
     Stack = stack;
     Info = info;
     Tag = tag;
     Structure = structure;
     Owner = owner;
 }
예제 #6
0
 public PasteElementsCommand(CommandContextStack stack, OpenTagCache info, TagInstance tag, TagStructureInfo structure, object owner)
     : base(CommandFlags.Inherit,
           "pasteelements",
           $"Pastes block element(s) to a specific tag block in the current {structure.Types[0].Name} definition.",
           "pasteelements <tag block name> [index = *]",
           $"Pastes block element(s) to a specific tag block in the current {structure.Types[0].Name} definition.")
 {
     Stack = stack;
     Info = info;
     Tag = tag;
     Structure = structure;
     Owner = owner;
 }
예제 #7
0
 public EditBlockCommand(CommandContextStack stack, OpenTagCache info, TagInstance tag, object value)
     : base(CommandFlags.Inherit,
           "edit",
           "Edit the fields of a particular block element.",
           "edit <block name> [block index (if block)]",
           "Edit the fields of a particular block element.")
 {
     Info = info;
     Stack = stack;
     Tag = tag;
     Structure = new TagStructureInfo(value.GetType(), Info.Version);
     Owner = value;
 }
 public void BeginSerialize(TagStructureInfo info)
 {
     _data = new TagData
     {
         Group = new TagGroup
         (
             tag: info.GroupTag,
             parentTag: info.ParentGroupTag,
             grandparentTag: info.GrandparentGroupTag,
             name: (info.Structure.Name != null) ? _stringIds.GetStringID(info.Structure.Name) : StringID.Null
         ),
     };
 }
예제 #9
0
        /// <summary>
        /// Serializes a tag structure into a context.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStructure">The tag structure.</param>
        public void Serialize(ISerializationContext context, object tagStructure, uint? offset = null)
        {
            // Serialize the structure to a data block
            var info = new TagStructureInfo(tagStructure.GetType(), _version);
            context.BeginSerialize(info);
            var tagStream = new MemoryStream();
            var structBlock = context.CreateBlock();
            SerializeStruct(context, tagStream, structBlock, info, tagStructure);

            // Finalize the block and write all of the tag data out
            var mainStructOffset = offset.HasValue ? offset.Value : structBlock.Finalize(tagStream);
            var data = tagStream.ToArray();
            context.EndSerialize(info, data, mainStructOffset);
        }
        public BinaryReader BeginDeserialize(TagStructureInfo info)
        {
            if (_resource.DefinitionAddress.Value == 0 || _resource.DefinitionAddress.Type != ResourceAddressType.Definition)
                throw new InvalidOperationException("Invalid resource definition address");

            // Create a stream with a copy of the resource definition data
            var stream = new MemoryStream(_resource.DefinitionData.Length);
            stream.Write(_resource.DefinitionData, 0, _resource.DefinitionData.Length);

            // Apply fixups
            var writer = new BinaryWriter(stream);
            foreach (var fixup in _resource.DefinitionFixups)
            {
                stream.Position = fixup.DefinitionDataOffset;
                writer.Write(fixup.Address.Value);
            }
            stream.Position = _resource.DefinitionAddress.Offset;
            return new BinaryReader(stream);
        }
예제 #11
0
 public void EndDeserialize(TagStructureInfo info, object obj)
 {
 }
예제 #12
0
 public void BeginSerialize(TagStructureInfo info)
 {
 }
예제 #13
0
 public EndianReader BeginDeserialize(TagStructureInfo info)
 {
     return(GetReader(InitialAddressType));
 }
예제 #14
0
        /// <summary>
        /// Deserializes a structure.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="info">Information about the structure to deserialize.</param>
        /// <returns>The deserialized structure.</returns>
        /// <exception cref="System.InvalidOperationException">Target type must have TagStructureAttribute</exception>
        public object DeserializeStruct(EndianReader reader, ISerializationContext context, TagStructureInfo info)
        {
            var baseOffset = reader.BaseStream.Position;
            var instance   = (TagStructure)Activator.CreateInstance(info.Types[0]);

            foreach (var tagFieldInfo in instance.GetTagFieldEnumerable(info.Version))
            {
                DeserializeProperty(reader, context, instance, tagFieldInfo, baseOffset);
            }

            if (info.TotalSize > 0)
            {
                reader.BaseStream.Position = baseOffset + info.TotalSize;
            }

            return(instance);
        }
예제 #15
0
 public void BeginSerialize(TagStructureInfo info)
 {
     _fixups.Clear();
     _d3dFixups.Clear();
 }
예제 #16
0
 /// <summary>
 /// Constructs an enumerator over a tag structure.
 /// </summary>
 /// <param name="info">The info for the structure. Only fields which match the version used to create the info will be enumerated over.</param>
 public TagFieldEnumerator(TagStructureInfo info)
 {
     Info = info;
     Begin();
 }
예제 #17
0
 public EndianReader BeginDeserialize(TagStructureInfo info)
 {
     return(Reader);
 }
 public BinaryReader BeginDeserialize(TagStructureInfo info)
 {
     var reader = _tag.Cache.Reader;
     reader.SeekTo(_tag.Offset);
     return reader;
 }
 public void BeginSerialize(TagStructureInfo info)
 {
     throw new NotImplementedException();
 }
예제 #20
0
        /// <summary>
        /// Serializes a structure into a temporary memory block.
        /// </summary>
        /// <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="info">Information about the tag structure type.</param>
        /// <param name="structure">The structure to serialize.</param>
        /// <exception cref="System.InvalidOperationException">Structure type must have TagStructureAttribute</exception>
        private void SerializeStruct(ISerializationContext context, MemoryStream tagStream, IDataBlock block, TagStructureInfo info, object structure)
        {
            var baseOffset = block.Stream.Position;
            var enumerator = new TagFieldEnumerator(info);
            while (enumerator.Next())
                SerializeProperty(context, tagStream, block, structure, enumerator, baseOffset);

            // Honor the struct size if it's defined
            if (info.TotalSize > 0)
            {
                block.Stream.Position = baseOffset + info.TotalSize;
                if (block.Stream.Position > block.Stream.Length)
                    block.Stream.SetLength(block.Stream.Position);
            }

            // Honor alignment
            if (info.Structure.Align > 0)
                block.SuggestAlignment(info.Structure.Align);
        }
 public void EndDeserialize(TagStructureInfo info, object obj)
 {
 }
 public void BeginSerialize(TagStructureInfo info)
 {
     ResourceFixups.Clear();
     ResourceDefinitionFixups.Clear();
 }
예제 #23
0
 public void EndSerialize(TagStructureInfo info, byte[] data, uint mainStructOffset)
 {
     Writer.Write(data);
 }
예제 #24
0
 /// <summary>
 /// Constructs an enumerator over a tag structure.
 /// </summary>
 /// <param name="info">The info for the structure. Only fields which match the version used to create the info will be enumerated over.</param>
 public TagFieldEnumerator(TagStructureInfo info)
 {
     Info = info;
     Begin();
 }
 public void BeginSerialize(TagStructureInfo info)
 {
     _fixups.Clear();
     _d3dFixups.Clear();
 }
예제 #26
0
        /// <summary>
        /// Serializes a structure into a temporary memory block.
        /// </summary>
        /// <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="info">Information about the tag structure type.</param>
        /// <param name="structure">The structure to serialize.</param>
        /// <exception cref="System.InvalidOperationException">Structure type must have TagStructureAttribute</exception>
        private void SerializeStruct(ISerializationContext context, MemoryStream tagStream, IDataBlock block, TagStructureInfo info, object structure)
        {
            var baseOffset = block.Stream.Position;

            foreach (var tagFieldInfo in TagStructure.GetTagFieldEnumerable(info))
            {
                SerializeProperty(info.Version, context, tagStream, block, structure, tagFieldInfo, baseOffset);
            }

            // Honor the struct size if it's defined
            if (info.TotalSize > 0)
            {
                block.Stream.Position = baseOffset + info.TotalSize;
                if (block.Stream.Position > block.Stream.Length)
                {
                    block.Stream.SetLength(block.Stream.Position);
                }
            }

            // Honor alignment
            if (info.Structure.Align > 0)
            {
                block.SuggestAlignment(info.Structure.Align);
            }
        }
 public void EndSerialize(TagStructureInfo info, byte[] data, uint mainStructOffset)
 {
     throw new NotImplementedException();
 }
 public void EndSerialize(TagStructureInfo info, byte[] data, uint mainStructOffset)
 {
     _data.MainStructOffset = mainStructOffset;
     _data.Data = data;
     _cache.SetTagData(_stream, Tag, _data);
     _data = null;
 }
 public void EndSerialize(TagStructureInfo info, byte[] data, uint mainStructOffset)
 {
     throw new NotImplementedException();
 }
예제 #30
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;
        }
 public EndianReader BeginDeserialize(TagStructureInfo info)
 {
     BlamCache.Reader.BaseStream.Position = BlamTag.Offset;
     return(BlamCache.Reader);
 }
 public void BeginSerialize(TagStructureInfo info)
 {
     throw new NotImplementedException();
 }
예제 #33
0
        public static CommandContext Create(CommandContextStack stack, OpenTagCache info, TagInstance tag)
        {
            var groupName = info.StringIDs.GetString(tag.Group.Name);

            var tagName = $"0x{tag.Index:X4}";

            if (info.TagNames.ContainsKey(tag.Index))
            {
                tagName = info.TagNames[tag.Index];
                tagName = $"(0x{tag.Index:X4}) {tagName.Substring(tagName.LastIndexOf('\\') + 1)}";
            }

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

            object value = null;

            using (var stream = info.OpenCacheRead())
                value = info.Deserializer.Deserialize(
                    new TagSerializationContext(stream, info.Cache, info.StringIDs, tag),
                    TagStructureTypes.FindByGroupTag(tag.Group.Tag));

            switch (tag.Group.Tag.ToString())
            {
                case "vfsl": // vfiles_list
                    VFilesContextFactory.Populate(context, info, tag, (VFilesList)value);
                    break;

                case "unic": // multilingual_unicode_string_list
                    UnicodeContextFactory.Populate(context, info, tag, (MultilingualUnicodeStringList)value);
                    break;

                case "bitm": // bitmap
                    BitmapContextFactory.Populate(context, info, tag, (Bitmap)value);
                    break;

                case "hlmt": // model
                    ModelContextFactory.Populate(context, info, tag, (Model)value);
                    break;

                case "mode": // render_model
                    RenderModelContextFactory.Populate(context, info, tag, (RenderModel)value);
                    break;

                case "jmad":
                    AnimationContextFactory.Populate(context, info, tag, (ModelAnimationGraph)value);
                    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(context, info, tag, (RenderMethod)value);
                    break;

                case "scnr":
                    ScnrContextFactory.Populate(context, info, tag, (Scenario)value);
                    break;

                case "sbsp":
                    BSPContextFactory.Populate(context, info, tag, (ScenarioStructureBsp)value);
                    break;
            }

            var structure = new TagStructureInfo(
                TagStructureTypes.FindByGroupTag(tag.Group.Tag));

            context.AddCommand(new ListFieldsCommand(info, structure, value));
            context.AddCommand(new SetFieldCommand(stack, info, tag, structure, value));
            context.AddCommand(new EditBlockCommand(stack, info, tag, value));
            context.AddCommand(new AddToCommand(stack, info, tag, structure, value));
            context.AddCommand(new RemoveFromCommand(stack, info, tag, structure, value));
            context.AddCommand(new CopyElementsCommand(stack, info, tag, structure, value));
            context.AddCommand(new PasteElementsCommand(stack, info, tag, structure, value));
            context.AddCommand(new SaveChangesCommand(info, tag, value));
            context.AddCommand(new ExitToCommand(stack));

            return context;
        }