public void ReadReflexive(ReflexiveData reflexive) { if (!reflexive.HasChildren || reflexive.CurrentIndex < 0) return; bool opened = OpenReader(); try { uint oldBaseOffset = _baseOffset; _baseOffset = (uint)(reflexive.FirstEntryOffset + reflexive.CurrentIndex * reflexive.EntrySize); ReflexivePage page = reflexive.Pages[reflexive.CurrentIndex]; for (int i = 0; i < page.Fields.Length; i++) { if (page.Fields[i] != null) ReadField(page.Fields[i]); else ReadField(reflexive.Template[i]); } _baseOffset = oldBaseOffset; } finally { if (opened) CloseReader(); } }
public void ReadReflexiveChildren(ReflexiveData reflexive) { if (!reflexive.HasChildren || reflexive.CurrentIndex < 0) return; bool opened = OpenReader(); try { // Calculate the base offset to read from uint oldBaseOffset = BaseOffset; int dataOffset = _cache.MetaArea.PointerToOffset(reflexive.FirstEntryAddress); BaseOffset = (uint)(dataOffset + reflexive.CurrentIndex * reflexive.EntrySize); ReflexivePage page = reflexive.Pages[reflexive.CurrentIndex]; for (int i = 0; i < page.Fields.Length; i++) { if (page.Fields[i] != null) ReadField(page.Fields[i]); else ReadField(reflexive.Template[i]); } BaseOffset = oldBaseOffset; } finally { if (opened) CloseReader(); } }
public WrappedReflexiveEntry GetTopLevelWrapper(ReflexiveData reflexive, WrappedReflexiveEntry wrapper) { FlattenedReflexive flattened; if (_flattenInfo.TryGetValue(reflexive, out flattened)) return flattened.GetTopLevelWrapper(wrapper); return null; }
public void ReadReflexiveChildren(ReflexiveData reflexive) { if (!reflexive.HasChildren || reflexive.CurrentIndex < 0) return; var opened = OpenReader(); if (_reader == null) return; try { // Calculate the base offset to read from var oldBaseOffset = BaseOffset; var dataOffset = reflexive.FirstEntryAddress; if (_type == LoadType.File) dataOffset = (uint)_cache.MetaArea.PointerToOffset(dataOffset); BaseOffset = (uint)(dataOffset + reflexive.CurrentIndex * reflexive.EntrySize); var page = reflexive.Pages[reflexive.CurrentIndex]; for (var i = 0; i < page.Fields.Length; i++) { ReadField(page.Fields[i] ?? reflexive.Template[i]); } BaseOffset = oldBaseOffset; } finally { if (opened) CloseReader(); } }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length < 0 || (_cache.Engine != EngineType.FourthGeneration && !_cache.MetaArea.ContainsBlockPointer(pointer, (int)(length * field.EntrySize))) || (_cache.Engine == EngineType.FourthGeneration && (pointer < 0x40000000 || pointer > 0x50000000))) { if (length != 0 && pointer != 0) { //field.Opacity = 0.5f; MetroMessageBox.Show("Bad Block!", "Block \"" + field.Name + "\", plugin line " + field.PluginLine + " appears to be invalid. The block has been ignored to prevent crashing."); } length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); if (_cache.Engine == EngineType.ThirdGenMCC) { pointer = NewPointerConverter.ConvertToPointer(pointer); } // Make sure the pointer looks valid if (length < 0 || !_cache.MetaArea.ContainsTagBlockPointer(pointer, (int)(length * field.EntrySize))) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public TagBlockReallocator(ReflexiveData block) { _block = block; _originalCount = block.Length; InitializeComponent(); DwmDropShadow.DropShadowToWindow(this); InitBlockInformation(); }
/// <summary> /// Forcibly expands a reflexive and all of its ancestors. /// </summary> /// <param name="reflexive">The reflexive to make visible.</param> public void ForceVisible(ReflexiveData reflexive) { FlattenedReflexive flattened; if (!_flattenInfo.TryGetValue(reflexive, out flattened)) return; while (flattened != null && flattened.Expand()) flattened = flattened.Parent; }
public void EnumWrappers(ReflexiveData reflexive, Action<WrappedReflexiveEntry> wrapperProcessor) { FlattenedReflexive flattened; if (!_flattenInfo.TryGetValue(reflexive, out flattened)) return; foreach (WrappedReflexiveEntry wrapper in flattened.Wrappers) wrapperProcessor(wrapper); }
public void VisitReflexive(ReflexiveData field) { var values = new StructureValueCollection(); values.SetInteger("entry count", (uint)field.Length); values.SetInteger("pointer", field.FirstEntryAddress); SeekToOffset(field.Offset); StructureWriter.WriteStructure(values, _reflexiveLayout, _writer); }
public WrappedReflexiveEntry GetTopLevelWrapper(ReflexiveData reflexive, WrappedReflexiveEntry wrapper) { FlattenedReflexive flattened; if (_flattenInfo.TryGetValue(reflexive, out flattened)) { return(flattened.GetTopLevelWrapper(wrapper)); } return(null); }
public static int? Show(ICacheFile cache, ReflexiveData data) { App.AssemblyStorage.AssemblySettings.HomeWindow.ShowMask(); var dialog = new TagBlockReallocator(data) { Owner = App.AssemblyStorage.AssemblySettings.HomeWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; dialog.ShowDialog(); App.AssemblyStorage.AssemblySettings.HomeWindow.HideMask(); return dialog.NewCount; }
public void VisitReflexive(ReflexiveData field) { var values = new StructureValueCollection(); values.SetInteger("entry count", _cache.MetaArea.ContainsBlockPointer(field.FirstEntryAddress, (int)(field.Length * field.EntrySize)) ? (uint)field.Length : 0); uint cont = _cache.PointerExpander.Contract(field.FirstEntryAddress); values.SetInteger("pointer", cont); SeekToOffset(field.Offset); StructureWriter.WriteStructure(values, _reflexiveLayout, _writer); }
public FlattenedReflexive(FlattenedReflexive parent, ReflexiveData template, ObservableCollection<MetaField> topLevelFields, FieldChangeTracker tracker, FieldChangeSet changes) { _parent = parent; _template = template; _activeReflexive = template; _synchronizedReflexives.Add(template); if (template.HasChildren) _lastPage = template.Pages[template.CurrentIndex]; _topLevelFields = topLevelFields; _tracker = tracker; _changes = changes; }
public void EnumWrappers(ReflexiveData reflexive, Action <WrappedReflexiveEntry> wrapperProcessor) { FlattenedReflexive flattened; if (!_flattenInfo.TryGetValue(reflexive, out flattened)) { return; } foreach (WrappedReflexiveEntry wrapper in flattened.Wrappers) { wrapperProcessor(wrapper); } }
/// <summary> /// Forcibly expands a reflexive and all of its ancestors. /// </summary> /// <param name="reflexive">The reflexive to make visible.</param> public void ForceVisible(ReflexiveData reflexive) { FlattenedReflexive flattened; if (!_flattenInfo.TryGetValue(reflexive, out flattened)) { return; } while (flattened != null && flattened.Expand()) { flattened = flattened.Parent; } }
public FlattenedReflexive(FlattenedReflexive parent, ReflexiveData template, ObservableCollection <MetaField> topLevelFields, FieldChangeTracker tracker, FieldChangeSet changes) { _parent = parent; _template = template; _activeReflexive = template; _synchronizedReflexives.Add(template); if (template.HasChildren) { _lastPage = template.Pages[template.CurrentIndex]; } _topLevelFields = topLevelFields; _tracker = tracker; _changes = changes; }
public void ReadReflexiveChildren(ReflexiveData reflexive) { if (!reflexive.HasChildren || reflexive.CurrentIndex < 0) { return; } bool opened = OpenReader(); if (_reader == null) { return; } try { // Calculate the base offset to read from uint oldBaseOffset = BaseOffset; uint dataOffset = reflexive.FirstEntryAddress; if (_cache.GetType() == typeof(Blamite.Blam.FourthGen.FourthGenCacheFile)) { dataOffset = HeaderOffset + (dataOffset & 0xFFFFFFF); } if (_type == LoadType.File) { dataOffset = (uint)_cache.MetaArea.PointerToOffset(dataOffset); } BaseOffset = (uint)(dataOffset + reflexive.CurrentIndex * reflexive.EntrySize); ReflexivePage page = reflexive.Pages[reflexive.CurrentIndex]; for (int i = 0; i < page.Fields.Length; i++) { ReadField(page.Fields[i] ?? reflexive.Template[i]); } BaseOffset = oldBaseOffset; } finally { if (opened) { CloseReader(); } } }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length < 0) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _reflexiveLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length <= 0 || !_cache.MetaArea.ContainsBlockPointer(pointer, (int)(length * field.EntrySize))) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public void VisitReflexive(ReflexiveData field) { // Don't enter empty reflexives ReflexiveData oldReflexive = _currentReflexive; _currentReflexive = field; if (FilterString(field, field.Name) && field.Length > 0) { // Forcibly highlight everything inside it _highlightLevel++; _flattener.EnumWrappers(field, ReflexiveFlattener_HandleWrapper); _highlightLevel--; } else if (field.Length > 0) { _flattener.EnumWrappers(field, ReflexiveFlattener_HandleWrapper); } _currentReflexive = oldReflexive; }
public void VisitReflexive(ReflexiveData field) { // Create flatten information for the reflexive and attach event handlers to it var flattened = new FlattenedReflexive(_flatParent, field, _topLevelFields, _tracker, _changes); AttachTo(field, flattened); FlattenedReflexive oldParent = _flatParent; _flatParent = flattened; Flatten(field.Template); field.UpdateWidth(); _flatParent = oldParent; for (int i = 0; i < field.Template.Count; i++) { WrappedReflexiveEntry wrapper = flattened.WrapField(field.Template[i], field.Width, i == field.Template.Count - 1); _index++; _fields.Insert(_index, wrapper); } }
public void LoadPage(ReflexiveData reflexive, int index) { _activeReflexive = reflexive; if (!reflexive.HasChildren) { return; } if (index >= 0 && index < reflexive.Length && reflexive.Pages[index] == _lastPage) { return; } UnloadPage(); if (index < 0 || index >= reflexive.Length) { _lastPage = null; return; } _lastPage = reflexive.Pages[index]; for (int i = 0; i < _lastPage.Fields.Length; i++) { // if _lastPage.Fields[i] is null, then we can just re-use the field from the template MetaField newField; if (_lastPage.Fields[i] != null) { newField = _lastPage.Fields[i]; } else { newField = reflexive.Template[i]; } // HACK: synchronize the opacity newField.Opacity = _loadedFields[i].Opacity; _loadedFields[i] = newField; } }
public override MetaField CloneValue() { var result = new ReflexiveData(Name, Offset, FieldAddress, EntrySize, Align, Sort, base.PluginLine, _metaArea); result._expanded = _expanded; result._width = _width; result._currentIndex = _currentIndex; result._firstEntryAddr = _firstEntryAddr; foreach (MetaField field in _template) { result._template.Add(field); } foreach (ReflexivePage page in _pages) { result._pages.Add(page.CloneValue()); } if (Cloned != null) { Cloned(this, new ReflexiveClonedEventArgs(this, result)); } return(result); }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = (uint)values.GetInteger("pointer"); long expanded = _cache.PointerExpander.Expand(pointer); // Make sure the pointer looks valid if (length < 0 || !_cache.MetaArea.ContainsBlockPointer(expanded, (int)(length * field.EntrySize))) { length = 0; pointer = 0; expanded = 0; } if (expanded != field.FirstEntryAddress) { field.FirstEntryAddress = expanded; } field.Length = length; }
public void VisitReflexive(ReflexiveData field) { var values = new StructureValueCollection(); values.SetInteger("entry count", (uint)field.Length); values.SetInteger("pointer", field.FirstEntryAddress); SeekToOffset(field.Offset); StructureWriter.WriteStructure(values, _reflexiveLayout, _writer); }
/// <summary> /// Synchronizes the expansion state of a reflexive with the expansion state of this FlattenedReflexive. /// </summary> /// <param name="other">The ReflexiveData to synchronize the expansion state of.</param> public void SynchronizeWith(ReflexiveData other) { _synchronizedReflexives.Add(other); }
private void AttachTo(ReflexiveData field, FlattenedReflexive flattened) { field.PropertyChanged += ReflexivePropertyChanged; field.Cloned += ReflexiveCloned; _flattenInfo[field] = flattened; }
/// <summary> /// Synchronizes the expansion state of a reflexive with the expansion state of this FlattenedReflexive. /// </summary> /// <param name="other">The ReflexiveData to synchronize the expansion state of.</param> public void SynchronizeWith(ReflexiveData other) { _synchronizedReflexives.Add(other); }
public void VisitReflexive(ReflexiveData field) { // TODO: Write length and address if (field.CurrentIndex < 0 || !field.HasChildren) return; // Get the base offset and convert it to an address if we're writing to memory uint newBaseOffset = field.FirstEntryOffset; if (_type == SaveType.Memory) newBaseOffset = _cache.MetaPointerConverter.OffsetToAddress(newBaseOffset); // Save the old base offset and set the base offset to the reflexive's base uint oldBaseOffset = _baseOffset; _baseOffset = newBaseOffset; // Write each page int _oldIndex = field.CurrentIndex; bool _oldPokeTemplates = _pokeTemplateFields; for (int i = 0; i < field.Length; i++) { // If we're saving everything, then change the active page so the values get loaded from the file if (_changes == null && field.CurrentIndex != i) field.CurrentIndex = i; // If we're not saving everything, then we can only poke template fields in reflexives // if the current indices all line up if (i != _oldIndex) _pokeTemplateFields = false; // Get each field in the page and write it ReflexivePage page = field.Pages[i]; for (int j = 0; j < page.Fields.Length; j++) { MetaField pageField = page.Fields[j]; // The field in the page takes precedence over the field in the reflexive's template if (pageField == null && (_changes == null || _pokeTemplateFields)) pageField = field.Template[j]; // Get it from the template if (pageField != null) WriteField(pageField); } // Advance to the next chunk _baseOffset += field.EntrySize; _pokeTemplateFields = _oldPokeTemplates; } if (field.CurrentIndex != _oldIndex) field.CurrentIndex = _oldIndex; // Restore the old base offset _baseOffset = oldBaseOffset; }
private void MetaFilterer_CollectResult(MetaField foundField, MetaField listField, ReflexiveData parent) { _resultIndices[listField] = _searchResults.Count; _searchResults.Add(new SearchResult(foundField, listField, parent)); }
public void LoadPage(ReflexiveData reflexive, int index) { _activeReflexive = reflexive; if (!reflexive.HasChildren) return; UnloadPage(); if (index < 0) { _lastPage = null; return; } _lastPage = reflexive.Pages[index]; for (int i = 0; i < _lastPage.Fields.Length; i++) { // if _lastPage.Fields[i] is null, then we can just re-use the field from the template MetaField newField; if (_lastPage.Fields[i] != null) newField = _lastPage.Fields[i]; else newField = reflexive.Template[i]; // HACK: synchronize the opacity newField.Opacity = _loadedFields[i].Opacity; _loadedFields[i] = newField; } }
public ReflexiveClonedEventArgs(ReflexiveData old, ReflexiveData clone) { Old = old; Clone = clone; }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int) values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length < 0) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) field.FirstEntryAddress = pointer; }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _reflexiveLayout); int length = (int)values.GetInteger("entry count"); uint pointer = (uint)values.GetInteger("pointer"); // Make sure the pointer looks valid int metaStartOff = _cache.MetaArea.Offset; int metaEndOff = metaStartOff + _cache.MetaArea.Size; int offset = _cache.MetaArea.PointerToOffset(pointer); if (offset < metaStartOff || offset + length * field.EntrySize > metaEndOff) length = 0; field.Length = length; if (pointer != field.FirstEntryAddress) field.FirstEntryAddress = pointer; }
public void LeaveReflexive() { if (_currentReflexive == null) throw new InvalidOperationException("Not in a reflexive"); _reflexives.RemoveAt(_reflexives.Count - 1); _currentReflexive = _reflexives.Count > 0 ? _reflexives[_reflexives.Count - 1] : null; }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _reflexiveLayout); var length = (int) values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length <= 0 || !_cache.MetaArea.ContainsBlockPointer(pointer, (int) (length*field.EntrySize))) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) field.FirstEntryAddress = pointer; }
public void WriteReflexiveChildren(ReflexiveData field) { if (field.CurrentIndex < 0 || !field.HasChildren) return; // Get the base address and convert it to an offset if we're writing to the file var newBaseOffset = field.FirstEntryAddress; if (_type == SaveType.File) newBaseOffset = (uint)_cache.MetaArea.PointerToOffset(newBaseOffset); // Save the old base offset and set the base offset to the reflexive's base var oldBaseOffset = _baseOffset; _baseOffset = newBaseOffset; // Write each page var _oldIndex = field.CurrentIndex; var _oldPokeTemplates = _pokeTemplateFields; for (var i = 0; i < field.Length; i++) { // If we're saving everything, then change the active page so the values get loaded from the file if (_changes == null && field.CurrentIndex != i) field.CurrentIndex = i; // If we're not saving everything, then we can only poke template fields in reflexives // if the current indices all line up if (i != _oldIndex) _pokeTemplateFields = false; // Get each field in the page and write it var page = field.Pages[i]; for (var j = 0; j < page.Fields.Length; j++) { var pageField = page.Fields[j]; // The field in the page takes precedence over the field in the reflexive's template if (pageField == null && (_changes == null || _pokeTemplateFields)) pageField = field.Template[j]; // Get it from the template if (pageField != null) WriteField(pageField); } // Advance to the next chunk _baseOffset += field.EntrySize; _pokeTemplateFields = _oldPokeTemplates; } if (field.CurrentIndex != _oldIndex) field.CurrentIndex = _oldIndex; // Restore the old base offset _baseOffset = oldBaseOffset; }
public void VisitReflexive(ReflexiveData field) { AddWidth(field.Width); }
public void VisitReflexive(ReflexiveData field) { // Don't enter empty reflexives ReflexiveData oldReflexive = _currentReflexive; _currentReflexive = field; if (FilterString(field, field.Name) && field.Length > 0) { // Forcibly highlight everything inside it _highlightLevel++; _flattener.EnumWrappers(field, ReflexiveFlattener_HandleWrapper); _highlightLevel--; } else if (field.Length > 0) { _flattener.EnumWrappers(field, ReflexiveFlattener_HandleWrapper); } _currentReflexive = oldReflexive; }
public void VisitReflexive(ReflexiveData field) { // Create flatten information for the reflexive and attach event handlers to it FlattenedReflexive flattened = new FlattenedReflexive(_flatParent, field, _topLevelFields, _tracker, _changes); AttachTo(field, flattened); FlattenedReflexive oldParent = _flatParent; _flatParent = flattened; Flatten(field.Template); field.UpdateWidth(); _flatParent = oldParent; for (int i = 0; i < field.Template.Count; i++) { WrappedReflexiveEntry wrapper = flattened.WrapField(field.Template[i], field.Width, i == field.Template.Count - 1); _index++; _fields.Insert(_index, wrapper); } }
/// <summary> /// Constructs a new search result holder. /// </summary> /// <param name="foundField">The field that was found and highlighted.</param> /// <param name="listField">The top-level field in the field list. For reflexive entries, this is the topmost wrapper field, otherwise, this may be the same as foundField.</param> /// <param name="parent">The reflexive that the field is in. Can be null.</param> public SearchResult(MetaField foundField, MetaField listField, ReflexiveData parent) { ListField = listField; Field = foundField; Reflexive = parent; }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); int length = _reader.ReadInt32(); uint address = _reader.ReadUInt32(); // Make sure the address looks valid uint metaStartAddr = _cache.Info.MetaBase.AsAddress(); uint metaEndAddr = metaStartAddr + _cache.Info.MetaSize; if (address < metaStartAddr || address + length * field.EntrySize > metaEndAddr) length = 0; field.Length = length; if (length > 0) field.FirstEntryOffset = _cache.MetaPointerConverter.AddressToOffset(address); ReadReflexive(field); }
public override MetaField CloneValue() { var result = new ReflexiveData(Name, Offset, FieldAddress, EntrySize, Align, base.PluginLine, _metaArea); result._expanded = _expanded; result._width = _width; result._currentIndex = _currentIndex; result._firstEntryAddr = _firstEntryAddr; foreach (MetaField field in _template) result._template.Add(field); foreach (ReflexivePage page in _pages) result._pages.Add(page.CloneValue()); if (Cloned != null) Cloned(this, new ReflexiveClonedEventArgs(this, result)); return result; }
public void VisitReflexive(ReflexiveData field) { AddWidth(field.Width); }
public void ReadReflexiveChildren(ReflexiveData reflexive) { if (!reflexive.HasChildren || reflexive.CurrentIndex < 0) return; bool opened = OpenReader(); if (_reader == null) return; try { // Calculate the base offset to read from uint oldBaseOffset = BaseOffset; uint dataOffset = reflexive.FirstEntryAddress; if(_cache.GetType() == typeof(Blamite.Blam.FourthGen.FourthGenCacheFile)) dataOffset = HeaderOffset + (dataOffset & 0xFFFFFFF); if (_type == LoadType.File) dataOffset = (uint) _cache.MetaArea.PointerToOffset(dataOffset); BaseOffset = (uint) (dataOffset + reflexive.CurrentIndex*reflexive.EntrySize); ReflexivePage page = reflexive.Pages[reflexive.CurrentIndex]; for (int i = 0; i < page.Fields.Length; i++) { ReadField(page.Fields[i] ?? reflexive.Template[i]); } BaseOffset = oldBaseOffset; } finally { if (opened) CloseReader(); } }
private void AttachTo(ReflexiveData field, FlattenedReflexive flattened) { field.PropertyChanged += ReflexivePropertyChanged; field.Cloned += ReflexiveCloned; _flattenInfo[field] = flattened; }
public void WriteReflexiveChildren(ReflexiveData field) { if (field.CurrentIndex < 0 || !field.HasChildren) { return; } // Get the base address and convert it to an offset if we're writing to the file long newBaseOffset = field.FirstEntryAddress; if (_type == SaveType.File) { newBaseOffset = _cache.MetaArea.PointerToOffset(newBaseOffset); } // Save the old base offset and set the base offset to the reflexive's base long oldBaseOffset = _baseOffset; _baseOffset = newBaseOffset; // Write each page int _oldIndex = field.CurrentIndex; bool _oldPokeTemplates = _pokeTemplateFields; for (int i = 0; i < field.Length; i++) { // If we're saving everything, then change the active page so the values get loaded from the file if (_changes == null && field.CurrentIndex != i) { field.CurrentIndex = i; } // If we're not saving everything, then we can only poke template fields in reflexives // if the current indices all line up if (i != _oldIndex) { _pokeTemplateFields = false; } // Get each field in the page and write it ReflexivePage page = field.Pages[i]; for (int j = 0; j < page.Fields.Length; j++) { MetaField pageField = page.Fields[j]; // The field in the page takes precedence over the field in the reflexive's template if (pageField == null && (_changes == null || _pokeTemplateFields)) { pageField = field.Template[j]; // Get it from the template } if (pageField != null) { WriteField(pageField); } } // Advance to the next chunk _baseOffset += field.EntrySize; _pokeTemplateFields = _oldPokeTemplates; } if (!Equals(field.CurrentIndex, _oldIndex)) { field.CurrentIndex = _oldIndex; } // Restore the old base offset _baseOffset = oldBaseOffset; }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); var values = StructureReader.ReadStructure(_reader, _reflexiveLayout); var length = (int)values.GetInteger("entry count"); var pointer = (uint)values.GetInteger("pointer"); // Make sure the pointer looks valid var metaEnd = _cache.MetaArea.BasePointer + _cache.MetaArea.Size; if (!_cache.MetaArea.ContainsPointer(pointer) || pointer + length * field.EntrySize > metaEnd) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) field.FirstEntryAddress = pointer; }
public ReflexiveClonedEventArgs(ReflexiveData old, ReflexiveData clone) { Old = old; Clone = clone; }
public bool EnterReflexive(string name, uint offset, bool visible, uint entrySize, uint pluginLine) { if (visible || _showInvisibles) { var data = new ReflexiveData(name, offset, 0, entrySize, pluginLine, _metaArea); AddValue(data); _reflexives.Add(data); Reflexives.Add(data); _currentReflexive = data; return true; } return false; }