coderholic

How I got the Turntable.fm Gorilla in less than 48 hours

Turntable.fm has taken off in a big way. Launching in May, over 140,000 users signed up in the first month. Celebrities regularly hang out there, and Lady GaGa and Kanye West are even investing in the site.

For those that haven't tried it out yet (or perhaps can't, more on that shortly) turntable is somewhere that you can listen to great music and discover new artists and songs that you might otherwise not have otherwise come across.

The site features a number of rooms, each with a different theme (eg. chillout, dubstep, indie) and in each room there are up to 5 DJs. Every one in a room can "awesome" or "lame" each song that is played.

If you're the DJ you get a point for everyone awesome you receive. The more points you get the better the avatar you can select. The most prized avatar on the site, a gorilla, requires 1000 points. Currently that's something that has only been achieved by 4000 of the sites users, and something that has taken most of them weeks or even months of effort. Here's how I got the gorilla in less than 48 hours...

Getting in

Due to some licensing issues Turntable has been unavailable to anyone outside the US since the end of June. I'm based in the UK, so the first challenge I faced was simply getting into the site. I'd need to make it appear as though I was in the US. The sshuttle app makes extremely easy to do exactly that. You just need a host in the target country (fortunately this blog is hosted in the US, so that's what I used), and the IP address of the target site. It gets a little more complicated if the target site has several IP addresses, but a quick check with dig shows that turntable currently has just the one:

$ dig -tA +short turntable.fm
50.16.229.9

Tunnelling all traffic to this IP via my US based server is as simple as running this command:

sshuttle -r coderholic.com 50.16.229.9/32

It'll now appear to turntable that I'm in the US, and can login into the site using my Facebook account.

Getting 1000 points

In popular rooms it can be really difficult to get a DJ spot. Even if you manage to get one it's not easy to pick songs that get a lot of points, and it can be hard to keep your spot. That's why it usually takes weeks if not months of effort to get the 1000 points required for the gorilla. My plan was to automate the process as much as possible.

There are already lots of scripts and plugins available for Turntable. I started digging into the code of frankielaguna's Auto-Awesome bookmarket to see what was going on under the hood. The code starts with this:

//Attempt to find the room manager object
for (var prop in window) { 
    if (window.hasOwnProperty(prop) && window[prop] instanceof roommanager){ 
        ttObj = window[prop];
        break;
    } 
}

The "room manager object" sounded very interesting! Pasting the above code into the Chrome javascript console showed right away how much interesting stuff there really is in this object:

It contains details of who's DJing, how many DJ slots there are, callbacks for when you get points, and lots lots more. Certainly everything I would need was there.

My plan was to create a new room and login with 2 accounts, one my actual account, and one fake account. I'd have both the accounts DJ and automatically awesome each other. To speed the process up I made some changes to the auto-awesome code so that it would "awesome" every 5 seconds, and so that the current DJ would skip the rest of their song as soon as they received a point. I noticed a set_dj_points method in the room manager object, and overrode it like so:

// Override the set_dj_points function, so we skip to the next DJ as soon as we get a point
var set_dj_points = ttObj['set_dj_points'];
ttObj['set_dj_points'] = function(j) {
    if(ttObj.myuserid == ttObj.current_dj[0]) {
        console.log("I've got more points:", j);
        // We're done - skip to the next DJ
        ttObj.callback('stop_song');
    }
    set_dj_points(j);
}

After settings things in motion I discovered that turntable require a variable amount of the song to be played before the an awesome is actually counted, so it would usually take longer than 5 seconds for the current DJ to get a point. Not a huge problem, but it meant things would take longer than expected.

The next problem I ran into was a little more serious. After each DJ had played 40 songs they got kicked off. I could manually make them a DJ again, but that'd require me to check the site every so often. Instead I updated the script so that every 5 second iteration we check to see if we're the DJ, and if not then become one:

// Check to see if we're in the DJ queue or not
if(!ttObj.myuserid in ttObj.djs_uid) {
    // We're not!! Become a DJ
    ttObj.callback('become_dj');
}

The next problem that I ran into was that turntable limits the number of awesomes you can get from a single user to 50! Therefore I had to signup for more fake facebook accounts and get them in on the act. Rather than signing up for one new account at a time I instead created severeal accounts and got them all into the room at the same time. I created a slightly different script for these other accounts, so that they'd just awesome the song rather than DJ. I also modified the DJ script to DJ for a fixed amount of time, rather than give up DJing after the first awesome. That way I could collect a few points for each song play.

Less than 48 hours and a load of fake facebook accounts later I'd managed to get the required 1000 points. The gorilla was mine! The complete code that I used is up on GitHub: https://github.com/coderholic/turntable.fm

Preventing it

I went through this process mostly out of curiosity. It's clear that not many people are employing the same kind of tactics, with only around 4000 users of the site having obtained the gorilla. It'd certainly be a problem for turntable if everyone started doing this though, so what could they do to prevent it?

It seems as though turntable are already doing quite a bit to make it difficult , by limiting the number of awesomes received from each profile, requiring the song to be played for a certain amount of time, and booting DJs off after they've played a certain number of songs. There's certainly more that they could do. For example, they could make it harder to get hold of the roommanger object. Within the room manager object itself they could ignore any actions unless the browser has focus.

Ultimately the client code must communicate with the Turntable server though, so any client side changes would only make things harder. They wouldn't actually prevent anything. In fact Alain Gilbert has put together a node.js based Turntable client that does exactly that.

Comment or vote at Hacker News

Posted on 13 Sep 2011
If you enjoyed reading this post you might want to follow @coderholic on twitter or browse though the full blog archive.