Пример #1
0
        public DatumIndex InjectTag(ExtractedTag tag, IStream stream)
        {
            if (tag == null)
            {
                throw new ArgumentNullException("tag is null");
            }

            // Don't inject the tag if it's already been injected
            DatumIndex newIndex;

            if (_tagIndices.TryGetValue(tag, out newIndex))
            {
                return(newIndex);
            }

            // Make sure there isn't already a tag with the given name
            ITag existingTag = _cacheFile.Tags.FindTagByName(tag.Name, tag.Class, _cacheFile.FileNames);

            if (existingTag != null)
            {
                return(existingTag.Index);
            }

            // Look up the tag's datablock to get its size and allocate a tag for it
            DataBlock tagData = _container.FindDataBlock(tag.OriginalAddress);

            if (_resources == null && BlockNeedsResources(tagData))
            {
                // If the tag relies on resources and that info isn't available, throw it out
                LoadResourceTable(stream);
                if (_resources == null)
                {
                    return(DatumIndex.Null);
                }
            }

            ITag newTag = _cacheFile.Tags.AddTag(tag.Class, tagData.Data.Length, stream);

            _tagIndices[tag] = newTag.Index;
            _cacheFile.FileNames.SetTagName(newTag, tag.Name);

            // Write the data
            WriteDataBlock(tagData, newTag.MetaLocation, stream);

            // Make the tag load
            LoadZoneSets(stream);
            if (_zoneSets != null && _zoneSets.GlobalZoneSet != null)
            {
                _zoneSets.GlobalZoneSet.ActivateTag(newTag, true);
            }

            return(newTag.Index);
        }
Пример #2
0
		public DatumIndex InjectTag(ExtractedTag tag, IStream stream)
		{
			if (tag == null)
				throw new ArgumentNullException("tag is null");

			// Don't inject the tag if it's already been injected
			DatumIndex newIndex;
			if (_tagIndices.TryGetValue(tag, out newIndex))
				return newIndex;

			// Make sure there isn't already a tag with the given name
			ITag existingTag = _cacheFile.Tags.FindTagByName(tag.Name, tag.Class, _cacheFile.FileNames);
			if (existingTag != null)
				return existingTag.Index;

			// If the tag has made it this far but is a sound, make everyone (especially gerit) shut up.
			if (tag.Class == SoundClass)
				return DatumIndex.Null;

			// Look up the tag's datablock to get its size and allocate a tag for it
			DataBlock tagData = _container.FindDataBlock(tag.OriginalAddress);
			if (_resources == null && BlockNeedsResources(tagData))
			{
				// If the tag relies on resources and that info isn't available, throw it out
				LoadResourceTable(stream);
				if (_resources == null)
					return DatumIndex.Null;
			}

			ITag newTag = _cacheFile.Tags.AddTag(tag.Class, tagData.Data.Length, stream);
			_tagIndices[tag] = newTag.Index;
			_cacheFile.FileNames.SetTagName(newTag, tag.Name);

			// Write the data
			WriteDataBlock(tagData, newTag.MetaLocation, stream, newTag);

			// Make the tag load
			LoadZoneSets(stream);
			if (_zoneSets != null && _zoneSets.GlobalZoneSet != null)
				_zoneSets.GlobalZoneSet.ActivateTag(newTag, true);

			// If its class matches one of the valid simulation class names, add it to the simulation definition table
			if (_cacheFile.SimulationDefinitions != null && _simulationClasses.Contains(CharConstant.ToString(newTag.Class.Magic)))
				_cacheFile.SimulationDefinitions.Add(newTag);

			return newTag.Index;
		}
