hacking agar.io, part 5

I guess now anyone who’s been following will also want to a chance to play Agar.io without ads. Here are the step-by-step instructions.

Note: Throughout, I’ll use 1.2.3.4 as the IP address of the DNS server you’ll be creating. Assume that every time you see this, you’ll be substituting your own server’s private IP address. Any other IP address you see should be typed in exactly as I’ve shown.

I’ll be including instructions for two different DNS servers. Choose the one that makes more sense for you based upon your experience.

Node.js DNS server version

Since I like JavaScript, here’s a Node.js implementation which may be augmented to include a nice HTML administrative interface if you’d like. I haven’t gotten quite that far yet but you can see what it takes to host a DNS server and a webserver all in one application.

  1. I assume that you already have Node.js installed, as well as npm and the express-generator. If not, you’ll need to install each first.
  2. Open a terminal
  3. Change to your home directory and optionally, change into a subfolder like ~/Sites like I did. Create one if necessary with: mkdir ~/Sites
  4. Run the express command to generate a new project:  express one-trick-pony
  5. If that ran correctly, change into the newly-created folder:  cd one-trick-pony
  6. Run the npm command to install the dependencies:  npm install
  7. Determine the IP address of your server and save this information for later: ifconfig | grep en1
  8. Run the npm command to install dnsd into your project (those are two hyphens without a space between them):  npm install dense –-save
  9. Edit the www file:  vi ./bin/www
    1. After this line var http = require(‘http’); add the indicated text seen in the block quote below
    2. After this line server.on(‘listening’, onListening);, optionally add the line:  console.log(‘Webserver running at *:3000’);
  10. Determine the path of the node command you usually use and save this information for later:  which node
    1. Run the su command to elevate into superuser (root) mode:  su
    2. Change to the working folder from before: cd /Users/yourname/Sites/one-trick-pony
    3. Run the node command giving a full path to the executable, which you found in the earlier step: ../../local/node/bin/node ./bin/www
    4. At this point, you should see that the server is running, indicating that it’s listening to two different ports:  53 (DNS) and 3000 (HTTP).
  11. From a workstation you can verify that the DNS server is running with the indicated command, noting that the server should still be logging requests:  dig @1.2.3.4 www.agar.io
  12. Now from the iPad, for example, go to Settings -> Wi-Fi -> select the i logo next to your connected local wi-fi zone -> DHCP -> DNS -> (write down everything here and save it), overwrite it with 1.2.3.4 (your server’s private IP address)
  13. Press the Home button twice and if Agar.io is running, swipe up to remove it from memory
  14. Start up the Agar.io app and verify that it logs in (even with Facebook), it works AND it no longer displays advertisements.
  15. When you’re finished, in Settings -> Wi-Fi, either “Forget This Network” your existing local wi-fi profile (re-entering your password) or manually re-enter the earlier DNS information that you wrote down from an earlier step.  Your iPad is now ready to behave like before.
  16. When you’re completely finished, go back to the server’s terminal session and press Ctrl-C to end Node and then enter the exit command to leave the su session.

Code to add into the ./bin/www file:

var dnsd = require(‘dnsd’);

function dns_handler(req, res) {
console.log(‘%s:%s/%s %j’,
req.connection.remoteAddress,
req.connection.remotePort,
req.connection.type,
req);

var question =
res.question[0],
hostname = question.name,
length = hostname.length,
ttl = Math.floor(Math.random() * 3600);

if (question.type == ‘A’) {
// Agar.io website
if (hostname == ‘agar.io’ || hostname == ‘www.agar.io’ || hostname == ‘m.agar.io’) {
res.answer.push({name:hostname, type:’A’, data:”104.20.26.122″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”104.20.25.122″, ‘ttl’:ttl});
}
// Facebook.com authentication
if (hostname == ‘facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.69.228″, ‘ttl’:ttl});
}
if (hostname == ‘www.facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.77.36″, ‘ttl’:ttl});
}
if (hostname == ‘graph.facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.77.6″, ‘ttl’:ttl});
}
// AmazonAWS
if (hostname == ‘prod-miniclip-v3-881814867.us-west-2.elb.amazonaws.com’) {
res.answer.push({name:hostname, type:’A’, data:”52.42.253.135″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.43.226.3″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.39.93.232″, ‘ttl’:ttl});
}
// Miniclippt.com
if (hostname == ‘mobile-live-v5-0.agario.miniclippt.com’) {
res.answer.push({name:hostname, type:’A’, data:”52.8.170.192″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.9.37.138″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”54.183.177.123″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.52.55.140″, ‘ttl’:ttl});
}
}
res.end();
}

