} // method public string Get(string name) { for (VifEntry entry = first; entry != null; entry = entry.next) { if (entry.name == name) { return(entry.value); } } return(string.Empty); } // method
public Steam() { // Get paths of folders and files steam_folder = GetSteamFolder(); if (string.IsNullOrEmpty(steam_folder)) { throw new Exception("Steam is not installed."); } if (!Directory.Exists(steam_folder)) { throw new Exception(string.Format("Folder does not exist: {0}", steam_folder)); } apps_folder = Path.Combine(steam_folder, "steamapps"); if (!Directory.Exists(apps_folder)) { throw new Exception(string.Format("Folder does not exist: {0}", apps_folder)); } libs_file = Path.Combine(apps_folder, "libraryfolders.vdf"); if (!File.Exists(libs_file)) { throw new Exception(string.Format("File does not exist: {0}", libs_file)); } // Read the libfolders file string contents = File.ReadAllText(libs_file); VifEntry libraries = VifEntry.Scan(ref contents); // Read the manifest files string[] filelist = Directory.GetFiles(apps_folder); foreach (string filename in filelist) { string ext = Path.GetExtension(filename).ToLower(); const string prefix = "appmanifest_"; int prelen = prefix.Length; if (ext == ".acf" && Path.GetFileName(filename).StartsWith(prefix)) // eg. "appmanifest_228980.acf" { contents = File.ReadAllText(filename); VifEntry manifest = VifEntry.Scan(ref contents); string appid = Path.GetFileNameWithoutExtension(filename).Substring(prelen); manifests[appid] = manifest; } } } // constructor
} // method public static StringBuilder ProcessCSGO(Arguments options) { StringBuilder buf = new StringBuilder(); Steam steam = new Steam(); string appid = "730"; VifEntry manifest = steam.GetManifest(appid); if (manifest == null) { throw new Exception(string.Format("Failed to read the manifest for csgo (appid={0}) from \"{1}\"", appid, steam.apps_folder)); } string game_folder = Path.Combine(steam.apps_folder, "common", manifest.Get("AppState", "installdir")); string game_name = manifest.Get("AppState", "name"); if (!Directory.Exists(game_folder)) { throw new Exception(string.Format("Folder does not exist: {0}", game_folder)); } buf.WriteLine("Appid {0}", appid); buf.WriteLine(game_name); buf.WriteLine(game_folder); //manifest.ToStringBuilder(buf); CSGO csgo = new CSGO(game_folder, options.output_folder); if (options.docfg) { buf.WriteLine("Created Script:"); buf.Write(csgo.CreateRecordScript().ToString()); } buf.WriteLine("{0}{1}", "Files found: ", csgo.files.Count); buf.WriteLine("{0}{1}", "Next demo number: ", csgo.maxnum + 1); if (options.docopy) { csgo.CopyFiles(); buf.WriteLine("Copied {0} files to {1}", csgo.files_copied, csgo.output_folder); } return(buf); } // method
} // method public void ToStringBuilder(StringBuilder buf, int indent = 0) { string tindent = String.Empty; if (indent > 0) { tindent = new String(' ', indent); } VifEntry entry = this; while (entry != null) { if (entry.first != null) { buf.WriteLine("{0}{1}", tindent, entry.name); entry.first.ToStringBuilder(buf, indent + 3); } else { buf.WriteLine("{0}{1} {2}", tindent, entry.name, entry.value); } entry = entry.next; } } // method
public static VifEntry Scan(ref string content) { VifToken token = new VifToken(); Stack <VifEntry> scopes = new Stack <VifEntry>(); VifEntry root = null; VifEntry prev = null; VifEntry parent = null; while (true) { // Get the first token int match = token.Match(ref content, token.eos); //System.Diagnostics.Debug.WriteLine(string.Format("Name {0,3} {1,3} {2,3} {3}", token.Length(), token.bos, token.eos, token.ToString(ref content))); if (match == -1) { break; // end of file } if (match < 0) { throw new Exception("File format error: Malformed file."); } // Test for ending curly brace. if (token.token_type == AcfType.AcfCEnd) { if (scopes.Count() == 0) { throw new Exception("File format error: Unblanaced curly brace."); } prev = scopes.Pop(); parent = (scopes.Count() > 0) ? scopes.Peek() : null; continue; } // Get the name of the entry if (token.token_type != AcfType.AcfQstr) { throw new Exception("File format error: Expected a quoted string as a name."); } VifEntry entry = new VifEntry(); entry.name = token.ToString(ref content); // Insert the entry into the graph if (root == null) { root = entry; } if (parent != null && parent.first == null) { parent.first = entry; } else if (prev != null) { prev.next = entry; } prev = entry; // Get the value of the entry, the second token. if (token.Match(ref content, token.eos) < 0) { throw new Exception(string.Format("File format error: Expected a value for name {0}", entry.name)); } //System.Diagnostics.Debug.WriteLine(string.Format("Value {0,3} {1,3} {2,3} {3}", token.Length(), token.bos, token.eos, token.ToString(ref content))); if (token.token_type == AcfType.AcfCBegin) { scopes.Push(entry); parent = entry; continue; } if (token.token_type == AcfType.AcfQstr) { entry.value = token.ToString(ref content); continue; } throw new Exception(string.Format("File format error: Malformed value for name {0}", entry.name)); } return(root); } // method