Пример #3
0
        public DatumIndex InjectTag(ExtractedTag tag, IStream stream)
        {
            string tagnameuniqifier = "";

            if (tag == null)
            {
                throw new ArgumentNullException("tag is null");
            }

            // Don't inject the tag if it's already been injected
            DatumIndex newIndex;

            if (_tagIndices.TryGetValue(tag, out newIndex))
            {
                return(newIndex);
            }

            // Make sure there isn't already a tag with the given name
            ITag existingTag = _cacheFile.Tags.FindTagByName(tag.Name, tag.Group, _cacheFile.FileNames);

            if (existingTag != null)
            {
                //check if we are doing shader tweaks
                if (_renameShaders && _shaderGroups.Contains(CharConstant.ToString(tag.Group)))
                {
                    //append old tagid to make it unique
                    tagnameuniqifier = "_" + tag.OriginalIndex.ToString();

                    //make sure the tag didnt come from this exact map
                    if (existingTag.Index == tag.OriginalIndex)
                    {
                        return(existingTag.Index);
                    }

                    //make sure the appended name isn't already present
                    existingTag = _cacheFile.Tags.FindTagByName(tag.Name + tagnameuniqifier, tag.Group, _cacheFile.FileNames);

                    if (existingTag != null)
                    {
                        return(existingTag.Index);
                    }
                }
                else
                {
                    return(existingTag.Index);
                }
            }

            if (!_keepSound && tag.Group == SoundGroup)
            {
                return(DatumIndex.Null);
            }

            //PCA resource type is not always present, so get rid of 'em for now
            if (tag.Group == PCAGroup)
            {
                return(DatumIndex.Null);
            }

            // Look up the tag's datablock to get its size and allocate a tag for it
            DataBlock tagData = _container.FindDataBlock(tag.OriginalAddress);

            if (_resources == null && BlockNeedsResources(tagData))
            {
                // If the tag relies on resources and that info isn't available, throw it out
                LoadResourceTable(stream);
                if (_resources == null)
                {
                    return(DatumIndex.Null);
                }
            }
            if (_soundResources == null && BlockNeedsSounds(tagData))
            {
                // If the tag relies on sound resources and that info isn't available, throw it out
                LoadSoundResourceTable(stream);
                if (_soundResources == null)
                {
                    return(DatumIndex.Null);
                }
            }

            ITag newTag = _cacheFile.Tags.AddTag(tag.Group, tagData.Data.Length, stream);

            _tagIndices[tag] = newTag.Index;
            _cacheFile.FileNames.SetTagName(newTag, tag.Name + tagnameuniqifier);

            // Write the data
            WriteDataBlock(tagData, newTag.MetaLocation, stream, newTag);

            // Make the tag load
            LoadZoneSets(stream);
            if (_zoneSets != null)
            {
                _zoneSets.ExpandAllTags(newTag.Index.Index);
                if (_zoneSets.GlobalZoneSet != null)
                {
                    _zoneSets.GlobalZoneSet.ActivateTag(newTag, true);
                }
            }

            // If its group matches one of the valid simulation group names, add it to the simulation definition table
            if (_cacheFile.SimulationDefinitions != null && _simulationGroups.Contains(CharConstant.ToString(newTag.Group.Magic)))
            {
                _cacheFile.SimulationDefinitions.Add(newTag);
            }

            return(newTag.Index);
        }
Пример #4
0
 /// <summary>
 ///     Adds information about an extracted tag to the container.
 /// </summary>
 /// <param name="tag">The tag information to add.</param>
 public void AddTag(ExtractedTag tag)
 {
     _tagsByIndex[tag.OriginalIndex] = tag;
 }
