public VDFNode GetNodeAt(string[] args, bool create, int index) { if (index >= args.Length) { return(this); } if (NodeType != ValueType.Array) { return(null); } if (!(NodeData is Dictionary <string, VDFNode> arrayData)) { throw new InvalidCastException("NodeData is not a Dictionary<string, VDFNode>"); } if (ContainsKey(args[index])) { return(arrayData[args[index]].GetNodeAt(args, create, index + 1)); } if (!create) { return(null); } VDFNode newNode = new VDFNode(); arrayData.Add(args[index], newNode); return(newNode.GetNodeAt(args, true, index + 1)); }
public static VDFNode LoadFromText(StreamReader stream, bool useFirstAsRoot) { VDFNode thisLevel = useFirstAsRoot ? null : new VDFNode(); ReadText_SkipWhitespace(stream); while (!stream.EndOfStream) { ReadText_SkipWhitespace(stream); // Get key char nextChar = (char)stream.Read(); if (stream.EndOfStream || nextChar == '}') { break; } if (nextChar != '"') { throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Unexpected Character Key '{0}'", nextChar)); } string key = ReadText_GetStringToken(stream); ReadText_SkipWhitespace(stream); // Get value nextChar = (char)stream.Read(); VDFNode newNode; if (nextChar == '"') { newNode = new VDFNode(ReadText_GetStringToken(stream)); } else if (nextChar == '{') { newNode = LoadFromText(stream); } else { throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Unexpected Character Value '{0}'", nextChar)); } if (useFirstAsRoot) { return(newNode); } thisLevel[key] = newNode; } return(thisLevel); }
public static Dictionary <int, PackageInfo> LoadPackages(string path) { /* * 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 */ Dictionary <int, PackageInfo> packageInfos = new Dictionary <int, PackageInfo>(); using (BinaryReader binaryReader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), Encoding.ASCII)) { long streamLength = binaryReader.BaseStream.Length; VDFNode.ReadBin_SeekTo(binaryReader, PackageidBytes, streamLength); while (binaryReader.BaseStream.Position < streamLength) { int id = binaryReader.ReadInt32(); PackageInfo package = new PackageInfo(id); VDFNode.ReadBin_SeekTo(binaryReader, BillingtypeBytes, streamLength); package.BillingType = (PackageBillingType)binaryReader.ReadInt32(); VDFNode.ReadBin_SeekTo(binaryReader, AppidsBytes, streamLength); while (binaryReader.ReadByte() == 0x02) { while (binaryReader.ReadByte() != 0x00) { } package.AppIds.Add(binaryReader.ReadInt32()); } packageInfos.Add(package.Id, package); VDFNode.ReadBin_SeekTo(binaryReader, PackageidBytes, streamLength); } } return(packageInfos); }
public static PackageInfo FromNode(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; 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); }
/// <summary> /// Loads a VDFNode from a stream. /// </summary> /// <param name="stream">Stream to read from.</param> /// <param name="streamLength">Length of stream in bytes.</param> /// <returns>VDFNode representing the content of the given stream.</returns> public static VDFNode LoadFromBinary(BinaryReader stream, long streamLength) { if (stream.BaseStream.Position == streamLength) { return(null); } VDFNode thisLevel = new VDFNode(); bool endOfStream = false; while (true) { byte nextByte; try { nextByte = stream.ReadByte(); } catch (EndOfStreamException) { endOfStream = true; nextByte = 8; } if (endOfStream || nextByte == 8 || stream.BaseStream.Position == streamLength) { break; } string key; switch (nextByte) { case 0: { key = ReadBin_GetStringToken(stream); VDFNode newNode = LoadFromBinary(stream, streamLength); thisLevel[key] = newNode; break; } case 1: key = ReadBin_GetStringToken(stream); thisLevel[key] = new VDFNode(ReadBin_GetStringToken(stream)); break; case 2: { key = ReadBin_GetStringToken(stream); int val = stream.ReadInt32(); thisLevel[key] = new VDFNode(val); break; } case 7: { key = ReadBin_GetStringToken(stream); ulong val = stream.ReadUInt64(); thisLevel[key] = new VDFNode(val); break; } case 0xFF: return(null); default: throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Unexpected Character Key '{0}'", nextByte)); } } return(thisLevel); }