public MetaEditorControlPage(Meta meta, MapForms.MapForm mapForm) { InitializeComponent(); // Try to draw treeview nodes to "hide" "disabled" nodes; fail. Still leaves space where node is //treeViewTagReflexives.DrawMode = TreeViewDrawMode.OwnerDrawAll; //treeViewTagReflexives.DrawNode += new DrawTreeNodeEventHandler(myTreeView_DrawNode); this.MapForm = mapForm; this.map = mapForm.map; this.meta = meta; this.BR = new BinaryReader(meta.MS); // Create a backup of the Tags memory stream, for restoring, comparing, etc msBackup = new MemoryStream(meta.MS.ToArray()); msDebug = new MemoryStream((int)meta.MS.Length); mainReflexive = createReflexiveList(); // Done refreshTreeListing(mainReflexive); // Done this.treeViewTagReflexives.Sort(); treeViewTagReflexives.SelectedNode = treeViewTagReflexives.Nodes[0]; // Default Peek/Poke to "Single Value" this.tscbApplyTo.SelectedIndex = 0; }
public reflexiveData(reflexiveData parentReflexive) { this.node = null; this.reflexive = null; this.baseOffset = -1; this.chunkCount = 0; this.chunkSelected = -1; this.inTagNumber = -1; this.parent = parentReflexive; this.children = null; }
public void refreshTreeListing(TreeNode parent) { if (((reflexiveData)parent.Tag).chunkCount == 0) { parent.ForeColor = Color.LightGray; refreshTreeSubNodes(parent); return; } parent.ForeColor = parent.Parent.ForeColor; // If available, re-load data loadFile(); BinaryReader BR = new BinaryReader(memStream); this.SuspendLayout(); if (parent != this.Nodes[0]) { reflexiveData rd = (reflexiveData)parent.Tag; if (parent.ForeColor == Color.LightGray) { /* * BR.BaseStream.Position = ((reflexiveData)parent.Parent.Tag).baseOffset + rd.reflexive.offset; * if (((reflexiveData)parent.Parent.Tag).inTagNumber == meta.TagIndex) * BR.BaseStream.Position += meta.offset */ ((reflexiveData)parent.Tag).chunkCount = 0; return; } else { BR.BaseStream.Position = ((reflexiveData)parent.Parent.Tag).baseOffset + rd.reflexive.offset; rd.chunkCount = BR.ReadInt32(); rd.baseOffset = BR.ReadInt32() - meta.magic + rd.chunkSelected * rd.reflexive.chunkSize - meta.offset; } /* * rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); * if (rd.inTagNumber == meta.TagIndex) * rd.baseOffset -= meta.offset; * else * { * map.CloseMap(); * if (rd.inTagNumber != -1) * { * parent.ForeColor = Color.Red; * parent.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + * "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); * } * } */ } refreshTreeSubNodes(parent); this.ResumeLayout(); }
private void refreshTreeSubNodes(TreeNode parent) { BinaryReader BR = new BinaryReader(memStream); foreach (TreeNode tn in parent.Nodes) { reflexiveData rd = (reflexiveData)tn.Tag; /* * if (rd.inTagNumber != meta.TagIndex) * { * map.OpenMap(MapTypes.Internal); * BA = map.BA; * BA.Position = ((reflexiveData)parent.Tag).baseOffset + rd.reflexive.offset; * if (((reflexiveData)parent.Tag).inTagNumber == meta.TagIndex) * BA.Position += meta.offset; * } * else */ if (parent.ForeColor == Color.LightGray) { rd.chunkCount = 0; } else { BR.BaseStream.Position = ((reflexiveData)parent.Tag).baseOffset + rd.reflexive.offset; rd.chunkCount = BR.ReadInt32(); rd.baseOffset = BR.ReadInt32() - meta.magic + rd.chunkSelected * rd.reflexive.chunkSize - meta.offset; } /* * rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); * if (rd.inTagNumber == meta.TagIndex) * rd.baseOffset -= meta.offset; * else * { * map.CloseMap(); * if (rd.inTagNumber != -1) * { * tn.ForeColor = Color.Red; * tn.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + * "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); * } * } */ tn.Text = tn.Name + " [" + rd.chunkCount.ToString() + "]"; refreshTreeListing(tn); } }
/// <summary> /// Creates a clone of the passed memory stream and multiple controls of the /// passed in control type. Returns DialogResult.None if no changes have been written to the memory stream. /// Returns DialogResult.Yes if changes have been written to the original memory stream. /// </summary> /// <param name="control">Any child of type BaseField</param> /// <param name="rd">The associated reflexiveData information</param> public MassFieldChanger(BaseField control, reflexiveData rd) { /* Create "loading" form to show while loading * Form LoadingForm = new Form(); * this.Tag = LoadingForm; */ InitializeComponent(); this.FieldControl = control; // Temporarily use our BinaryReader to create a Clone of the original memory stream this.BR = new BinaryReader(control.meta.MS); this.BR.BaseStream.Position = 0; this.MS = new MemoryStream(this.BR.ReadBytes((int)this.BR.BaseStream.Length)); // Set the Reader/Writer to our cloned memory stream this.BR = new BinaryReader(MS); this.BW = new BinaryWriter(MS); this.RD = rd; this.Text = ": " + FieldControl.EntName + " (" + FieldControl.Controls[FieldControl.Controls.Count - 1].Text + ")"; reflexiveData RDParent = rd; while (RDParent.parent != null) { string s = "\\" + RDParent.reflexive.name; if (RDParent != rd) { s += "[" + RDParent.chunkSelected + "]"; } this.Text = s + this.Text; RDParent = RDParent.parent; } #region Fill in Start & End combo boxes ans select starting values for (int x = 0; x < RD.chunkCount; x++) { cbStartChunk.Items.Add(x.ToString()); cbEndChunk.Items.Add(x.ToString()); } // Start at chunk 0 cbStartChunk.Text = "0"; // Only load the first 100 chunks by default for starters cbEndChunk.Text = RD.chunkCount > 100 ? "99" : (RD.chunkCount - 1).ToString(); #endregion // States that no values have changed this.DialogResult = DialogResult.None; }
/// <summary> /// Creates a clone of the passed memory stream and multiple controls of the /// passed in control type. Returns DialogResult.None if no changes have been written to the memory stream. /// Returns DialogResult.Yes if changes have been written to the original memory stream. /// </summary> /// <param name="control">Any child of type BaseField</param> /// <param name="rd">The associated reflexiveData information</param> public MassFieldChanger(BaseField control, reflexiveData rd) { /* Create "loading" form to show while loading Form LoadingForm = new Form(); this.Tag = LoadingForm; */ InitializeComponent(); this.FieldControl = control; // Temporarily use our BinaryReader to create a Clone of the original memory stream this.BR = new BinaryReader(control.meta.MS); this.BR.BaseStream.Position = 0; this.MS = new MemoryStream(this.BR.ReadBytes((int)this.BR.BaseStream.Length)); // Set the Reader/Writer to our cloned memory stream this.BR = new BinaryReader(MS); this.BW = new BinaryWriter(MS); this.RD = rd; this.Text = ": " + FieldControl.EntName + " (" + FieldControl.Controls[FieldControl.Controls.Count-1].Text + ")"; reflexiveData RDParent = rd; while (RDParent.parent != null) { string s = "\\" + RDParent.reflexive.name; if (RDParent != rd) s += "[" + RDParent.chunkSelected + "]"; this.Text = s + this.Text; RDParent = RDParent.parent; } #region Fill in Start & End combo boxes ans select starting values for (int x = 0; x < RD.chunkCount; x++) { cbStartChunk.Items.Add(x.ToString()); cbEndChunk.Items.Add(x.ToString()); } // Start at chunk 0 cbStartChunk.Text = "0"; // Only load the first 100 chunks by default for starters cbEndChunk.Text = RD.chunkCount > 100 ? "99" : (RD.chunkCount-1).ToString(); #endregion // States that no values have changed this.DialogResult = DialogResult.None; }
private void loadValues(TreeNode tn, ListBox lb) { lb.Items.Clear(); if (tn.Nodes.Count > 0 || tn.ForeColor == System.Drawing.Color.LightGray) { return; } reflexiveData rd = (reflexiveData)tn.Tag; BinaryReader br = new BinaryReader(fStream); for (int i = 0; i < rd.chunkCount; i++) { br.BaseStream.Position = rd.baseOffset + rd.reflexive.offset + i * rd.reflexive.chunkSize; //getDataFromBinaryStream(br, ObjectType.ToString()); } }
// public reflexiveData[] loadTreeReflexives(reflexiveData parentReflexive, int metaOffset, object[] items, bool enabled) /// <summary> /// Scans from the given reflexive through all children and updates counts, offsets, etc /// </summary> /// <param name="parentReflexive">The reflexive to start scanning at</param> public void refreshReflexiveList(reflexiveData parentReflexive) { map.OpenMap(MapTypes.Internal); if (parentReflexive.parent != null) { // Update information for currently selected reflexive if (parentReflexive.inTagNumber != meta.TagIndex && parentReflexive.parent.inTagNumber != meta.TagIndex) { map.OpenMap(MapTypes.Internal); BR = map.BR; } else { BR = new BinaryReader(meta.MS); } BR.BaseStream.Position = parentReflexive.parent.baseOffset + parentReflexive.reflexive.offset; parentReflexive.chunkCount = BR.ReadInt32(); parentReflexive.baseOffset = BR.ReadInt32() - meta.magic + parentReflexive.chunkSelected * parentReflexive.reflexive.chunkSize; parentReflexive.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(parentReflexive.baseOffset); if (parentReflexive.inTagNumber == meta.TagIndex) { parentReflexive.baseOffset -= meta.offset; parentReflexive.node.ForeColor = Color.Black; parentReflexive.node.ToolTipText = "Offset: " + parentReflexive.reflexive.offset.ToString(); } else { map.CloseMap(); if (parentReflexive.inTagNumber != -1) { parentReflexive.node.ForeColor = Color.Red; parentReflexive.node.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[parentReflexive.inTagNumber].ToLower() + "] " + map.FileNames.Name[parentReflexive.inTagNumber].ToLower(); } } // Update all information for children refreshReflexiveListRecursive( parentReflexive, meta.offset + parentReflexive.baseOffset ); } else { refreshReflexiveListRecursive( parentReflexive, meta.offset ); } map.CloseMap(); }
public TreeNode[] loadTreeReflexives(BinaryReader BR, int metaOffset, object[] items, bool enabled) { List<TreeNode> tns = new List<TreeNode>(); foreach (object o in items) { TreeNode tn = new TreeNode(((IFPIO.BaseObject)o).name); if (o is IFPIO.Reflexive) { IFPIO.Reflexive IFPR = (IFPIO.Reflexive)o; reflexiveData rd = new reflexiveData(); tn.Tag = rd; rd.node = tn; rd.reflexive = IFPR; tn.ForeColor = Color.LightGray; tn.Name = IFPR.name; tn.ToolTipText = "Offset: " + rd.reflexive.offset.ToString(); if (enabled) { BR.BaseStream.Position = IFPR.offset + metaOffset; rd.chunkCount = BR.ReadInt32(); if (rd.chunkCount > 0) { rd.chunkSelected = 0; tn.ForeColor = Color.Black; rd.baseOffset = BR.ReadInt32() - meta.magic - meta.offset; // Some listings are actually in other tags! // Check [BLOC] "objects\\vehicles\\wraith\\garbage\\wing_boost\\wing_boost" // > attachments[0] = [BLOC] "objects\\vehicles\\ghost\\garbage\\seat\\seat" if (rd.baseOffset < 0 || rd.baseOffset >= memStream.Length) { rd.chunkCount = 0; } else { rd.inTagNumber = meta.TagIndex; } /* rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); if (rd.inTagNumber == -1) { tn.ToolTipText = "DATA ERROR! Possibly corrupt data or incorrect plugin."; rd.chunkCount = 0; rd.chunkSelected = -1; continue; } if (rd.inTagNumber == meta.TagIndex) rd.baseOffset -= meta.offset; else { tn.ForeColor = Color.Red; tn.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); } */ } } tn.Text += " [" + rd.chunkCount.ToString() + "]"; refData.Add(rd); // Add if non-existant, otherwise update Text /* if (rd.inTagNumber == meta.TagIndex) tn.Nodes.AddRange(loadTreeReflexives(BR, meta.offset + rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0)); else */ tn.Nodes.AddRange(loadTreeReflexives(BR, rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0)); if (rd.chunkCount != 0 | !hideUnusedReflexives) tns.Add(tn); } else { //tns.Add(tn); } } return tns.ToArray(); }
private void createTreeListing() { if (meta == null) return; try { ifp = HaloMap.Plugins.IFPHashMap.GetIfp(meta.type, HaloVersion); #region Save info about our current Selected Node TreeNode node = this.SelectedNode; string tempS = string.Empty; string[] path = new string[0]; if (node != null) { while (node.Level > 0) { tempS = "\\" + ((reflexiveData)node.Tag).reflexive.offset.ToString() + tempS; node = node.Parent; } path = ("0" + tempS).Split('\\'); } #endregion this.Nodes.Clear(); this.Sorted = sortByName; this.Nodes.Add("0", ".:[ MAIN ]:."); reflexiveData rd = new reflexiveData(); this.Nodes[0].Tag = rd; rd.node = this.Nodes[0]; rd.chunkCount = 1; rd.chunkSelected = 0; rd.baseOffset = 0; // meta.offset; rd.inTagNumber = meta.TagIndex; refData.Clear(); refData.Add(rd); BinaryReader br = new BinaryReader(memStream); this.Nodes[0].Nodes.AddRange(loadTreeReflexives(br, 0, ifp.items, true)); //meta.offset //this.ExpandAll(); this.Nodes[0].Expand(); #region Re-Select our previously selected node TreeNodeCollection nodes = this.Nodes[0].Nodes; this.Enabled = false; this.SelectedNode = this.Nodes[0]; for (int i = 1; i < path.Length; i++) { foreach (TreeNode tn in nodes) { if (((reflexiveData)tn.Tag).reflexive.offset.ToString() == path[i]) { this.SelectedNode = tn; nodes = tn.Nodes; break; } } } // If we didn't get the right node, deselect all nodes if (this.SelectedNode.Level != path.Length - 1) this.SelectedNode = null; this.Enabled = true; #endregion } catch (Exception ex) { Globals.Global.ShowErrorMsg(string.Empty, ex); } }
/// <summary> /// Creates a "MAIN" reflexive and a complete list of all sub-reflexives. /// </summary> /// <returns>A Pointer to the topmost reflexive</returns> private reflexiveData createReflexiveList() { reflexiveData rd = new reflexiveData(null); try { ifp = HaloMap.Plugins.IFPHashMap.GetIfp(meta.type, map.HaloVersion); rd.node = new TreeNode(".:[ MAIN ]:."); rd.node.Tag = rd; rd.chunkCount = 1; rd.chunkSelected = 0; rd.baseOffset = 0; // meta.offset; rd.inTagNumber = meta.TagIndex; // Load all the children reflexives for the Tag ("Main") rd.children = loadReflexivesList(rd, meta.offset, ifp.items); // Loads all chunk count, offset, etc data from MAIN down. refreshReflexiveList(rd); rd.node.Expand(); } catch (Exception ex) { Globals.Global.ShowErrorMsg(string.Empty, ex); } return rd; }
/// <summary> /// Pokes a full reflexive to the xbox /// </summary> /// <param name="rd">The reflexive to poke</param> private void debugPokeReflexive(reflexiveData rd) { // The end of the block to read int endOffset = 0; // The start of the block to read int startOffset = endOffset; // The size of the block to read int readSize = 0; // For tag main section, use headersize instead of reflexive size int size = rd.reflexive == null ? meta.headersize : rd.reflexive.chunkSize; // Keeps track of the control we are checking int controlNum = panelMetaEditor.Controls.Count; // Initialize with chunkOffset & size = 0 BaseField oldc = new BaseField(); // Read in blocks, stopping at all 8-byte Idents and reflexives to be handled accordingly while (startOffset != size) { controlNum--; BaseField c = null; int sizeChange = 0; if (controlNum >= 0) { c = (BaseField)panelMetaEditor.Controls[controlNum]; sizeChange = c.size; } else { readSize = endOffset - startOffset; } if (readSize > 0) { BR.BaseStream.Position = startOffset + rd.baseOffset; byte[] buffer = BR.ReadBytes(readSize); HaloMap.RealTimeHalo.RTH_Imports.Poke( (uint)(meta.offset + rd.baseOffset + startOffset + meta.magic), buffer, readSize); // If second part of Tag/Ident... if (c != null && c.chunkOffset >= endOffset) startOffset = c.chunkOffset; else startOffset = endOffset; } readSize = 0; // Idents must be poked individually with Tag Type, then Tag Name. It doesn't change if both // are poked at once. if (c is Ident && c.size == 8) { // Not positive if this will work, but we can try! readSize = c.chunkOffset - startOffset + 4; // TAG portion as well sizeChange = 4; if (readSize != 0) controlNum++; } // Check for a reflexive between controls if (c != null && c.chunkOffset > endOffset) { readSize = endOffset - startOffset; endOffset = c.chunkOffset; controlNum++; sizeChange = 0; } endOffset += sizeChange; oldc = c; } }
private void refreshTreeSubNodes(reflexiveData parent) { foreach (reflexiveData rd in parent.children) { TreeNode tn = rd.node; /* if (rd.inTagNumber != meta.TagIndex) { map.OpenMap(MapTypes.Internal); BR = map.BR; BR.BaseStream.Position = parent.baseOffset + rd.reflexive.offset; if (parent.inTagNumber == meta.TagIndex) BR.BaseStream.Position += meta.offset; } else { BR = new BinaryReader(meta.MS); BR.BaseStream.Position = parent.baseOffset + rd.reflexive.offset; } rd.chunkCount = BR.ReadInt32(); rd.baseOffset = BR.ReadInt32() - meta.magic + rd.chunkSelected * rd.reflexive.chunkSize; */ tn.ForeColor = (rd.chunkCount == 0 ? Color.LightGray : Color.Black); if (rd.inTagNumber != meta.TagIndex) { if (rd.inTagNumber != -1) { tn.ForeColor = Color.Red; tn.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); } } tn.Text = tn.Name + " [" + rd.chunkCount.ToString() + "]"; refreshTreeListing(rd); } }
private void createTreeListing() { if (meta == null) { return; } try { ifp = HaloMap.Plugins.IFPHashMap.GetIfp(meta.type, HaloVersion); #region Save info about our current Selected Node TreeNode node = this.SelectedNode; string tempS = string.Empty; string[] path = new string[0]; if (node != null) { while (node.Level > 0) { tempS = "\\" + ((reflexiveData)node.Tag).reflexive.offset.ToString() + tempS; node = node.Parent; } path = ("0" + tempS).Split('\\'); } #endregion this.Nodes.Clear(); this.Sorted = sortByName; this.Nodes.Add("0", ".:[ MAIN ]:."); reflexiveData rd = new reflexiveData(); this.Nodes[0].Tag = rd; rd.node = this.Nodes[0]; rd.chunkCount = 1; rd.chunkSelected = 0; rd.baseOffset = 0; // meta.offset; rd.inTagNumber = meta.TagIndex; refData.Clear(); refData.Add(rd); BinaryReader br = new BinaryReader(memStream); this.Nodes[0].Nodes.AddRange(loadTreeReflexives(br, 0, ifp.items, true)); //meta.offset //this.ExpandAll(); this.Nodes[0].Expand(); #region Re-Select our previously selected node TreeNodeCollection nodes = this.Nodes[0].Nodes; this.Enabled = false; this.SelectedNode = this.Nodes[0]; for (int i = 1; i < path.Length; i++) { foreach (TreeNode tn in nodes) { if (((reflexiveData)tn.Tag).reflexive.offset.ToString() == path[i]) { this.SelectedNode = tn; nodes = tn.Nodes; break; } } } // If we didn't get the right node, deselect all nodes if (this.SelectedNode.Level != path.Length - 1) { this.SelectedNode = null; } this.Enabled = true; #endregion } catch (Exception ex) { Globals.Global.ShowErrorMsg(string.Empty, ex); } }
/* private void refreshReflexiveListRecursive(reflexiveData parentReflexive) { if (parentReflexive.chunkCount != 0) { map.BR.BaseStream.Position = IFPR.offset + metaOffset; rd.chunkCount = map.BR.ReadInt32(); if (rd.chunkCount > 0) { rd.chunkSelected = 0; tn.ForeColor = Color.Black; rd.baseOffset = map.BR.ReadInt32() - meta.magic; // Some listings are actually in other tags! // Check [BLOC] "objects\\vehicles\\wraith\\garbage\\wing_boost\\wing_boost" // > attachments[0] = [BLOC] "objects\\vehicles\\ghost\\garbage\\seat\\seat" rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); if (rd.inTagNumber == -1) { tn.ToolTipText = "DATA ERROR! Possibly corrupt data or incorrect plugin."; rd.chunkCount = 0; rd.chunkSelected = -1; continue; } if (rd.inTagNumber == meta.TagIndex) rd.baseOffset -= meta.offset; else { tn.ForeColor = Color.Red; tn.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); } } } tn.Text += " [" + rd.chunkCount.ToString() + "]"; // Add if non-existant, otherwise update Text if (rd.inTagNumber == meta.TagIndex) rd.children = loadTreeReflexives(rd, meta.offset + rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0); else rd.children = loadTreeReflexives(rd, rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0); //if (rd.chunkCount != 0 | !cbHideUnused.Checked) rds.Add(rd); } } return rds.ToArray(); } */ private void refreshTreeListing(reflexiveData parentReflexive) { TreeNode parentNode = parentReflexive.node; if (parentReflexive.chunkCount == 0 && cbHideUnused.Checked) { // If a reflexive was listed, but no longer contains a count, remove it from the tree if (parentReflexive.parent.node.Nodes.Contains(parentReflexive.node)) parentReflexive.parent.node.Nodes.Remove(parentReflexive.node); return; } // See if we are in the MAIN of the tag if (parentReflexive != mainReflexive) { if (parentReflexive.inTagNumber == meta.TagIndex) { parentNode.ForeColor = Color.Black; parentNode.ToolTipText = "Offset: " + parentReflexive.reflexive.offset.ToString(); } else { if (parentReflexive.inTagNumber != -1) { parentNode.ForeColor = Color.Red; parentNode.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[parentReflexive.inTagNumber].ToLower() + "] " + map.FileNames.Name[parentReflexive.inTagNumber].ToLower(); } } #region old unused code /* if (parentReflexive.inTagNumber != meta.TagIndex && parentReflexive.parent.inTagNumber != meta.TagIndex) { map.OpenMap(MapTypes.Internal); BR = map.BR; BR.BaseStream.Position = ((reflexiveData)parentNode.Parent.Tag).baseOffset + parentReflexive.reflexive.offset; } else { BR = new BinaryReader(meta.MS); BR.BaseStream.Position = parentReflexive.parent.baseOffset + parentReflexive.reflexive.offset; } parentReflexive.chunkCount = BR.ReadInt32(); parentReflexive.baseOffset = BR.ReadInt32() - meta.magic + parentReflexive.chunkSelected * parentReflexive.reflexive.chunkSize; parentReflexive.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(parentReflexive.baseOffset); if (parentReflexive.inTagNumber == meta.TagIndex) { parentReflexive.baseOffset -= meta.offset; parentNode.ForeColor = Color.Black; parentNode.ToolTipText = "Offset: " + parentReflexive.reflexive.offset.ToString(); } else { map.CloseMap(); if (parentReflexive.inTagNumber != -1) { parentNode.ForeColor = Color.Red; parentNode.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[parentReflexive.inTagNumber].ToLower() + "] " + map.FileNames.Name[parentReflexive.inTagNumber].ToLower(); } } */ #endregion } if (parentReflexive == mainReflexive) { if (!treeViewTagReflexives.Nodes.Contains(parentReflexive.node)) { treeViewTagReflexives.Nodes.Add(parentReflexive.node); } } else { if (!parentReflexive.parent.node.Nodes.Contains(parentReflexive.node)) { parentReflexive.parent.node.Nodes.Add(parentReflexive.node); } } refreshTreeSubNodes(parentReflexive); }
public TreeNode[] loadTreeReflexives(BinaryReader BR, int metaOffset, object[] items, bool enabled) { List <TreeNode> tns = new List <TreeNode>(); foreach (object o in items) { TreeNode tn = new TreeNode(((IFPIO.BaseObject)o).name); if (o is IFPIO.Reflexive) { IFPIO.Reflexive IFPR = (IFPIO.Reflexive)o; reflexiveData rd = new reflexiveData(); tn.Tag = rd; rd.node = tn; rd.reflexive = IFPR; tn.ForeColor = Color.LightGray; tn.Name = IFPR.name; tn.ToolTipText = "Offset: " + rd.reflexive.offset.ToString(); if (enabled) { BR.BaseStream.Position = IFPR.offset + metaOffset; rd.chunkCount = BR.ReadInt32(); if (rd.chunkCount > 0) { rd.chunkSelected = 0; tn.ForeColor = Color.Black; rd.baseOffset = BR.ReadInt32() - meta.magic - meta.offset; // Some listings are actually in other tags! // Check [BLOC] "objects\\vehicles\\wraith\\garbage\\wing_boost\\wing_boost" // > attachments[0] = [BLOC] "objects\\vehicles\\ghost\\garbage\\seat\\seat" if (rd.baseOffset < 0 || rd.baseOffset >= memStream.Length) { rd.chunkCount = 0; } else { rd.inTagNumber = meta.TagIndex; } /* * rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); * if (rd.inTagNumber == -1) * { * tn.ToolTipText = "DATA ERROR! Possibly corrupt data or incorrect plugin."; * rd.chunkCount = 0; * rd.chunkSelected = -1; * continue; * } * if (rd.inTagNumber == meta.TagIndex) * rd.baseOffset -= meta.offset; * else * { * tn.ForeColor = Color.Red; * tn.ToolTipText = "Data Source Located in:\n[" + map.MetaInfo.TagType[rd.inTagNumber].ToLower() + * "] " + map.FileNames.Name[rd.inTagNumber].ToLower(); * } */ } } tn.Text += " [" + rd.chunkCount.ToString() + "]"; refData.Add(rd); // Add if non-existant, otherwise update Text /* * if (rd.inTagNumber == meta.TagIndex) * tn.Nodes.AddRange(loadTreeReflexives(BR, meta.offset + rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0)); * else */ tn.Nodes.AddRange(loadTreeReflexives(BR, rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items, rd.chunkCount != 0)); if (rd.chunkCount != 0 | !hideUnusedReflexives) { tns.Add(tn); } } else { //tns.Add(tn); } } return(tns.ToArray()); }
private void tvSourceTags_AfterSelect(object sender, TreeViewEventArgs e) { if (tvSourceTags.SelectedNode == null) { return; } int lastNode = tvSourceTags.SelectedNode.Level; TreeNode[] tn = new TreeNode[lastNode + 1]; tn[lastNode] = tvSourceTags.SelectedNode; for (int x = lastNode - 1; x >= 0; x--) { tn[x] = tn[x + 1].Parent; } string[] offsets = tn[lastNode].Name.Split('\\'); #region source data int baseOffsetS = 0; int chunkCountS = 0; for (int x = 0; x < offsets.Length - 1; x++) { tagInfo ti = ((tagInfo)tn[x].Tag); baseOffsetS = getOffset(fStream, baseOffsetS, int.Parse(offsets[x])) + ti.chunkSelection * ti.size; if (x == offsets.Length - 2) { chunkCountS = ti.chunkCount; } } int size = 0; if (offsets.Length > 1) { size = ((tagInfo)tn[lastNode - 1].Tag).size; } lbSourceIndices.Items.Clear(); if (baseOffsetS != -1) { BinaryReader brS = new BinaryReader(fStream); for (int i = 0; i < chunkCountS; i++) { brS.BaseStream.Position = baseOffsetS + int.Parse(offsets[offsets.Length - 1]) + i * size; lbSourceIndices.Items.Add(getDataFromBinaryStream(brS, tn[lastNode].ToolTipText.Substring(1, tn[lastNode].ToolTipText.IndexOf(']') - 1))); } } if (lastNode != 0) { reflexiveData rd = ((reflexiveData)tn[lastNode - 1].Tag); baseOffsetS = rd.baseOffset; // Don't show all for refelxives as we can't do full reflexives anyways if (tn[lastNode].Nodes.Count == 0) { chunkCountS = rd.chunkCount; } if (lastNode > 1) { while (panel1.Controls.Count > lastNode - 1) { panel1.Controls.RemoveAt(panel1.Controls.Count - 1); } for (int x = 0; x <= lastNode - 2; x++) { rd = (reflexiveData)tn[x + 1].Tag; ComboBox cb; if (panel1.Controls.Count <= x) { cb = new ComboBox(); cb.Dock = DockStyle.Right; cb.DropDownStyle = ComboBoxStyle.DropDownList; cb.Size = new System.Drawing.Size(80, 21); cb.Size = new System.Drawing.Size(panel1.Width / (tn.Length - 2), 21); cb.SelectedIndexChanged += new EventHandler(cbSourceReflexiveNumber_SelectedIndexChanged); panel1.Controls.Add(cb); } else { cb = (ComboBox)panel1.Controls[x]; cb.Size = new System.Drawing.Size(panel1.Width / (tn.Length - 2), 21); } if (rd.chunkCount == 0) { lblSourceReflexiveNumber.Enabled = false; cb.Enabled = false; } else { if (cb.Items.Count != rd.chunkCount) { cb.Items.Clear(); for (int i = 0; i < rd.chunkCount; i++) { cb.Items.Add((i + 1).ToString() + ": " + tn[x + 1].Text.Substring(0, tn[x + 1].Text.LastIndexOf('['))); } cb.SelectedIndex = 0; } lblSourceReflexiveNumber.Enabled = true; cb.Enabled = true; } } } else { lblSourceReflexiveNumber.Enabled = false; cbSourceReflexiveNumber.Enabled = false; } } #endregion loadValues(tn[lastNode], lbSourceIndices); btnSelectAll_Click(sender, e); }
/// <summary> /// Loads all the labels into the dropdown selection box. /// </summary> string[] loadLabels(reflexiveData rd) { List<string> ls = new List<string>(); IFPIO.BaseObject bo = null; if (rd.reflexive.label == "" || rd.reflexive.label == null) return new string[rd.chunkCount]; try { for (int i = 0; i <= rd.reflexive.items.Length; i++) { if (rd.reflexive.label == ((IFPIO.BaseObject)rd.reflexive.items[i]).name) { bo = (IFPIO.BaseObject)rd.reflexive.items[i]; break; } } } catch { } // If label does not exist, then return an empty array if (bo == null) return new string[rd.chunkCount]; BinaryReader BR = new BinaryReader(meta.MS); // baseOffset contains the offset to the 0 index of the reflexive int baseOffset = rd.baseOffset - (rd.reflexive.chunkSize * rd.chunkSelected); // All values must return "s" which will be returned to the caller in a string array string s = null; // l is a general integer value for whatever int l; for (int i = 0; i < rd.chunkCount; i++) { BR.BaseStream.Position = baseOffset + (rd.reflexive.chunkSize * i) + bo.offset; IFPIO.ObjectEnum ObjType = bo.ObjectType; s = string.Empty; #region For Block Indexes (Indices) if (bo is IFPIO.IFPInt && (((IFPIO.IFPInt)bo)).entIndex != null) { int value = -1; switch (ObjType) { case IFPIO.ObjectEnum.Byte: value = BR.ReadByte(); break; case IFPIO.ObjectEnum.Short: value = BR.ReadInt16(); break; case IFPIO.ObjectEnum.UInt: value = (int)BR.ReadUInt32(); break; case IFPIO.ObjectEnum.UShort: value = BR.ReadUInt16(); break; case IFPIO.ObjectEnum.Int: value = BR.ReadInt32(); break; } s += value.ToString() + ": "; if (((IFPIO.IFPInt)bo).entIndex.reflexiveLayer == "root") { BR.BaseStream.Position = (((IFPIO.IFPInt)bo).entIndex.ReflexiveOffset); int count = BR.ReadInt32(); int ofs = BR.ReadInt32() - meta.magic - meta.offset; ofs += (((IFPIO.IFPInt)bo).entIndex.ReflexiveSize * value) + ((IFPIO.IFPInt)bo).entIndex.ItemOffset; BR.BaseStream.Position = ofs; } else { } switch (((IFPIO.IFPInt)bo).entIndex.ItemType.ToLower()) { case "ident": ObjType = IFPIO.ObjectEnum.Ident; break; case "string32": ObjType = IFPIO.ObjectEnum.String32; break; case "string256": ObjType = IFPIO.ObjectEnum.String256; break; case "stringid": ObjType = IFPIO.ObjectEnum.StringID; break; default: MessageBox.Show("Didn't add support for Index Block type \"" + ((IFPIO.IFPInt)bo).entIndex.ItemType + "\". Please inform developer."); ObjType = IFPIO.ObjectEnum.Unused; break; } } #endregion switch (ObjType) { #region Enum Labels case IFPIO.ObjectEnum.Char_Enum: case IFPIO.ObjectEnum.Enum: case IFPIO.ObjectEnum.Long_Enum: switch (((IFPIO.IFPEnum)bo).enumSize) { case 8: l = (int)BR.ReadByte(); s += ((IFPIO.BaseObject)((IFPIO.IFPEnum)bo).options[l]).name; break; case 16: l = BR.ReadInt16(); s += ((IFPIO.BaseObject)((IFPIO.IFPEnum)bo).options[l]).name; break; case 32: l = BR.ReadInt32(); s += ((IFPIO.BaseObject)((IFPIO.IFPEnum)bo).options[l]).name; break; } break; #endregion #region Bitmask Labels case IFPIO.ObjectEnum.Byte_Flags: case IFPIO.ObjectEnum.Word_Flags: case IFPIO.ObjectEnum.Long_Flags: l = 0; switch (((IFPIO.Bitmask)bo).bitmaskSize) { case 8: l = (int)BR.ReadByte(); break; case 16: l = (int)BR.ReadUInt16(); break; case 32: l = (int)BR.ReadUInt32(); break; } for (int ll = 0; ll < ((IFPIO.Bitmask)bo).bitmaskSize; ll++) { s += ((l >> ll) & 1) + s; } break; #endregion #region Tag / Ident Labels case IFPIO.ObjectEnum.TagType: l = BR.ReadInt32(); goto case IFPIO.ObjectEnum.Ident; case IFPIO.ObjectEnum.Ident: l = BR.ReadInt32(); l = map.Functions.ForMeta.FindMetaByID(l); if (l != -1) { s += "[" + map.MetaInfo.TagType[l] + "] " + map.FileNames.Name[l]; } else { s += "[null] null"; } break; #endregion #region Number Data Value Labels (Int, Float, Byt, UShort, etc) case IFPIO.ObjectEnum.Byte: l = BR.ReadByte(); s += (char)l + " (" + l.ToString() + ")"; break; case IFPIO.ObjectEnum.Float: case IFPIO.ObjectEnum.Unknown: s += BR.ReadSingle().ToString(); break; case IFPIO.ObjectEnum.Short: s += BR.ReadInt16().ToString(); break; case IFPIO.ObjectEnum.UInt: s += BR.ReadUInt32().ToString(); break; case IFPIO.ObjectEnum.UShort: s += BR.ReadUInt16().ToString(); break; case IFPIO.ObjectEnum.Int: s += BR.ReadInt32().ToString(); break; case IFPIO.ObjectEnum.Unused: s += BitConverter.ToString(BR.ReadBytes(((IFPIO.Unused)bo).size), 0); break; #endregion #region String ID Labels case IFPIO.ObjectEnum.StringID: short sidIndexer = BR.ReadInt16(); byte tempnull = BR.ReadByte(); byte sidLength = BR.ReadByte(); s += map.Strings.Name[sidIndexer]; if (s.Length != sidLength) s = null; break; #endregion #region String Labels case IFPIO.ObjectEnum.UnicodeString256: case IFPIO.ObjectEnum.UnicodeString64: Encoding decode = Encoding.Unicode; try { byte[] tempbytes = BR.ReadBytes(((IFPIO.IFPString)bo).size); s += decode.GetString(tempbytes); s = s.TrimEnd('\0'); } catch { s = "UNICODE ERROR"; } break; case IFPIO.ObjectEnum.String: case IFPIO.ObjectEnum.String32: case IFPIO.ObjectEnum.String256: try { s += new string(BR.ReadChars(((IFPIO.IFPString)bo).size)); s = s.TrimEnd('\0'); } catch { s = "LABEL ERROR"; } break; #endregion default: throw new Exception("Whoops! Forgot to code in \"" + bo.ObjectType.ToString() + "\" data type for labels!\n" + "Slap the programmer and tell him about this message!"); break; } ls.Add(s); } return ls.ToArray(); }
/// <summary> /// Uses recursion to create a structured reflexiveData listing. Call "refreshReflexiveList()" afterwards. /// </summary> /// <param name="parentReflexive">The starting reflexive to start at. (Usually "MAIN")</param> /// <param name="metaOffset">The offset to the meta</param> /// <param name="items">IFPIO item listing</param> /// <returns>A list of children reflexiveData</returns> public reflexiveData[] loadReflexivesList(reflexiveData parentReflexive, int metaOffset, object[] items) { List<reflexiveData> rds = new List<reflexiveData>(); foreach (object o in items) { if (o is IFPIO.Reflexive) { IFPIO.Reflexive IFPR = (IFPIO.Reflexive)o; reflexiveData rd = new reflexiveData(parentReflexive); rd.node = new TreeNode(IFPR.name); rd.node.Name = rd.node.Text; rd.node.Tag = rd; rd.reflexive = IFPR; rd.chunkSelected = 0; // Add if non-existant, otherwise update Text if (rd.inTagNumber == meta.TagIndex) rd.children = loadReflexivesList(rd, meta.offset + rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items); else rd.children = loadReflexivesList(rd, rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize, IFPR.items); rds.Add(rd); } } return rds.ToArray(); }
private void refreshReflexiveListRecursive(reflexiveData parentReflexive, int metaOffset) { foreach (reflexiveData rd in parentReflexive.children) { // If parent reflexive is 0 count, make sure to 0 count all children as well if (parentReflexive.baseOffset >= 0) { map.BR.BaseStream.Position = rd.reflexive.offset + metaOffset; rd.chunkCount = map.BR.ReadInt32(); } else { rd.chunkCount = 0; } // If reflexive has a count if (rd.chunkCount > 0) { rd.chunkSelected = 0; rd.baseOffset = map.BR.ReadInt32() - meta.magic; // Some listings are actually in other tags! // Check [BLOC] "objects\\vehicles\\wraith\\garbage\\wing_boost\\wing_boost" // > attachments[0] = [BLOC] "objects\\vehicles\\ghost\\garbage\\seat\\seat" rd.inTagNumber = map.Functions.ForMeta.FindMetaByOffset(rd.baseOffset); if (rd.inTagNumber == -1) { rd.chunkCount = 0; rd.chunkSelected = -1; continue; } if (rd.inTagNumber == meta.TagIndex) rd.baseOffset -= meta.offset; } else { rd.chunkSelected = -1; rd.baseOffset = -1; rd.inTagNumber = -1; } if (rd.inTagNumber == meta.TagIndex) refreshReflexiveListRecursive(rd, meta.offset + rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize); else refreshReflexiveListRecursive(rd, rd.baseOffset + rd.chunkSelected * rd.reflexive.chunkSize); } }
public reflexiveData(reflexiveData parentReflexive) { node = null; reflexive = null; baseOffset = -1; chunkCount = 0; chunkSelected = -1; inTagNumber = -1; this.parent = parentReflexive; }