Пример #5
0
        private void contextExtract_Click(object sender, RoutedEventArgs e)
        {
            // Get the menu item and the tag
            var item = e.Source as MenuItem;
            if (item == null)
                return;

            var tag = item.DataContext as TagEntry;
            if (tag == null)
                return;

            // Ask where to save the extracted tag collection
            var sfd = new SaveFileDialog
            {
                Title = "Save Tag Set",
                Filter = "Tag Container Files|*.tagc"
            };
            bool? result = sfd.ShowDialog();
            if (!result.Value)
                return;

            // Make a tag container
            var container = new TagContainer();

            // Recursively extract tags
            var tagsToProcess = new Queue<ITag>();
            var tagsProcessed = new HashSet<ITag>();
            var resourcesToProcess = new Queue<DatumIndex>();
            var resourcesProcessed = new HashSet<DatumIndex>();
            var resourcePagesProcessed = new HashSet<ResourcePage>();
            tagsToProcess.Enqueue(tag.RawTag);

            ResourceTable resources = null;
            using (IReader reader = _mapManager.OpenRead())
            {
                while (tagsToProcess.Count > 0)
                {
                    ITag currentTag = tagsToProcess.Dequeue();
                    if (tagsProcessed.Contains(currentTag))
                        continue;

                    // Get the plugin path
                    string className = VariousFunctions.SterilizeTagClassName(CharConstant.ToString(currentTag.Class.Magic)).Trim();
                    string pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins",
                        _buildInfo.Settings.GetSetting<string>("plugins"), className);

                    // Extract dem data blocks
                    var blockBuilder = new DataBlockBuilder(reader, currentTag.MetaLocation, _cacheFile, _buildInfo);
                    using (XmlReader pluginReader = XmlReader.Create(pluginPath))
                        AssemblyPluginLoader.LoadPlugin(pluginReader, blockBuilder);

                    foreach (DataBlock block in blockBuilder.DataBlocks)
                        container.AddDataBlock(block);

                    // Add data for the tag that was extracted
                    string tagName = _cacheFile.FileNames.GetTagName(currentTag) ?? currentTag.Index.ToString();
                    var extractedTag = new ExtractedTag(currentTag.Index, currentTag.MetaLocation.AsPointer(), currentTag.Class.Magic,
                        tagName);
                    container.AddTag(extractedTag);

                    // Mark the tag as processed and then enqueue all of its child tags and resources
                    tagsProcessed.Add(currentTag);
                    foreach (DatumIndex tagRef in blockBuilder.ReferencedTags)
                        tagsToProcess.Enqueue(_cacheFile.Tags[tagRef]);
                    foreach (DatumIndex resource in blockBuilder.ReferencedResources)
                        resourcesToProcess.Enqueue(resource);
                }

                // Load the resource table in if necessary
                if (resourcesToProcess.Count > 0)
                    resources = _cacheFile.Resources.LoadResourceTable(reader);
            }

            // Extract resource info
            if (resources != null)
            {
                while (resourcesToProcess.Count > 0)
                {
                    DatumIndex index = resourcesToProcess.Dequeue();
                    if (resourcesProcessed.Contains(index))
                        continue;

                    // Add the resource
                    Resource resource = resources.Resources[index.Index];
                    container.AddResource(new ExtractedResourceInfo(resource));

                    // Add data for its pages
                    if (resource.Location == null)
                        continue;
                    if (resource.Location.PrimaryPage != null && !resourcePagesProcessed.Contains(resource.Location.PrimaryPage))
                    {
                        container.AddResourcePage(resource.Location.PrimaryPage);
                        resourcePagesProcessed.Add(resource.Location.PrimaryPage);
                    }
                    if (resource.Location.SecondaryPage == null || resourcePagesProcessed.Contains(resource.Location.SecondaryPage))
                        continue;
                    container.AddResourcePage(resource.Location.SecondaryPage);
                    resourcePagesProcessed.Add(resource.Location.SecondaryPage);
                }
            }

            // Write it to a file
            using (var writer = new EndianWriter(File.Open(sfd.FileName, FileMode.Create, FileAccess.Write), Endian.BigEndian))
                TagContainerWriter.WriteTagContainer(container, writer);

            // YAY!
            MetroMessageBox.Show("Extraction Successful",
                "Extracted " + container.Tags.Count + " tag(s), " + container.DataBlocks.Count + " data block(s), " +
                container.ResourcePages.Count + " resource page pointer(s), and " + container.Resources.Count +
                " resource pointer(s).");
        }
