rmed.blog

The server is full!

06 Jan 2016

Ok, even I have to admit this is getting a bit out of hand. You see, some weeks ago I started subtly influencing my brother so that he would start playing the MMO Guild Wars 2 with me, given that it recently became free-to-play.

He finally agreed to do it (yay!), if I came up with a name for his character. I asked a friend for help and we came up with a list of names, including some hilarious ones that my brother discarded right away. Anyway, before he could create his character, he had to choose a server to play in and I told him which was the only Spanish server, but it was full. Huh, weird. We tried again the next days with no luck, so I thought of something (you must surely know what is coming).

Zoe, could you...

Yep, let's have Zoe do the dirty job. Again. I knew that the game had a public API and one of its endpoints offers information on servers, specifically: name, ID code and population. From the complete list of servers I found the one I was interested in:

{"id":2301,"name":"Bahía de Baruch [ES]","population":"Full"}

For now, I only need the ID to have the server return only the information for this server (world). Knowing that, I made an agent that made requests every 5 minutes (don't want to overload their servers or get banned ;) ) and checked the population level. If the level was not Full, then the agent would send me both a Telegram message and an email indicating the new population. Similarly, it would also notify me if the population changed to Full again.

The code is pretty simple, as it only had to check a specific server:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# baruch.py
# Rafael Medina García
import json
import urllib.request

from zoe.deco import *
import zoe

@Agent('baruch')
class Baruch:

    def __init__(self):
        self.is_full = True

    @Timed(300)
    def check(self):
        """ Check current popularion. """
        resp = urllib.request.urlopen(
            'http://api.guildwars2.com/v2/worlds?ids=2301')

        str_resp = resp.readall().decode('utf-8')
        obj = json.loads(str_resp)

        population = obj[0].get('population', None)

        if not population:
            print('[ERROR] Failed to get population')
            return

        print('[DEBUG] Current population: ' + population)

        # Determine message to send
        if population != 'Full' and self.is_full:
            self.is_full = False

            return self.send_msg(population)

        elif population == 'Full' and not self.is_full:
            self.is_full = True

            return self.send_msg(population)

    def send_msg(self, population):
        """ Send me a message with the population. """
        text_pop = 'Population is now: ' + population

        msg_mail = {
            'dst': 'relay',
            'relayto': 'mail',
            'to': 'admin',
            'subject': 'The population in Baruch Bay has changed',
            'txt': text_pop
        }

        msg_tg = {
            'dst': 'relay',
            'relayto': 'tg',
            'to': 'admin',
            'msg': text_pop
        }

        return [zoe.MessageBuilder(msg_mail), zoe.MessageBuilder(msg_tg)]

Pretty silly, I know, but it did save us a lot of time!

Tags: zoe bot agent gw2 api game

rmed

My name is Rafael Medina, and I like code.

More about me.