The Steam Market Shopper

The Steam Market Shopper is a C# application I wrote to automatically purchase items from the Steam Community Market based on criteria provided by the user.

BACKGROUND

The Steam Community Market is a website which allows users of Valve's PC gaming service, Steam, to buy and sell in-game (digital) items to each other. It is essentially a gigantic online flea market. Although sellers are free to set their own prices for the items they list, historical pricing information is available for all items and so it is very easy for a seller to establish the fair market price for any item they might wish to sell. As a result, item prices tend to be very uniform – often within a few cents of each other. Nevertheless, bargains will still periodically appear on the market – sellers may list items at a discounted price to make a quick sale, or simply due to user error (for example, accidentally listing an item for $1.20 instead of $12.00).

But it can be very difficult for an interested buyer to take advantage of these bargains when they appear. The Steam Community Market does not provide any kind of "buy order" functionality which would allow a user to automatically buy items when they are away from their computer, nor will it provide alerts when items meeting certain criteria go on sale. In fact, the Market does not even provide a live feed of items as they are listed; the only way to see a steady stream of new items is to continually refresh the Steam Community Market website. Therefore, the only way for a buyer to take advantage of a bargain is to be lucky enough to have reloaded the Steam Community Market shortly after the discounted item is listed, and then be fast enough to click the "buy" button before any other user. Indeed, many users will sit at their computer for long periods of time, refreshing the Steam Community Market website every few seconds, hoping to be the lucky individual who spots a deal before anyone else.

The Steam Market Shopper strives to eliminate this pointless exercise by continually monitoring the Steam Community Market for new items, and by submitting buy orders automatically, without any action from the user themselves.

DISCLAIMER

Valve's Steam Subscriber Agreement states: "You may not use Cheats, automation software (bots), mods, hacks, or any other unauthorized third-party software, to modify or automate any Subscription Marketplace process." Although Valve has been lax on taking action against users who attempt to automate the Steam Community Marketplace, bannings have occurred. In one high-profile case, a Reddit user named "dmn002" claimed he was banned for automated buying and selling after he had accumulated over $10,000 in digital items. Although I have designed and implemented the Steam Market Shopper, I have not actually put it into use. If any Valve employees happen to be read this, I assure you that this is purely a software engineering exercise; please don't ban my Steam account.

PRIOR WORK

As demonstrated by the cautionary tale above, the idea of automatically buying items from the Steam Community Market is hardly novel; many tools already exist to serve this purpose. The simplest (and most common) of these tools is a snippet of JavaScript which runs inside the user's browser. The script automatically refreshes the Steam Community Market website at an interval specified by the user (typically, every two to three seconds) and inspects the content of the page – if an item with a sufficiently low price is found, then the script simulates the clicking of the "buy" button in order to purchase the item.

While these scripts do work, they have several downsides. Firstly, they must typically open one webpage per item the user wishes to watch. A user who watches 10 items at once will be consuming a non-trivial amount of memory – not to mention the bandwidth required to refresh each of these pages every two seconds. In fact, the high bandwidth usage and repeated requests creates a very distinctive pattern of behavior which could easily be used to identify the users of such scripts, if Valve was so inclined. Secondly, these scripts are typically difficult to customize, requiring the end user to modify the JavaScript directly in order to set prices, refresh rates, and so on. Finally, these scripts must run inside a browser, with all the overhead (e.g. the rendering of the actual website) that it entails.

While more sophisticated automation tools surely exist, it is difficult to find any information on them – possibly because of their illicit nature.

DESIGN GOALS

Several goals guided the design of the Steam Market Shopper. Informed by the cautionary tale of Reddit user "dmn002", the primary design goal was to avoid detection. In particular, I wanted to avoid inundating the Steam Community Market servers with a constant stream of requests, like the JavaScripts described above. My second goal was to create a user-friendly way to capture entire classes of items, rather than forcing users to search for specific items, one by one. My third goal was to create a program which was fast and responsive; in the field of automated buying it all comes down to who can identify new listings and send buy orders the fastest.

Let's examine each of these goals in turn.

AVOIDING DETECTION

There are many mechanisms by which you might identify a buyer who is making automated purchases. But, as discussed, the easiest approach by far is to look at a user's connection history. Recall that a typical JavaScript will refresh the Steam Community Market website every two to three seconds. If a given user is submitting requests to the Steam Community Market with superhuman speed for hours at a time, then it is reasonably safe to assume that they are running an automated buyer. This presents an apparent paradox: to operate with maximum effectiveness, an automated buyer must poll the Steam Community Market servers as fast as possible, so that it can see the new listings as soon as they are posted. But the more an automated buyer polls the market, the more its behavior will stand out as irregular. The Steam Market Shopper attempts to address this problem by employing several "agents" which work in tandem. An agent is simply an HTTP connection with a unique IP address and (optionally) an associated Steam account. Agents are divided into two categories: "listing agents" and "buying agents". The job of a listing agent is to acquire new listings from the Steam Community Market server. They poll the servers on a regular basis, and submit new listings to the Steam Market Shopper for processing. When the Steam Market Shopper finds an item which matches the criteria specified by the user, it submits that listing's information to a buying agent, which then sends a "buy" request to the Steam Community Market servers in order to purchase the item.

There are two important things to note here. Firstly, the buying agents never poll the Steam Community Market servers for new listings; the only time they send requests to the server is in order to purchase an item. This minimizes the number of requests they need to make, which is important, because buying agents are the ones which will fall under the most scrutiny. Secondly, increasing the number of listing agents can increase the throughput of new listings while decreasing the amount of requests sent by any individual agent. For example, instead of having a single agent polling the Steam Community Market servers every two seconds, you can have a pool of eight different agents, which each poll the servers every second. Although you receive updates twice as fast, no single agent polls the server more than every eight seconds.