Пример #6
0
        private void extractTags(bool withRaw, TagEntry tag)
        {
            // Ask where to save the extracted tag collection
            var sfd = new SaveFileDialog
            {
                Title = "Save Tag Set",
                Filter = "Tag Container Files|*.tagc"
            };
            bool? result = sfd.ShowDialog();
            if (!result.Value)
                return;

            // Make a tag container
            var container = new TagContainer();

            // Recursively extract tags
            var tagsToProcess = new Queue<ITag>();
            var tagsProcessed = new HashSet<ITag>();
            var resourcesToProcess = new Queue<DatumIndex>();
            var resourcesProcessed = new HashSet<DatumIndex>();
            var resourcePagesProcessed = new HashSet<ResourcePage>();
            tagsToProcess.Enqueue(tag.RawTag);

            ResourceTable resources = null;
            using (var reader = _mapManager.OpenRead())
            {
                while (tagsToProcess.Count > 0)
                {
                    var currentTag = tagsToProcess.Dequeue();
                    if (tagsProcessed.Contains(currentTag))
                        continue;

                    // Get the plugin path
                    var className = VariousFunctions.SterilizeTagClassName(CharConstant.ToString(currentTag.Class.Magic)).Trim();
                    var pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins",
                        _buildInfo.Settings.GetSetting<string>("plugins"), className);

                    // Extract dem data blocks
                    var blockBuilder = new DataBlockBuilder(reader, currentTag, _cacheFile, _buildInfo);
                    using (var pluginReader = XmlReader.Create(pluginPath))
                        AssemblyPluginLoader.LoadPlugin(pluginReader, blockBuilder);

                    foreach (var block in blockBuilder.DataBlocks)
                        container.AddDataBlock(block);

                    // Add data for the tag that was extracted
                    var tagName = _cacheFile.FileNames.GetTagName(currentTag) ?? currentTag.Index.ToString();
                    var extractedTag = new ExtractedTag(currentTag.Index, currentTag.MetaLocation.AsPointer(), currentTag.Class.Magic,
                        tagName);
                    container.AddTag(extractedTag);

                    // Mark the tag as processed and then enqueue all of its child tags and resources
                    tagsProcessed.Add(currentTag);
                    foreach (var tagRef in blockBuilder.ReferencedTags)
                        tagsToProcess.Enqueue(_cacheFile.Tags[tagRef]);
                    foreach (var resource in blockBuilder.ReferencedResources)
                        resourcesToProcess.Enqueue(resource);
                }

                // Load the resource table in if necessary
                if (resourcesToProcess.Count > 0)
                    resources = _cacheFile.Resources.LoadResourceTable(reader);
            }

            // Extract resource info
            if (resources != null)
            {
                while (resourcesToProcess.Count > 0)
                {
                    var index = resourcesToProcess.Dequeue();
                    if (resourcesProcessed.Contains(index))
                        continue;

                    // Add the resource
                    var resource = resources.Resources[index.Index];
                    container.AddResource(new ExtractedResourceInfo(index, resource));

                    // Add data for its pages
                    if (resource.Location == null) continue;

                    if (resource.Location.PrimaryPage != null &&
                        !resourcePagesProcessed.Contains(resource.Location.PrimaryPage))
                    {
                        container.AddResourcePage(resource.Location.PrimaryPage);
                        resourcePagesProcessed.Add(resource.Location.PrimaryPage);

                        if (withRaw)
                        {
                            using (var fileStream = File.OpenRead(_cacheLocation))
                            {
                                var resourceFile = _cacheFile;
                                Stream resourceStream = fileStream;
                                if (resource.Location.PrimaryPage.FilePath != null)
                                {
                                    var resourceCacheInfo =
                                    App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault(
                                        r => r.EngineName == _buildInfo.Name);

                                    var resourceCachePath = (resourceCacheInfo != null)
                                        ? resourceCacheInfo.ResourceCachePath
                                        : Path.GetDirectoryName(_cacheLocation);

                                    resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(resource.Location.PrimaryPage.FilePath));

                                    if (!File.Exists(resourceCachePath))
                                    {
                                        MetroMessageBox.Show("Unable to extract tag",
                                            "Unable to extract tag, because a resource it relies on is in a external cache '{0}' that could not be found. Check Assembly's settings and set the file path to resource caches.");
                                        return;
                                    }

                                    resourceStream =
                                        File.OpenRead(resourceCachePath);
                                    resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, Endian.BigEndian), _buildInfo,
                                        _cacheFile.BuildString);
                                }

                                var extractor = new ResourcePageExtractor(resourceFile);
                                byte[] pageData;
                                using (var pageStream = new MemoryStream())
                                {
                                    extractor.ExtractPage(resource.Location.PrimaryPage, resourceStream, pageStream);
                                    pageData = new byte[pageStream.Length];
                                    Buffer.BlockCopy(pageStream.GetBuffer(), 0, pageData, 0, (int) pageStream.Length);
                                }
                                container.AddExtractedResourcePage(new ExtractedPage(pageData, resource.Location.PrimaryPage.Index));
                            }
                        }
                    }
                    if (resource.Location.SecondaryPage == null || resourcePagesProcessed.Contains(resource.Location.SecondaryPage))
                        continue;

                    container.AddResourcePage(resource.Location.SecondaryPage);
                    resourcePagesProcessed.Add(resource.Location.SecondaryPage);

                    if (withRaw)
                    {
                        using (var fileStream = File.OpenRead(_cacheLocation))
                        {
                            var resourceFile = _cacheFile;
                            Stream resourceStream = fileStream;
                            if (resource.Location.SecondaryPage.FilePath != null)
                            {
                                var resourceCacheInfo =
                                    App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault(
                                        r => r.EngineName == _buildInfo.Name);

                                var resourceCachePath = (resourceCacheInfo != null)
                                    ? resourceCacheInfo.ResourceCachePath
                                    : Path.GetDirectoryName(_cacheLocation);

                                resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(resource.Location.SecondaryPage.FilePath));

                                if (!File.Exists(resourceCachePath))
                                {
                                    MetroMessageBox.Show("Unable to extract tag",
                                        "Unable to extract tag, because a resource it relies on is in a external cache '{0}' that could not be found. Check Assembly's settings and set the file path to resource caches.");
                                    return;
                                }

                                resourceStream =
                                    File.OpenRead(resourceCachePath);
                                resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, Endian.BigEndian), _buildInfo,
                                    _cacheFile.BuildString);
                            }

                            var extractor = new ResourcePageExtractor(resourceFile);
                            byte[] pageData;
                            using (var pageStream = new MemoryStream())
                            {
                                extractor.ExtractPage(resource.Location.SecondaryPage, resourceStream, pageStream);
                                pageData = new byte[pageStream.Length];
                                Buffer.BlockCopy(pageStream.GetBuffer(), 0, pageData, 0, (int)pageStream.Length);
                            }
                            container.AddExtractedResourcePage(new ExtractedPage(pageData, resource.Location.SecondaryPage.Index));
                        }
                    }
                }
            }

            // Write it to a file
            using (var writer = new EndianWriter(File.Open(sfd.FileName, FileMode.Create, FileAccess.Write), Endian.BigEndian))
                TagContainerWriter.WriteTagContainer(container, writer);

            // YAY!
            MetroMessageBox.Show("Extraction Successful",
                "Extracted " +
                container.Tags.Count + " tag(s), " +
                container.DataBlocks.Count + " data block(s), " +
                container.ResourcePages.Count + " resource page pointer(s), " +
                container.ExtractedResourcePages.Count + " extracted resource page(s), and " +
                container.Resources.Count + " resource pointer(s).");
        }
