Steam Library Shortcuts

From Valve Developer Community
Revision as of 17:39, 5 August 2023 by XBLAH (talk | contribs) (Added C# methods to read and write shortcuts.vdf. TODO: this could be later converted to pseudocode, in case anyone wants to make a script of this.)
Jump to navigation Jump to search

Source mods under /sourcemods/, when configured correctly, show up on Steam Library after a restart. Source Mods placed in |all_source_engine_paths|, GoldSrc mods or even Source 2 mods don't show up by default.

Steam shortcuts file

Any game/mod could by added to the Steam Library by creating a shortcut. The shortcuts file for a given user are located under the directory steam_install_dir\\userdata\\, and the path ends with config. The shortcuts are stored inside this directory, in a file named shortcuts.vdf.

Shortcut format

  • string AppName
  • string Exe
  • string StartDir
  • string Icon
  • string ShortcutPath
  • string LaunchOptions
  • bool Hidden
  • array<string> Tags

Reading the shortcuts.vdf

   List<Shortcut> result = new List<Shortcut>();
   int start = shortcutsString.IndexOf("\u0000shortcuts\u0000") + "\u0000shortcuts\u0000".Length;
   int end = shortcutsString.LastIndexOf("\u0008\u0008");
   shortcutsString = shortcutsString.Substring(start, end - start);
   Shortcut shortcut = null;
   string word = "";
   string key = "";
   bool readingTags = false;
   int tagId = -1;
   foreach (char c in shortcutsString.ToCharArray())
   {
       if (c == '\u0000')
       {
           if (word.EndsWith("\u0001appname"))
           {
               if (shortcut != null)
                   result.Add(shortcut);
               // New shortcut
               shortcut = new Shortcut();
               key = "\u0001appname";
           }
           else if (
               word == "\u0001exe" ||
               word == "\u0001StartDir" ||
               word == "\u0001icon" ||
               word == "\u0001ShortcutPath" ||
               word == "\u0001LaunchOptions" ||
               word == "\u0002hidden"
               )
           {
               key = word;
           }
           else if (word == "tags")
           {
               readingTags = true;
           }
           else if (key != "")
           {
               switch (key)
               {
                   case "\u0001appname":
                       shortcut.AppName = word;
                       break;
                   case "\u0001exe":
                       shortcut.Exe = word.Trim('"');
                       break;
                   case "\u0001StartDir":
                       shortcut.StartDir = word.Trim('"');
                       break;
                   case "\u0001icon":
                       shortcut.Icon = word;
                       break;
                   case "\u0001ShortcutPath":
                       shortcut.ShortcutPath = word;
                       break;
                   case "\u0001LaunchOptions":
                       shortcut.LaunchOptions = word;
                       break;
                   case "\u0002hidden":
                       shortcut.Hidden = (word == "\u0001");
                       break;
                   default:
                       break;
               }
               key = "";
           }
           else if (readingTags)
           {
               if (word.StartsWith("\u0001"))
               {
                   tagId = int.Parse(word.Substring("\u0001".Length));
               }
               else if (tagId >= 0)
               {
                   shortcut.Tags.Add(word);
                   tagId = -1;
               }
               else
               {
                   readingTags = false;
               }
           }
           word = "";
       }
       else
       {
           word += c;
       }
   }
   if (shortcut != null)
       result.Add(shortcut);
   return result;

Writing the shortcuts.vdf

   private static string BuildShortcuts(List<Shortcut> shortcuts)
   {
       string shortcutsString = "\u0000shortcuts\u0000";
       for (int i = 0; i < shortcuts.Count; i++)
       {
           shortcutsString += "\u0000" + i + "\u0000";
           shortcutsString += BuildShortcut(shortcuts[i]);
           shortcutsString += "\u0008";
       }
       shortcutsString += "\u0008\u0008";
       return shortcutsString;
   }
   private static string BuildShortcut(Shortcut shortcut)
   {
       string shortcutString = "";
       //shortcutString += "\u0002appid\u0000" + shortcut.GetAppID() + "\u0000";
       shortcutString += "\u0001appname\u0000" + shortcut.AppName + "\u0000";
       shortcutString += "\u0001exe\u0000\"" + shortcut.Exe + "\"\u0000";
       shortcutString += "\u0001StartDir\u0000\"" + shortcut.StartDir + "\"\u0000";
       shortcutString += "\u0001icon\u0000" + shortcut.Icon + "\u0000";
       shortcutString += "\u0001ShortcutPath\u0000" + shortcut.ShortcutPath + "\u0000";
       shortcutString += "\u0001LaunchOptions\u0000" + shortcut.LaunchOptions + "\u0000";
       shortcutString += "\u0002hidden\u0000" + (shortcut.Hidden ? "\u0001" : "\u0000") + "\u0000\u0000\u0000";
       shortcutString += buildTags(shortcut.Tags);
       return shortcutString;
   }
   private static string buildTags(List<string> tags)
   {
       var tagString = "\u0000tags\u0000";
       for (var i = 0; i < tags.Count; ++i)
       {
           tagString += "\u0001" + i + "\u0000" + tags[i] + "\u0000";
       }
       tagString += "\u0008";
       return tagString;
   }