var dnsServer = dnsd.createServer(dns_handler);
dnsServer.zone(‘agar.io’,
‘ns1.agar.io’, ‘root@agar.io’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘facebook.com’,
‘ns1.facebook.com’, ‘root@facebook.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘amazonaws.com’,
‘ns1.amazonaws.com’, ‘root@amazonaws.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘miniclippt.com’,
‘ns1.miniclippt.com’, ‘root@miniclippt.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.listen(53, ‘1.2.3.4’);
console.log(‘DNS server running at 1.2.3.4:53’);

Bind DNS server version

This version will assume that you have a Linux (Ubuntu, in this case) server or workstation that can run the bind9 service.

Here, I assume that you’re comfortable with commands in a terminal, know what sudo does and can use the vi editor to edit and save a file. You know what touch does. If any of these don’t sound familiar, then this probably isn’t the option for you.

On a Linux (Ubuntu) server, do the following:

  1. Make sure that your system is up-to-date:
    1. sudo apt-get update
    2. sudo apt-get upgrade
    3. sudo apt-get dist-upgrade
  2. Install the DNS service, noting that it will take a fair amount of configuration work
    1. sudo apt-get install bind9 bind9utils bind9-doc
  3. cd /etc/bind
  4. Create four empty files, one per “forward” zone. In the next steps you’ll be editing each, making sure to substitute your own server’s private IP address in each case.
    1. sudo touch for.agar.io
    2. sudo touch for.facebook.com
    3. sudo touch for.miniclippt.com
    4. sudo touch for.amazonaws.com
  5. sudo vi for.agar.io
    1. $TTL 86400

      @   IN  SOA     pri.agar.io. root.agar.io. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.agar.io.

      @       IN  A           104.20.25.122

      @       IN  A           104.20.26.122

      pri     IN  A           1.2.3.4

      www     IN  A           104.20.25.122

      www     IN  A           104.20.26.122

      m       IN  A           104.20.25.122

      m       IN  A           104.20.26.122

  6. sudo vi for.facebook.com
    1. $TTL 86400

      @   IN  SOA     pri.facebook.com. root.facebook.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.facebook.com.

      @       IN  A           31.13.69.228

      pri     IN  A           1.2.3.4

      www     IN  A           31.13.77.36

      graph   IN  A           31.13.77.6

  7. sudo vi for.miniclippt.com
    1. $TTL 86400

      @   IN  SOA     pri.miniclippt.com. root.miniclippt.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.miniclippt.com.

      pri     IN  A           1.2.3.4

      mobile-live-v5-0.agario     IN  A   52.52.55.140

      mobile-live-v5-0.agario     IN  A   54.183.177.123

      mobile-live-v5-0.agario     IN  A   52.8.170.192

      mobile-live-v5-0.agario     IN  A   52.9.37.138

  8. sudo vi for.amazonaws.com
    1. $TTL 86400

      @   IN  SOA     pri.amazonaws.com. root.amazonaws.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.amazonaws.com.

      pri     IN  A           1.2.3.4

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.42.253.135

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.39.93.232

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.43.226.3

  9. sudo vi named.conf.local
    1. # Append this to the file:

      zone “agar.io” {

      type master;

      file “/etc/bind/for.agar.io”;

      };

      zone “facebook.com” {

      type master;

      file “/etc/bind/for.facebook.com”;

      };

      zone “amazonaws.com” {

      type master;

      file “/etc/bind/for.amazonaws.com”;

      };

      zone “miniclippt.com” {

      type master;

      file “/etc/bind/for.miniclippt.com”;

      };

  10. sudo vi named.conf
    1. # Append this to file:

      logging {

      channel query.log {

      file “/var/log/query.log”;

      severity debug 3;

      };

      category queries { query.log; };

      };

  11. Make sure that the service can read/control its configuration files:
    1. sudo chmod -R 755 /etc/bind
    2. sudo chown -R bind:bind /etc/bind
  12. sudo vi /etc/apparmor.d/usr.sbin.named
    1. # Insert this line inside the “/usr/sbin/named {” section

      /var/log/query.log w,

  13. Create an empty log file, change ownership and make sure that the service can write to it
    1. sudo touch /var/log/query.log
    2. sudo chown bind /var/log/query.log
    3. cat /etc/apparmor.d/usr.sbin.named | sudo apparmor_parser -r
  14. Verify that the configuration files will parse correctly:
    1. sudo named-checkconf /etc/bind/named.conf
    2. sudo named-checkconf /etc/bind/named.conf.local
    3. sudo named-checkzone agar.io /etc/bind/for.agar.io (repeat for other zone files)
  15. Stop/start the DNS service:
    1. sudo systemctl restart bind9
  16. Follow the instructions from step 11 in the Node.js section to verify that the DNS server is running, substituting the IP address of the Ubuntu server.
  17. As before, configure the iPad to use your server’s IP address and test the Agar.io app
  18. You can watch what the app is querying from your server, giving you insight into how many ad servers are actually involved: tail -f /var/log/query.log
  19. When you are completely finished, you may stop the DNS server:  sudo systemctl stop bind9

That’s it. I’ve described how to setup two different DNS servers which should effectively cheat the ads you’d normally see during Agar.io game play.

And now, I think I’ll settle into some uninterrupted Agar.io and all without having to unnecessarily stop the game to shutdown some long-running/buggy ad attempt (losing my earned XP points).

hacking agar.io, part 4!

Eureka! I’ve managed to totally cheat the ads and still play Agar.io on my iPad! Yesh.

For those of you following along, here are the entries that I had to create in my surrogate DNS server:

  • agar.io (with A records @, www and m)
  • facebook.com (with A records @, www and graph)
  • amazonaws.com (with A record prod-miniclip-v3-881814867.us-west-2.elb)
  • miniclippt.com (with A record mobile-live-v5-0.agario)

This allows the game to startup, authenticate via Facebook’s mechanism and to start the game. Gone are the ads in their entirety.

hacking agar.io, part 3

This would be the third post in a series. You might want to read the first in the series if you haven’t already done so. Here, I continue with the work related to rendering the game server’s ads so that they don’t display at all.

DNS server

It struck me that if I could build a relatively-ignorant DNS server of my own and point my iPad to it then I could control which servers my computer talks to. Remove everything but the minimum and this should work for killing the Agar.io advertisements.

So I would need to use nslookup to find the IP addresses of the servers the game talks to. And since I’m authenticating via Facebook’s mechanism I’d need to educate the DNS server to this as well.

I happen to have an Ubuntu server which is under-utilized at the moment since I’m using it to develop WordPress plugins. So I installed bind9 (the DNS service) to this server and then configured it with some entries and zones:

  • agar.io @, www and m
  • facebook.com @ and www

For each of the entries above, I just used the nslookup command to determine what the normal IP address(es) would be and used those values.

The next step would be to make sure that this bind service does not do recursive lookups, in other words, it won’t ask for help if it doesn’t know the zone in question. So in theory, it will only give answers to the entries I’ve made; anything else will fail a lookup.

Next, on the iPad -> Settings -> Wi-fi -> my zone area, I manually set the only DNS server to be the IP address of my private server. I then confirmed that in a browser I could not resolve Google.com but could see the webpage for Agar.io.

Did it work? Not yet. Upon startup it either is missing a critical server it needs to talk to and the app now can’t do the DNS lookup to find that server. It’s okay. I’ll keep hacking away at this to find out what server that is. I should be able to get this approach to work, I just need to go to school on the application some more to find out.

hacking agar.io, part 2

This would be the second post in a series. You might want to read the first in the series if you haven’t already done so. Here, I continue with the work related to redirecting the game’s server traffic to my own website so that I can discover the interface.

DNS server

I first install Dnsmasq on my MacBook, add a single entry to its /etc/hosts file to redirect traffic for m.agar.io to my MacBook’s private IP address. Starting up Dnsmasq I then have a DNS server which will redirect game traffic to my own website. Make sure that the program is running by entering ps aux|grep dnsmasq|grep -v grep. You should see an entry for this program.

It’s probably a good idea to test your DNS server to verify that it returns the expected information.

nslookup
> server myip
> m.agar.io.
> exit

After entering the third line above you should see a DNS lookup which returns your server’s private IP address.

Our website

In my ~/sites folder, I run the following command to use Express to generate a generic website: express agar. As is usual for Express, I change into the newly-created agar directory and then run npm install to bring in the dependencies. Since the default installation binds to an upper TCP port and we want the standard port 80 instead, I then edit the bin/www file in this folder and replace the port number 3000 with 80 on a single line.

Note that Node.js, the underlying program that serves up an Express website, will not be able to bind to port 80 since it’s reserved unless I’m running as the root user. If your own user is setup to run the su command then you should be able to start this website with the command su npm start in the agar folder. Otherwise, you’ll have to run just su to become the root user, navigate back into your user folder area to find this folder and then just run npm start instead.

It’s probably a good idea to test the website by bringing up Safari and entering the address http://myip/ (substituting my private IP address) to see if it works.

Configuring the iPad

At this step, I’ll need to tell the iPad’s Wi-Fi configuration to use my own DNS server first and then the existing set of DNS servers next. You’ll find this under Settings -> Wi-Fi -> select the i button next to your own connected Wi-Fi network -> DHCP -> DNS -> prepend your own server’s private IP address and a comma at the beginning of the list.

This is the initial preparation for redirecting the game traffic to your own website. Note that the Node.js website while running will write to its log file and this will be our method of discovering the interface for Agar.io.

Discovery phase

By now attempting to play the Agar.io game on the iPad, it makes requests to what it thinks is the server. Only these requests are now being sent to my website instead. As each attempt is logged as a failure on my own website, I then make this call manually in another computer to the actual Agar.io website to see what it’s supposed to return.

For example, the game makes a request to the game server’s interface with just /info as the URL.

/info returns:

{"regions":{
  "CN-China":{"avgPlayersPerServer":368.5,"avgPlayersPerRealm":147.4,"numPlayers":737,"numServers":5,"numRealms":5},
  "US-Atlanta":{"avgPlayersPerServer":445.1034482758621,"avgPlayersPerRealm":203.2755905511811,"numPlayers":25816,"numServers":267,"numRealms":127},
  "EU-London":{"avgPlayersPerServer":430.6,"avgPlayersPerRealm":191.37777777777777,"numPlayers":8612,"numServers":179,"numRealms":45},
  "SG-Singapore":{"avgPlayersPerServer":546.0,"avgPlayersPerRealm":136.5,"numPlayers":1092,"numServers":9,"numRealms":8},
  "Unknown":{"numPlayers":0,"numServers":0,"numRealms":0},
  "BR-Brazil":{"avgPlayersPerServer":333.3220338983051,"avgPlayersPerRealm":200.6734693877551,"numPlayers":19666,"numServers":181,"numRealms":98},
  "RU-Russia":{"avgPlayersPerServer":473.25,"avgPlayersPerRealm":145.6153846153846,"numPlayers":1893,"numServers":45,"numRealms":13},
  "JP-Tokyo":{"avgPlayersPerServer":460.0,"avgPlayersPerRealm":172.5,"numPlayers":1380,"numServers":8,"numRealms":8},
  "TK-Turkey":{"avgPlayersPerServer":287.14285714285717,"avgPlayersPerRealm":154.6153846153846,"numPlayers":2010,"numServers":30,"numRealms":13}
  },
  "totals":{"numPlayers":61206,"numServers":724,"numEnabledServers":317,"numRealms":317}
}

As you can see, this is a fair bit of information. The format is known as json in case it’s not familiar to you. As of my writing this, there appear to be over 61,000 players in the game right now and well over 700 servers with almost half of those enabled. So this would be why it’s difficult to get a simultaneous FFA game with your friends—the odds are against you.

Without further ado, here are the other queries which I discovered.

/ returns:

37.187.171.110:1523
8QJP8

This appears to be your issued server and port on the first line and what is likely its instance alias from whichever cloud-based company they’re using.

/getLatestID returns:

131

I know, not very impressive. But it appears to be the highest user ID for your issued server.

/findServer returns:

{"ip":"151.80.98.52:1516","token":"86JYH"}

Another json response, this appears to also be issuing you a server and port. It’s possible that the first home query is asked at the beginning of the game and then /findServer is called each time your die in the game.

So far, this appears to be everything I’ve learned from this redirection technique.

Status

At this point, I now have the game interface which the Agar.io app uses to communicate with the server. It likely makes more requests but that’s good for now. I could have enough to go on in order to work up something so that multiple iOS people could join the same FFA game, for example, since we know this issuing mechanism.

hacking agar.io

In an earlier post I described an addictive game called Agar.io, an interactive eat-or-be-eaten game involving graphical dots. In this series of posts, I’ll be attempting to hack the game to see what I can get away with.

Agar-top

Define:  hacking

I suppose there are several ways of interpreting the term hack here. In the movies, some character will “hack the mainframe” or some other nonsense. And we’re also familiar with someone who attempts to use techniques to hack a website, perhaps injecting SQL code into an innocent-looking HTML form. Here, I refer to one of the original uses of the word, to hack away at a problem until it is solved. I’m interested in the game itself, how it talks to the server and I’d like to go to school on their efforts. As a coder of smartphones myself I’d call that part of the learning curve.

Goals

Ultimately, I would like to learn how the game works behind-the-scenes. I do have some secondary goals though. It would be interesting to see if it is in fact possible to edit an existing iOS app and have it still work and all without the original coder’s digital certificate. If successful, I think the first order of business would be to remove the ads you might see during game play. Another personal goal would be to allow multiple friends on iOS devices to play the FFA (free-for-all) mode of the game with each other; this could be made possible with a proxy server, I’d propose.

The platform

Currently, I play the Agar.io game on an iPad II since I prefer the interface over a browser-based version that’s available. So I will be attempting to hack the Apple store app ultimately.

This may turn out to be impossible since an app that runs on iOS is supposed to be digitally signed to prevent tampering. And yet this is what I intend to do, nonetheless. I’ll be testing that assertion to see if a hacked app will still work.

Concepts

Here, I’ll discuss some of the concepts of the approaches I’ll take.

  • Patching:  Patching is an old-school technique in which binary code, for example, is edited in place with a script. Individual characters or code is replaced in the original to create a new file. The patch program itself works together with another program called diff, used to calculate the differences between two files.
  • DNS:  This service is responsible for looking up a name like m.agar.io and replacing it with an IP address.
  • Redirection:  Using your own DNS server so that you can redirect requests to your own website instead of the intended one.
  • iOS app:  An iOS app might seem a little daunting if you’re not a coder. It’s actually a collection or manifest of files all rolled up into one .ipa file. I think it’s safe to say that the app was written in Apple’s Xcode using a computer language like Objective-C or Swift.
  • Ad-based add-ons:  It’s clear that Agar.io has many opportunities to display ads within the game itself. The programming interface to these (for the Agar.io developer) is almost always JavaScript-based.
  • Tethering:  Connecting a smartphone—or the iPad in this case—to a computer to allow for interaction (like development testing) to occur.

Throughout this series of posts keep in mind that if I’m indicating a command, it’s often being done on a MacBook with OS X 10.11.5 El Capitan at a shell prompt. Otherwise, I could be referring to something I’m doing on an iPad II with iOS 9.3.2 installed.

DNS server

I’ll be using the Dnsmasq easy-to-implement DNS server for redirecting Agar.io’s server requests to my own website. I’ll then configure my iPad to use this server first when doing DNS lookups.

Discovery website

And since I’m familiar with Node.js and Express I’ll be using this to mockup a website for those redirected app requests. When the iPad makes a request to what it thinks is the Agar.io website, I will see that request in my website’s logs.

This could be technically called a man-in-the-middle technique since I could then have my own website forward the request to Agar.io’s actual server and then answer the iPad with that response, adjusting it if I wanted to. I guess technically you could also call this a proxy approach.

Binary editor

I’ll likely also use Hex Fiend at least minimally to find the location within the main program app where I’ll be patching the code.

Installing a modified app

Normally, you would download an app directly to our iPad straight from the Apple iTunes store. Technically, I suppose, I could have taken advantage of the redirection concept from before to steer the iPad to my own website to deliver the edited content but it’s not that difficult. There appears to be a mechanism so that you can download iOS applications on an OS X computer and then, while tethered, install them remotely using iTunes. This actually allows us to use a MacBook in this case to snag the code package itself and to start all the fun. We’ll be taking advantage of this in order to then try to push a modified app package to the iPad.

If you’re on a standard OS X computer and you get the Agar.io app, it won’t seemingly do anything after the download; you’re not presented with the usual Open button after it has downloaded. It does, however, get silently copied to your hard drive under your user folder in /Users/username/Music/iTunes/iTunes Media/Mobile Applications. Having downloaded it, you should find a file called Agar.io 1.3.0.ipa which is the app (collection) itself.

Expanding the app

From here, you might not know that an .ipa file is little more than a .zip file. I’d suggest copying the Agar.io app file somewhere else (like creating a folder called AgarIO) and then open a shell so that you can decompress it.

MacBook:AgarIO$ unzip "Agar.io 1.3.0.ipa"

This command then will decompress the collection of files for you.

What’s inside the .ipa file

There are a lot of files inside this package, just like you’d find with most store apps. The first I’ll discuss is iTunesMetadata.plist which is perhaps the most aggravating of all. A .plist file is like a database for a coder, it usually stores configuration options. Opening it with TextEdit then shows me that this is the file responsible for knowing who downloaded it (myself) and how I’m then authorized to use it. I’m sure there’s a similar mechanism inside any music file you download from iTunes to prevent you from playing it on an unauthorized device. So in other words, I couldn’t just patch the Agar.io application and then make it available for download for others. Each person interested in this would need to go through the motions themselves.

Next, there is a META-INF folder which contains two files. I haven’t fully investigated them yet but the first is com.apple.FixedZipMetadata.bin which appears to again be a compressed collection of files. And the second is com.apple.ZipMetadata.plist. It appears to have some indication of how the actual program was zipped up into an .ipa file.

The final folder is Payload which includes what appears to be a single file, Agar.io. Or, is it a single file? Knowing what I do about making iOS apps, it’s actually another compressed file. In Finder, you’ll want to rename this Agar.io file to Agar.zip, for example. Back in your shell, then unzip it as you did before to expand its contents.

What’s inside the Payload file

So now we’re getting down to the actual programming itself. Everything we have seen up until now is just a wrapper so that iTunes and Apple can provision an app to you and just your device(s).

Surprisingly, there are a total of 1,111 .png graphic files inside. Most seem to represent the many skins that you’ll see in the game. There are 153 .plist files which are used to store anything from advertisement configuration information, to promotions, to language localization information and collections of available skins by category. With respect to my goals, I’m not really interested in these. And there is a single .db file for the Vundle advertising platform.

There is a folder called _CodeSignature which appears to include hashes of the collection of graphics, presumably to prevent them from being edited perhaps.

There are 65 .ccbi files which appear to be another form of .plist files. There are 15 .json files which appear to have different localized versions.

Finally, there is agar.io which is the actual program file itself. I’ll save the actual editing for a follow-up post to this one.

Status

That’s a good start so far. We’ve downloaded the Agar.io app and performed two decompression steps to get at the actual executable itself. Next, I think I’ll switch gears and build the discovery website and DNS server so that I can get at the app’s server interface.

Update

Skip to the final post in this six-part series if you’re looking for the code. Enjoy!

unseen complications

Don’t you hate the unseen complications that rear their ugly heads somewhere down the line?  Today’s drama involved the inclusion of a very cool fullscreen api by Vincent Guillou.  Of course, it worked great in development and then failed silently on production.  Here is an overview of what makes my production site a little different.

Production Site Overview

GoDaddy domain name hosting with option “forwarding with masking” —> Firebase.com—based hosting site

GoDaddy does this technically by serving up a single HTML page which simply frames the remote content.  By its nature, it uses the HTTP protocol and cannot use HTTPS. In its configuration it allows you to set either HTTP/HTTPS for the framed content, however.  You’d think that you would have plenty of room to make something work. And it did work just fine up until the latest add to the project:  a button which allows the browser to go full screen and back again.

Unfortunately, the first push to production then failed silently. The button was there but didn’t seem to work. Entering the development area of the browser I saw that the browser had to block the content because the framing page was HTTP and the framed content was HTTPS and this isn’t allowed.

Okay, so I thought I could then adjust GoDaddy’s settings so that I could frame the content as HTTP to match the parent document. Unfortunately I see that Firebase always uses HTTPS and does not support HTTP. Since I can’t mis-match the content and combined with the fact that I can’t easily promote GoDaddy to HTTPS on the framing page or demote Firebase on the framed page, I was screwed.

To make a long story short, I either had to pay for hosting at Firebase (which allows you to bind your domain name to their hosting server) or I could abandon the cool  feature. Since I’m trying to highlight the cool new features of the latest browsers I decided that’s it’s better to just pay Firebase in this case.

It was still a bit technical in getting all this to work since Firebase only bound a single entity (www) to the website using my domain. This means that if someone just puts in my domain name only then they’re stuck at a GoDaddy-parked page. To work around this problem, I set up a redirect to deal with this situation. This time it looked like:  myJS.io -> http://www.myJS.io. Problem solved.

So now, the cool new feature is working on production and the implementation is slightly simpler, not that anyone else would necessarily know.

use your domain name not theirs

There are times when you want to use a service provider like Gmail, WordPress, Firebase, Heroku or OpenShift but you don’t necessarily want to keep advertising their domain name with your business, blog or website.

Converting me@gmail.com to me@MyDomain.com

This one is easy enough, assuming that you know your way around your domain registrar’s configuration.  I usually park things at GoDaddy these days so I’ll use them as an example. Likewise, I’ll assume that you have a free mailbox at Google’s Gmail.

Assumptions:

  • Mailbox: me@gmail.com
  • Domain: MyDomain.com
  • Registrar: GoDaddy

Instructions:

  1. Write down the collection of email entities that you would like to forward to your mailbox
  2. Log into GoDaddy, visit the Manage My Domains page
  3. Choose the Manage Email link associated with your domain
  4. If you haven’t already, setup email forward for your domain
  5. Choose the Create Forward link
  6. Type in the first email entity from step one above, for example, support
  7. When you type the @ symbol you next get to select MyDomain.com
  8. In the next field, enter your mailbox name of me@gmail.com
  9. In the next field, choose the Free email forwarding with domain: MyDomain.com
  10. Click the Create button
  11. Repeat for each of the entities you’d like to be:  support@MyDomain.com, info@MyDomain.com, MyName@MyDomain.com, etc

It’s best at this point to wait a couple of minutes and then send a test email out to one of these entities to see if it arrives into your mailbox.  Once you’ve verified that it works you may begin to use it confidently.

I routinely create multiple mailboxes for notification apps so that they can have their own email queue.  Again, email forwarding hides the Gmail mailbox name.

Converting wordpress.com/Me to blog.MyDomain.com

Again, this is easy enough using a feature called forwarding with masking.

Assumptions:

  • Blog: wordpress.com/me
  • Domain: MyDomain.com
  • Registrar: GoDaddy

Instructions:

  1. Log into GoDaddy, visit the Manage My Domains page
  2. Choose the gear icon associated with your domain and then choose thee Manage DNS link
  3. Choose the Settings tab
  4. Under Forward -> Subdomain choose the Manage link
  5. Click the Add Subdomain Forwarding button
  6. Enter blog as the subdomain
  7. Select http as the protocol
  8. Enter wordpress.com/me in the next field
  9. Select 301 as the Redirect Type
  10. Under forward settings choose Forward with Masking
  11. Click the Add button

Give it a couple of minutes before giving this a try to see if it works.

The same technique works for your website.  For example, I’m hosting a website at Firebase.com, another at Heroku, yet another at OpenShift.com, etc.  Each of these hosting providers would probably love it if I allowed the world to see their domain name in the URL.  But I’d rather not since that’s free advertising to them.  Don’t these examples look better?

happy-pretty-8464.firebase.com -> MyDomain.com

myphpapp-mydomain.rhcloud.com -> MyCoolApp.MyDomain.com

myappmydomain.herokuapp.com -> MyApp.MyDomain.com

Honestly, domain names cost you year after year.  You might as well take advantage of the many free services which are included with your domain registration.