Пример #7
0
        private void contextDuplicate_Click(object sender, RoutedEventArgs e)
        {
            // Get the menu item and the tag
            var item = e.Source as MenuItem;
            if (item == null)
                return;
            var tag = item.DataContext as TagEntry;
            if (tag == null)
                return;

            // TODO: Make this into a dialog with more options
            string newName;
            while (true)
            {
                newName = MetroInputBox.Show("Duplicate Tag", "Please enter a name for the new tag.", tag.TagFileName, "Enter a name.");
                if (newName == null)
                    return;
                if (newName != tag.TagFileName && _cacheFile.Tags.FindTagByName(newName, tag.RawTag.Class, _cacheFile.FileNames) == null)
                    break;
                MetroMessageBox.Show("Duplicate Tag", "Please enter a name that is different from the original and that is not in use.");
            }

            // Make a tag container for the tag and then inject it
            // TODO: A lot of this was copied and pasted from the tag extraction code...need to clean things up
            var container = new TagContainer();
            using (var stream = _mapManager.OpenReadWrite())
            {
                // Get the plugin path
                string className = VariousFunctions.SterilizeTagClassName(CharConstant.ToString(tag.RawTag.Class.Magic)).Trim();
                string pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins",
                    _buildInfo.Settings.GetSetting<string>("plugins"), className);

                // Extract data blocks
                var builder = new DataBlockBuilder(stream, tag.RawTag, _cacheFile, _buildInfo);
                using (XmlReader pluginReader = XmlReader.Create(pluginPath))
                    AssemblyPluginLoader.LoadPlugin(pluginReader, builder);
                foreach (var block in builder.DataBlocks)
                {
                    // Remove non-datablock fixups because those are still valid
                    // TODO: A better approach might be to just make DataBlockBuilder ignore these in the first place
                    block.StringIDFixups.Clear();
                    block.ShaderFixups.Clear();
                    block.ResourceFixups.Clear();
                    block.TagFixups.Clear();
                    container.AddDataBlock(block);
                }
                var extracted = new ExtractedTag(tag.RawTag.Index, tag.RawTag.MetaLocation.AsPointer(), tag.RawTag.Class.Magic, newName);
                container.AddTag(extracted);

                // Now inject the container
                var injector = new TagContainerInjector(_cacheFile, container);
                injector.InjectTag(extracted, stream);
                injector.SaveChanges(stream);
            }

            LoadTags();
            MetroMessageBox.Show("Duplicate Tag", "Tag duplicated successfully!");
        }
