private void AddChildrenToTreeNode(NodeEntryTreeNode treeNode) { if (treeNode.Node.Children.Count > 0) { treeNode.Nodes.AddRange(NodeEntryTreeNode.FromList(treeNode.Node.Children).ToArray()); foreach (var child in treeNode.Nodes) { AddChildrenToTreeNode((NodeEntryTreeNode)child); } } }
private void txtEditorFilter_TextChanged(object sender, EventArgs e) { if (_activeSaveFile == null) { return; } if (string.IsNullOrEmpty(txtEditorFilter.Text)) { EditorTree.Nodes.Clear(); foreach (var node in _activeSaveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); BuildVisualSubTree(treeNode, null); EditorTree.Nodes.Add(treeNode); } return; } // Filter nodes. We also show parents if children contain the text. var filterString = txtEditorFilter.Text.ToLowerInvariant(); List <NodeEntry> filteredNodes = new List <NodeEntry>(); foreach (var node in _activeSaveFile.FlatNodes) { if (node.ToString().Contains(filterString)) { filteredNodes.Add(node); } } List <NodeEntryTreeNode> filteredTreeNodes = new List <NodeEntryTreeNode>(); EditorTree.Nodes.Clear(); foreach (var node in _activeSaveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); BuildVisualSubTree(treeNode, filterString); if (treeNode.Text.ToLowerInvariant().Contains(filterString) || treeNode.Nodes.Count > 0) { EditorTree.Nodes.Add(treeNode); } } EditorTree.ExpandAll(); }
private void AddChildrenToTreeNodeWithFilter(NodeEntryTreeNode treeNode, string filter) { if (treeNode.Node.Children.Count > 0) { var nodes = new List <NodeEntryTreeNode>(); nodes.AddRange(NodeEntryTreeNode.FromList(treeNode.Node.Children).ToArray()); foreach (var child in nodes) { AddChildrenToTreeNodeWithFilter(child, filter); if (child.Text.ToLowerInvariant().Contains(filter) || child.Nodes.Count > 0) { treeNode.Nodes.Add(child); } } } }
private void LoadPcSaveClick(object sender, EventArgs e) { var fd = new OpenFileDialog { Multiselect = false, InitialDirectory = Environment.CurrentDirectory }; if (_settings.StartInSavesFolder) { fd.InitialDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Saved games", "CD Projekt Red", "Cyberpunk 2077"); } if (fd.ShowDialog() != DialogResult.OK) { return; } var fileName = fd.FileName; try { var bytes = File.ReadAllBytes(fileName); var newSaveFile = new SaveFile(_parserConfig.Where(p => p.Enabled).Select(p => p.Parser)); newSaveFile.Load(new MemoryStream(bytes)); _activeSaveFile = newSaveFile; footerLabel.Text = $"{_activeSaveFile.Header} - {fileName}"; } catch (Exception exception) { MessageBox.Show($"Error reading file: {exception.Message}"); return; } EditorTree.Nodes.Clear(); txtEditorFilter.Text = ""; foreach (var node in _activeSaveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); BuildVisualSubTree(treeNode, null); EditorTree.Nodes.Add(treeNode); } mainContainer.Panel2.Controls.Clear(); }
private void uncompressedToolStripMenuItem_Click(object sender, EventArgs e) { var fd = new OpenFileDialog { Multiselect = false, InitialDirectory = Environment.CurrentDirectory }; if (fd.ShowDialog() != DialogResult.OK) { return; } var fileName = fd.FileName; var bytes = File.ReadAllBytes(fileName); try { var newSaveFile = new SaveFile(_parserConfig.Where(p => p.Enabled).Select(p => p.Parser)); newSaveFile.LoadFromUncompressedStream(new MemoryStream(bytes)); _activeSaveFile = newSaveFile; Text = $"CyberCAT: {fileName}"; } catch (Exception exception) { MessageBox.Show($"Error reading file: {exception.Message}"); return; } EditorTree.Nodes.Clear(); txtEditorFilter.Text = ""; foreach (var node in _activeSaveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); BuildVisualSubTree(treeNode, null); EditorTree.Nodes.Add(treeNode); } }
private void loadAppearanceSectionButton_Click(object sender, EventArgs e) { var saveFile = new SaveFile(); var fileBytes = File.ReadAllBytes(appearanceUncompressedSaveFilePathTextbox.Text); var guid = Guid.NewGuid(); using (var stream = new MemoryStream(fileBytes)) { saveFile.LoadFromCompressedStream(stream); File.WriteAllText($"{Constants.FileStructure.OUTPUT_FOLDER_NAME}\\{guid}_dump.json", JsonConvert.SerializeObject(saveFile, Formatting.Indented)); } var growableSectionNames = new List <string>(); growableSectionNames.AddRange(saveFile.Nodes.Where(n => n.Size == n.TrueSize).Select(n => n.Name)); File.WriteAllLines($"{Constants.FileStructure.OUTPUT_FOLDER_NAME}\\{guid}_growableSectionNames.txt", growableSectionNames); MessageBox.Show($"Generated {Constants.FileStructure.OUTPUT_FOLDER_NAME}\\{guid}_dump.json"); foreach (var node in saveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); AddChildrenToTreeNode(treeNode); treeView1.Nodes.Add(treeNode); } }
private void ImportBinaryClick(object sender, EventArgs e) { var data = (NodeEntryTreeNode)EditorTree.SelectedNode; if (data.Node is VirtualNodeEntry) { MessageBox.Show("This is a visual node and cannot be imported into.\nVisual nodes are inserted to create more structure in the node tree and are denoted by the [V] prefix."); return; } if (data.Node.Children.Count > 0) { MessageBox.Show("Currently, nodes with children cannot be binary imported due to technical reasons."); return; } var fd = new OpenFileDialog { Multiselect = false, InitialDirectory = Environment.CurrentDirectory }; if (fd.ShowDialog() != DialogResult.OK) { return; } var fileName = fd.FileName; try { var bytes = File.ReadAllBytes(fileName); var parsers = _parserConfig.Where(p => p.Enabled).Select(p => p.Parser).ToList(); var parser = parsers.FirstOrDefault(p => p.ParsableNodeName == data.Node.Name) ?? throw new Exception("No parser for this node!"); data.Node.Offset = 0; data.Node.Size = bytes.Length; if (data.Node.WritesOwnTrailingSize) { data.Node.Size -= data.Node.TrailingSize; } using (var stream = new MemoryStream(bytes)) { using (var reader = new BinaryReader(stream)) { var newObject = parser.Read(data.Node, reader, parsers); data.Node.Value = newObject; } } } catch (Exception exception) { MessageBox.Show($"Error reading file: {exception.Message}"); return; } EditorTree.Nodes.Clear(); txtEditorFilter.Text = ""; foreach (var node in _activeSaveFile.Nodes) { var treeNode = new NodeEntryTreeNode(node); BuildVisualSubTree(treeNode, null); EditorTree.Nodes.Add(treeNode); } }
private void BuildVisualSubTree(NodeEntryTreeNode treeNode, string filter) { if (treeNode.Node.Value is Inventory inv) { // For inventory, we insert virtual nodes for the sub inventories. var subinventories = inv.SubInventories.Select(_ => (NodeEntry) new VirtualNodeEntry() { Value = _ }).ToList(); foreach (var subinventory in subinventories) { var real = subinventory as VirtualNodeEntry ?? throw new Exception("subinventory is not a VirtualNodeEntry, wtf?!"); var data = real.Value as Inventory.SubInventory; var simpleItems = new VirtualNodeEntry { Value = "Simple items" }; var modableItems = new VirtualNodeEntry { Value = "Modable Items" }; foreach (var itemNode in treeNode.Node.Children) { if (data.Items.Contains(itemNode.Value) && (filter == null || itemNode.ToString().ToLowerInvariant().Contains(filter))) { var item = ((ItemData)itemNode.Value).Data; if (item is ItemData.SimpleItemData sid) { simpleItems.Children.Add(itemNode); } else { modableItems.Children.Add(itemNode); } } } if (simpleItems.Children.Count > 0) { subinventory.Children.Add(simpleItems); } if (modableItems.Children.Count > 0) { subinventory.Children.Add(modableItems); } } treeNode.Nodes.AddRange(NodeEntryTreeNode.FromList(subinventories.Where(_ => filter == null || _.Children.Count > 0).ToList()).ToArray()); foreach (var child in treeNode.Nodes) { BuildVisualSubTree((NodeEntryTreeNode)child, filter); } return; } if (treeNode.Node.Value is CharacterCustomizationAppearances cca) { // For CCA we also insert virtual nodes for the three sections var sections = new List <CharacterCustomizationAppearances.Section> { cca.FirstSection, cca.SecondSection, cca.ThirdSection }; foreach (var section in sections) { var treeSection = new NodeEntryTreeNode(new VirtualNodeEntry { Value = section }); foreach (var appearanceSection in section.AppearanceSections) { if (filter == null || appearanceSection.ToString().ToLowerInvariant().Contains(filter)) { treeSection.Nodes.Add(new NodeEntryTreeNode(new VirtualNodeEntry { Value = appearanceSection })); } } if (treeSection.Nodes.Count > 0) { treeNode.Nodes.Add(treeSection); } } return; } if (treeNode.Node.Value is FactsTable ft) { foreach (var fe in ft.FactEntries) { if (filter == null || fe.ToString().ToLowerInvariant().Contains(filter)) { treeNode.Nodes.Add(new NodeEntryTreeNode(new VirtualNodeEntry { Value = fe })); } } return; } if (treeNode.Node.Children.Count > 0) { var nodes = new List <NodeEntryTreeNode>(); nodes.AddRange(NodeEntryTreeNode.FromList(treeNode.Node.Children).ToArray()); foreach (var child in nodes) { BuildVisualSubTree((NodeEntryTreeNode)child, filter); if (filter == null || child.Text.ToLowerInvariant().Contains(filter) || child.Nodes.Count > 0) { treeNode.Nodes.Add(child); } } } }