void LoadVDFNodeToTreeView(VDFNode node, TreeNode parent = null) { TreeNode newTreeNode = new TreeNode(node.Name); newTreeNode.Tag = new TreeNodeVDFTag(TreeNodeVDFTag.Type.Node, node); //Set the tag of our new TreeNode to our VDFNode using our TreeNodeVDFTag which will help us identify which BaseToken we have. if (node.Keys != null) { foreach (VDFKey key in node.Keys) { LoadVDFKeyToTreeView(key, newTreeNode); //Loop through each child keys of our VDFNode and add them to our newTreeNode child nodes recursively. } } if (node.Nodes != null) { foreach (VDFNode childNode in node.Nodes) { LoadVDFNodeToTreeView(childNode, newTreeNode); } } if (parent == null) //Check if the parent argument is set to null. If it is, it means that our node is a root node. Add them directly to the Treeview. Otherwise, add them to the parent TreeViewNode. { tViewData.Nodes.Add(newTreeNode); } else { parent.Nodes.Add(newTreeNode); } }
TreeNode CreateNewKey(string Name, string Value, TreeNodeVDFTag treeNodeTag, TreeNode nodeSelected) { TreeNode newTreeNode; if (treeNodeTag.TagType == TreeNodeVDFTag.Type.Node) //If the tag type of our selected tree node is a VDFNode. Then it's quite easy to create a new key for us. Just need to call the CreateNewKey method. { newTreeNode = CreateNewKey(Name, Value, treeNodeTag.Token as VDFNode, nodeSelected); } else { //We will need to retrieve the parent of this key for this one if the key is the one that is selected. if (nodeSelected.Parent == null) //Make sure that the parent of the TreeNode is set to another TreeNode { throw new NullReferenceException("TreeNode " + nodeSelected.Text + " parent property is not set!"); } VDFKey selectedKey = treeNodeTag.Token as VDFKey; //Cast our token to key first. if (selectedKey.Parent == null) { throw new NullReferenceException("Parent property of key " + selectedKey.Name + " is not set!"); } VDFNode parentNode = selectedKey.Parent; newTreeNode = CreateNewKey(Name, Value, parentNode, nodeSelected.Parent); } return(newTreeNode); }
const string APPMANIFEST_SEARCH_STRING = "appmanifest_*.acf"; //The search pattern to be used for searching steam apps manifest. /// <summary> /// Lists all the library folders of the steam installation. /// </summary> /// <param name="MainSteamInstallPath">The main directory of steam. (The installation folder.)</param> /// <returns></returns> public static List <string> RetrieveLibraryFolders(string MainSteamInstallPath) { List <string> libraryFolders = new List <string>(1); //Initialize our list of library folders with a count of 1 as we know that the InstallDir is a library folder. libraryFolders.Add(MainSteamInstallPath); //Let us now locate the file that contains the list of all the steam library folders in the machine. string LibFileFullPath = MainSteamInstallPath + "\\" + SteamAppsManager.STEAM_APPS_DIRNAME + "\\" + LIBRARY_FOLDERS_NAME; //The full path of the library folders file. if (!File.Exists(LibFileFullPath)) { return(libraryFolders); } VDFData vdfReader = new VDFData(LibFileFullPath); VDFNode vNode = vdfReader.Nodes.FindNode(LIBFILE_NODE_NAME); //Find the node that contains the list of steam libraries. if (vNode == null || vNode.Keys == null || vNode.Keys.Count == 0) //If it isn't found or the Nodes key is null or empty, there's nothing else to be done. Return the list of libraryfolders that we already have. (which is just MainSteamInstallPath) { return(libraryFolders); } foreach (VDFKey vKey in vNode.Keys) //List all the keys inside the vNode node. { if (vKey.Name.IsInteger()) //As per what I've seen from the Library Folders file, it seems that the key name for the location of the folders itself is a number so check if the key name is a number. { libraryFolders.Add(vKey.Value); } } return(libraryFolders); }
TreeNode AddNodeToNode(string Name, VDFData parentVDFDataStructure, TreeNodeVDFTag treeNodeTag, TreeNode nodeSelected) { TreeNode newTreeNode; if (treeNodeTag.TagType == TreeNodeVDFTag.Type.Node) //If we have the node itself selected on our Treeview, we just need to call the AddNodeToNode method directly. { newTreeNode = AddNodeToNode(Name, nodeSelected, parentVDFDataStructure, treeNodeTag.Token as VDFNode); } else { //We will need to retrieve the parent of this key for this one if the key is the one that is selected. if (nodeSelected.Parent == null) //Make sure that the parent of the TreeNode is set to another TreeNode { throw new NullReferenceException("TreeNode " + nodeSelected.Text + " parent property is not set!"); } VDFKey selectedKey = treeNodeTag.Token as VDFKey; //Cast our token to key first. if (selectedKey.Parent == null) { throw new NullReferenceException("Parent property of key " + selectedKey.Name + " is not set!"); } VDFNode parentNode = selectedKey.Parent; newTreeNode = AddNodeToNode(Name, nodeSelected.Parent, vdfData, parentNode); } return(newTreeNode); }
public void Save() { var apps = _sharedConfig.Nodes[0].Node("Software").Node("Valve").Node("Steam").Node("apps"); foreach (var app in Apps) { var vdfApp = apps.Node(app.Id.ToString()); if (vdfApp == null) { vdfApp = new VDFNode(app.Id.ToString(), _sharedConfig, apps); apps.Nodes.Add(vdfApp); } var tagsNode = vdfApp.Node("tags"); if (tagsNode != null) { foreach (var key in tagsNode.Keys.Select(k => k.Name).ToArray()) { tagsNode.Keys.CleanRemoveKey(key); } } int keyIndex = 0; foreach (var tag in app.Tags.Where(p => p.Value).Select(p => p.Key)) { if (tagsNode == null) { tagsNode = new VDFNode("tags", _sharedConfig, vdfApp); } tagsNode.Keys.Add(new VDFKey(keyIndex.ToString(), tag, tagsNode)); keyIndex++; } } _sharedConfig.SaveToFile(_sharedConfigPath, true); }
void UpdateNodeInfo(string Name, VDFNode nodeToUpdate, TreeNode treeNodeToUpdate) { if (Name != nodeToUpdate.Name) //To prevent initializing a new string. Check if Name is just the same as the one on the node. { nodeToUpdate.Name = Name; treeNodeToUpdate.Text = Name; } }
TreeNode CreateNewNode(string Name, VDFData parentVDFStructure, VDFNode parentNode, out VDFNode newNode) { newNode = new VDFNode(Name, parentVDFStructure, parentNode); //Create our new VDFNode first which will be referenced by our newNode argument (which will be passed back to the calling method.) TreeNode newTreeNode = new TreeNode(Name); newTreeNode.Tag = new TreeNodeVDFTag(TreeNodeVDFTag.Type.Node, newNode); //Set the tag to our newNode. Make sure to use VDFTag. return(newTreeNode); }
public static PackageInfo FromVdfNode(VDFNode node) { VDFNode idNode = node.GetNodeAt(new[] { "packageId" }, false); if (idNode != null && idNode.NodeType == ValueType.Int) { int id = idNode.NodeInt; string name = null; VDFNode nameNode = node.GetNodeAt(new[] { "name" }, false); if (nameNode != null && nameNode.NodeType == ValueType.String) { name = nameNode.NodeString; } PackageInfo package = new PackageInfo(id, name); VDFNode billingtypeNode = node["billingtype"]; if (billingtypeNode != null && billingtypeNode.NodeType == ValueType.String || billingtypeNode.NodeType == ValueType.Int) { int bType = billingtypeNode.NodeInt; /*if( Enum.IsDefined( typeof(PackageBillingType), bType ) ) { * * } else { * * }*/ package.BillingType = (PackageBillingType)bType; } VDFNode appsNode = node["appids"]; if (appsNode != null && appsNode.NodeType == ValueType.Array) { foreach (VDFNode aNode in appsNode.NodeArray.Values) { if (aNode.NodeType == ValueType.Int) { package.AppIds.Add(aNode.NodeInt); } } } return(package); } return(null); }
TreeNode CreateNewKey(string Name, string Value, VDFNode parent, TreeNode parentTreeNode) { if (parent.Keys == null) { throw new NullReferenceException("Keys list of " + parent.Name + " node is set to null!"); } VDFKey newKey = new VDFKey(Name, Value, parent); //Create our key with the values passed on to us as arguments. parent.Keys.Add(newKey); TreeNode newTreeNode = new TreeNode(Name); newTreeNode.Tag = new TreeNodeVDFTag(TreeNodeVDFTag.Type.Key, newKey); //Store our VDFKey on the tag property of our newTreeNode. Make sure to use the TreeNodeVDFTag. parentTreeNode.Nodes.Add(newTreeNode); return(newTreeNode); }
void DeleteVDFNode(VDFNode nodeToDelete, TreeNode treeNodeToDelete) { if (nodeToDelete.Parent == null) //If Parent property of the nodeToDelete is null then most likely we are a root node. { if (nodeToDelete.ParentVDFStructure == null) { throw new NullReferenceException("ParentVDFStructure property of Node " + nodeToDelete.Name + " is not set!"); } nodeToDelete.RemoveNodeFromParent(FullRemovalFromTheVDFStruct: true); tViewData.Nodes.Remove(treeNodeToDelete); //No need to do checks for our TreeNode as we can most certainly assume that our TreeNode is a root node as well. } else //If the nodeToDelete's parent property is set to another VDFNode then just remove it from the child nodes list of the parent. Do the same for the treenode. { nodeToDelete.RemoveNodeFromParent(); treeNodeToDelete.Parent.Nodes.Remove(treeNodeToDelete); } }
private void Window_Loaded(object sender, RoutedEventArgs e) { //check steam running //while (!CheckSteamProcess()) // MessageBox.Show("Steam app must be closed"); //get steam users var userdatapath = Path.Combine(Settings.SteamInstallPath, "userdata"); var users = new Dictionary <string, string>(); var localconfigs = new Dictionary <string, VDFNode>(); foreach (var userdirpath in Directory.GetDirectories(userdatapath, "*", SearchOption.TopDirectoryOnly)) { var userid = Path.GetFileName(userdirpath); var localconfig = new VDFData(File.ReadAllText(Path.Combine(userdirpath, "config", "localconfig.vdf")), false).Nodes[0]; localconfigs.Add(userid, localconfig); var username = "******"; try { username = localconfig.Node("friends").Node(userid).Key("name"); } catch { } users.Add(userid, username); } switch (users.Count) { case 0: MessageBox.Show("Steam users not found"); Close(); break; case 1: _userId = users.Keys.First(); break; default: var suw = new SelectUserWindow(users); suw.ShowDialog(); if (string.IsNullOrEmpty(suw.SelectedUser)) { Close(); } _userId = suw.SelectedUser; break; } _localConfig = localconfigs[_userId]; _steamUser = new SteamUser(_userId); _steamUser.UpdateAppsFromWeb(); _steamUser.UpdateAppsFromSharedConfig(); DataContext = _steamUser; }
void GUIUpdate_LoadNodeInfo(VDFNode node) { txtName.Text = node.Name; }
/// <summary> /// Loads Apps from packageinfo.vdf. /// </summary> /// <param name="path">Path of packageinfo.vdf</param> public static Dictionary <int, PackageInfo> LoadPackages(string path) { Dictionary <int, PackageInfo> result = new Dictionary <int, PackageInfo>(); /* packageinfo.vdf entry example format, sometimes has extra values. Line breaks are only for readability and not part of format. * we only care about *packageid*, *billingtype*, *appids* * *undeciphered*(24 bytes i haven't deciphered) *changenumber*(4 bytes, little endian) * 00 *packageid*(variable size, big endian, ascii) 00 * 02 packageid 00 *packageid*(4 bytes, little endian) * 02 billingtype 00 *billingtype*(4 bytes, little endian) * 02 licensetype 00 *licensetype*(4 bytes, little endian) * 02 status 00 00 00 00 00 00 extended 00 * 08 00 appids 00 02 *entrynumber*(variable size, number stored as string(ascii), starts at 0, random example: 31 38 39=189) 00 *appid*(4 bytes, little endian) * 08 00 depotids 00 02 *entrynumber* 00 *depotid*(4 bytes, little endian) 02 *entrynumber* 00 *depotid* 02 *entrynumber* 00 *depotid* * 08 00 appitems 00 08 08 08 */ BinaryReader bReader = new BinaryReader(new FileStream(path, FileMode.Open), Encoding.ASCII); long fileLength = bReader.BaseStream.Length; // seek to packageid: start of a new entry byte[] packageidBytes = { 0x00, 0x02, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, 0x69, 0x64, 0x00 }; // 0x00 0x02 p a c k a g e i d 0x00 byte[] billingtypeBytes = { 0x02, 0x62, 0x69, 0x6C, 0x6C, 0x69, 0x6E, 0x67, 0x74, 0x79, 0x70, 0x65, 0x00 }; // 0x02 b i l l i n g t y p e 0x00 byte[] appidsBytes = { 0x08, 0x00, 0x61, 0x70, 0x70, 0x69, 0x64, 0x73, 0x00 }; // 0x08 0x00 appids 0x00 VDFNode.ReadBin_SeekTo(bReader, packageidBytes, fileLength); while (bReader.BaseStream.Position < fileLength) { int id = bReader.ReadInt32(); PackageInfo package = new PackageInfo(id); VDFNode.ReadBin_SeekTo(bReader, billingtypeBytes, fileLength); package.BillingType = (PackageBillingType)bReader.ReadInt32(); VDFNode.ReadBin_SeekTo(bReader, appidsBytes, fileLength); while (bReader.ReadByte() == 0x02) { while (bReader.ReadByte() != 0x00) { } package.AppIds.Add(bReader.ReadInt32()); } result.Add(package.Id, package); VDFNode.ReadBin_SeekTo(bReader, packageidBytes, fileLength); } return(result); }
/// <summary> /// Initializes the SteamApp class. /// </summary> /// <param name="vdfdata">The parsed VDF Data Structure.</param> /// <param name="LibPath">The path of the library containing the application.</param> void init(VDFData vdfdata, string LibPath) { if (vdfdata == null) { throw new ArgumentNullException("Argument VDF Data is set to null!"); } if (vdfdata.Nodes == null || vdfdata.Nodes.Count == 0) { throw new NullReferenceException("Nodes of VDFData is either null or empty!"); } _unparsedData = vdfdata; VDFNode vNode = vdfdata.Nodes.FindNode(MANIFEST_NODE); //Locate our root node. We can do nodes[0] as well and it'll be faster but just to be safe. if (vNode == null) { throw new NullReferenceException("Node " + MANIFEST_NODE + " is not found!"); } if (vNode.Keys == null || vNode.Keys.Count == 0) { throw new NullReferenceException("Node " + MANIFEST_NODE + " list of keys is either null or empty!"); } VDFKey vKey = vNode.Keys.FindKey(MANIFEST_KEY_NAME); //Locate our first key which will be the name of the app. if (vKey != null) { _Name = vKey.Value; } else { throw new NullReferenceException("Key pertaining to the name of the app is not found under " + MANIFEST_NODE + " node."); } vKey = vNode.Keys.FindKey(MANIFEST_KEY_APPID); if (vKey != null) { int tryresult; if (int.TryParse(vKey.Value, out tryresult)) { _AppID = tryresult; } else { throw new NullReferenceException("Key pertaining to the Application ID of the app under " + MANIFEST_NODE + " node is invalid!"); } } else { throw new NullReferenceException("Key pertaining to the Application ID of the app is not found under " + MANIFEST_NODE + " node."); } vKey = vNode.Keys.FindKey(MANIFEST_KEY_INSDIR); if (vKey != null) { _InstallDir = LibPath + "\\" + SteamAppsManager.STEAM_APPS_DIRNAME + "\\" + SteamAppsManager.STEAM_APPS_COMMON_DIRNAME + "\\" + vKey.Value; _InstallDirName = vKey.Value; } else { throw new NullReferenceException("Key pertaining to the directory name containing the app under " + MANIFEST_NODE + " node is not found!"); } }
public static VDFNode Node(this VDFNode node, string name) { return(node.Nodes.FirstOrDefault(n => n.Name == name)); }
public static string Key(this VDFNode node, string name) { return(node.Keys.FirstOrDefault(n => n.Name == name).Value); }
public static bool ContainsKey(this VDFNode node, string name) { return(node.Keys.Any(n => n.Name == name)); }
TreeNode AddNodeToNode(string Name, TreeNode Parent, VDFData parentVDFDataStructure, VDFNode nodeParent) { VDFNode newNode; //Declare our newNode type VDFNode variable which we will be used by our CreateNewNode to pass back our newly created VDFNode. TreeNode newTreeNode = CreateNewNode(Name, parentVDFDataStructure, nodeParent, out newNode); //Call the method which will do the job of creating a TreeNode and VDFNode for us. if (nodeParent.Nodes == null) { throw new NullReferenceException("Nodes list of VDFData class is set to null!"); } nodeParent.Nodes.Add(newNode); Parent.Nodes.Add(newTreeNode); return(newTreeNode); }