Пример #8
0
        public DatumIndex InjectTag(ExtractedTag tag, IStream stream)
        {
            if (tag == null)
                throw new ArgumentNullException("tag is null");

            // Don't inject the tag if it's already been injected
            DatumIndex newIndex;
            if (_tagIndices.TryGetValue(tag, out newIndex))
                return newIndex;

            // Make sure there isn't already a tag with the given name
            ITag existingTag = _cacheFile.Tags.FindTagByName(tag.Name, tag.Class, _cacheFile.FileNames);
            if (existingTag != null)
                return existingTag.Index;

            // Look up the tag's datablock to get its size and allocate a tag for it
            DataBlock tagData = _container.FindDataBlock(tag.OriginalAddress);
            ITag newTag = _cacheFile.Tags.AddTag(tag.Class, tagData.Data.Length, stream);
            _tagIndices[tag] = newTag.Index;
            _cacheFile.FileNames.SetTagName(newTag, tag.Name);

            // Write the data
            WriteDataBlock(tagData, newTag.MetaLocation, stream);

            // Make the tag load
            LoadZoneSets(stream);
            _zoneSets.GlobalZoneSet.ActivateTag(newTag, true);

            return newTag.Index;
        }
Пример #9
0
		/// <summary>
		///     Adds information about an extracted tag to the container.
		/// </summary>
		/// <param name="tag">The tag information to add.</param>
		public void AddTag(ExtractedTag tag)
		{
			_tagsByIndex[tag.OriginalIndex] = tag;
		}
Пример #10
0
        public DatumIndex InjectTag(ExtractedTag tag, IStream stream)
        {
            if (tag == null)
            {
                throw new ArgumentNullException("tag is null");
            }

            // Don't inject the tag if it's already been injected
            DatumIndex newIndex;

            if (_tagIndices.TryGetValue(tag, out newIndex))
            {
                return(newIndex);
            }

            // Make sure there isn't already a tag with the given name
            ITag existingTag = _cacheFile.Tags.FindTagByName(tag.Name, tag.Class, _cacheFile.FileNames);

            if (existingTag != null)
            {
                return(existingTag.Index);
            }

            // If the tag has made it this far but is a sound, make everyone (especially gerit) shut up.
            if (tag.Class == SoundClass)
            {
                return(DatumIndex.Null);
            }

            // Look up the tag's datablock to get its size and allocate a tag for it
            DataBlock tagData = _container.FindDataBlock(tag.OriginalAddress);

            if (_resources == null && BlockNeedsResources(tagData))
            {
                // If the tag relies on resources and that info isn't available, throw it out
                LoadResourceTable(stream);
                if (_resources == null)
                {
                    return(DatumIndex.Null);
                }
            }

            ITag newTag = _cacheFile.Tags.AddTag(tag.Class, tagData.Data.Length, stream);

            _tagIndices[tag] = newTag.Index;
            _cacheFile.FileNames.SetTagName(newTag, tag.Name);

            // Write the data
            WriteDataBlock(tagData, newTag.MetaLocation, stream, newTag);

            // Make the tag load
            LoadZoneSets(stream);
            if (_zoneSets != null && _zoneSets.GlobalZoneSet != null)
            {
                _zoneSets.GlobalZoneSet.ActivateTag(newTag, true);
            }

            // If its class matches one of the valid simulation class names, add it to the simulation definition table
            if (_cacheFile.SimulationDefinitions != null && _simulationClasses.Contains(CharConstant.ToString(newTag.Class.Magic)))
            {
                _cacheFile.SimulationDefinitions.Add(newTag);
            }

            return(newTag.Index);
        }