Steam Library Shortcuts: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (clean up, added orphan, uncategorised, deadend tags)
(Updating code)
Line 6: Line 6:
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.
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 =
== 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'''.
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 =
== Shortcut format ==


* string AppName
* string AppName
Line 20: Line 20:
* array<string> Tags
* array<string> Tags


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


= Writing the shortcuts.vdf =
== Writing the shortcuts.vdf ==
<code>
<syntaxhighlight lang=csharp>
    private static string BuildShortcuts(List<Shortcut> shortcuts)
  private static string BuildShortcuts(List<Shortcut> shortcuts)
    {
  {
        string shortcutsString = "\u0000shortcuts\u0000";
      string shortcutsString = "\u0000shortcuts\u0000";
        for (int i = 0; i < shortcuts.Count; i++)
      for (int i = 0; i < shortcuts.Count; i++)
        {
      {
            shortcutsString += "\u0000" + i + "\u0000";
          shortcutsString += "\u0000" + i + "\u0000";
            shortcutsString += BuildShortcut(shortcuts[i]);
          shortcutsString += BuildShortcut(shortcuts[i]);
            shortcutsString += "\u0008";
          shortcutsString += "\u0008";
        }
      }
        shortcutsString += "\u0008\u0008";
      shortcutsString += "\u0008\u0008";
        return shortcutsString;
      return shortcutsString;
    }
  }


    private static string BuildShortcut(Shortcut shortcut)
  private static string BuildShortcut(Shortcut shortcut)
    {
  {
        string shortcutString = "";
      string shortcutString = "";
        //shortcutString += "\u0002appid\u0000" + shortcut.GetAppID() + "\u0000";
      //shortcutString += "\u0002appid\u0000" + shortcut.GetAppID() + "\u0000";
        shortcutString += "\u0001appname\u0000" + shortcut.AppName + "\u0000";
      shortcutString += "\u0001appname\u0000" + shortcut.AppName + "\u0000";
        shortcutString += "\u0001exe\u0000\"" + shortcut.Exe + "\"\u0000";
      shortcutString += "\u0001exe\u0000\"" + shortcut.Exe + "\"\u0000";
        shortcutString += "\u0001StartDir\u0000\"" + shortcut.StartDir + "\"\u0000";
      shortcutString += "\u0001StartDir\u0000\"" + shortcut.StartDir + "\"\u0000";
        shortcutString += "\u0001icon\u0000" + shortcut.Icon + "\u0000";
      shortcutString += "\u0001icon\u0000" + shortcut.Icon + "\u0000";
        shortcutString += "\u0001ShortcutPath\u0000" + shortcut.ShortcutPath + "\u0000";
      shortcutString += "\u0001ShortcutPath\u0000" + shortcut.ShortcutPath + "\u0000";
        shortcutString += "\u0001LaunchOptions\u0000" + shortcut.LaunchOptions + "\u0000";
      shortcutString += "\u0001LaunchOptions\u0000" + shortcut.LaunchOptions + "\u0000";
        shortcutString += "\u0002hidden\u0000" + (shortcut.Hidden ? "\u0001" : "\u0000") + "\u0000\u0000\u0000";
      shortcutString += "\u0002hidden\u0000" + (shortcut.Hidden ? "\u0001" : "\u0000") + "\u0000\u0000\u0000";
        shortcutString += buildTags(shortcut.Tags);
      shortcutString += buildTags(shortcut.Tags);
        return shortcutString;
      return shortcutString;
    }
  }


    private static string buildTags(List<string> tags)
  private static string buildTags(List<string> tags)
    {
  {
        var tagString = "\u0000tags\u0000";
      var tagString = "\u0000tags\u0000";
        for (var i = 0; i < tags.Count; ++i)
      for (var i = 0; i < tags.Count; ++i)
        {
      {
            tagString += "\u0001" + i + "\u0000" + tags[i] + "\u0000";
          tagString += "\u0001" + i + "\u0000" + tags[i] + "\u0000";
        }
      }
        tagString += "\u0008";
      tagString += "\u0008";
        return tagString;
      return tagString;
    }
  }
</code>
</syntaxhighlight>


= Get AppId for a shotcut =
== Get AppId for a shotcut ==
To display an image in the library, the app id of the shortcut must be known. What has been documented so far is that the app id is given by the following (untested) method:
To display an image in the library, the app id of the shortcut must be known. What has been documented so far is that the app id is given by the following (untested) method:
<code>
<syntaxhighlight lang=csharp>
    var longValue = new Long(crcValue, crcValue, true);
  var longValue = new Long(crcValue, crcValue, true);
    longValue = longValue.or(0x80000000);
  longValue = longValue.or(0x80000000);
    longValue = longValue.shl(32);
  longValue = longValue.shl(32);
    longValue = longValue.or(0x02000000);
  longValue = longValue.or(0x02000000);
    return result.ToString();
  return result.ToString();


    private string GetSHA1()
  private string GetSHA1()
    {
  {
        var data = Encoding.ASCII.GetBytes(Exe);
      var data = Encoding.ASCII.GetBytes(Exe);
        var hashData = new SHA1Managed().ComputeHash(data);
      var hashData = new SHA1Managed().ComputeHash(data);
        var hash = string.Empty;
      var hash = string.Empty;
        foreach (var b in hashData)
      foreach (var b in hashData)
        {
      {
            hash += b.ToString("X2");
          hash += b.ToString("X2");
        }
      }
        return hash;
      return hash;
    }
  }
</code>
</syntaxhighlight>


{{Uncategorized|date=January 2024}}
{{Uncategorized|date=January 2024}}

Revision as of 11:39, 25 June 2025

Wikipedia - Letter.png
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages)
Dead End - Icon.png
This article has no Wikipedia icon links to other VDC articles. Please help improve this article by adding links Wikipedia icon that are relevant to the context within the existing text.
January 2024

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;
   }

Get AppId for a shotcut

To display an image in the library, the app id of the shortcut must be known. What has been documented so far is that the app id is given by the following (untested) method:

   var longValue = new Long(crcValue, crcValue, true);
   longValue = longValue.or(0x80000000);
   longValue = longValue.shl(32);
   longValue = longValue.or(0x02000000);
   return result.ToString();

   private string GetSHA1()
   {
       var data = Encoding.ASCII.GetBytes(Exe);
       var hashData = new SHA1Managed().ComputeHash(data);
       var hash = string.Empty;
       foreach (var b in hashData)
       {
           hash += b.ToString("X2");
       }
       return hash;
   }
Wikipedia - Letter.png
This article has not been added to any content Wikipedia icon categories. Please help out by Wikipedia icon adding categories.
January 2024