Kastang Ramblings of a Geek


WoW Roster PHP Class

I am working on a PHP Class called RosterAPI that will parse the WoW Armory without XML Files. Unlike my previous two posts (Part 1 and Part 2), the information for each character can be pulled through get methods. Also included in RosterAPI are guild specific functions not included in my previous posts.

The following methods are currently included:

Character Specific:
* getLevel()
* getGender()
* getClass()
* getRace()
* getAchievementPoints()
* getProfessions(): Returns an associative array containing the name and value of each profession.
* getTalents(): Returns an associative array containing the name and value of each talent tree.
* getStat($stat): Please view the comment header of the getStat() function for a list of valid $stats.

Guild Specific:
* getGuildMembers($rank): If $rank is true, an associative array containing guild names and ranks will be returned. If $rank is false, an array will be returned containing all names in the guild.
* getTopWeeklyContributers(): Returns an array of the Top 5 Weekly Contributers in the guild.
* getGuildPerks(): Returns an array of the perks a guild currently has.


I have received several emails with suggestions over the past week. In addition to everything listed above, my RosterAPI will also:

*getItems: Returns an Associative Array that will return every item equipped on a character along with the Item Level, Enchants, and Gems.
*getStatistics: Given a specific Statistic (ex: Number of deaths), the value of the statistic will be returned.

The code can be obtained via GitHub. While it is still a work in progress, it should be stable enough for personal use. This class is being used to power the backend of the We Know Roster. Please read the README file along with the example.php file for a brief introduction on how to use the class. I recommend reading the comments above each function in RosterAPI to understand what exactly will be returned (especially with those functions that return associative arrays).

Update #2

The Roster API now returns Glyphs for each character.

EDIT #2:

By request in the comments, here is a Paypal Donate button:


Parsing the WoW Armory without XML – Part 2

This post is a continuation of my original post about parsing the WoW Armory with no XML feeds available. In my original post, I showed how to pull basic character information, such as professions and talents, from each member in a specified guild. This post will expand on more specific character information such as HP, MP, and Stats.

The getCharacterInformation($charName) function in my previous post can be expanded to include additional information available on the WoW Armory. (Please view my original post for the sample code). For the most part, the code below can be directly copied into the existing method. As in my previous post, I assume you have the knowledge to make minor changes to the method (such as modifying the return array).

Exact Health and Mana:

$health = $xpath->query('//li[@class="health"]/span[@class="value"]');
$mana = $xpath->query('//li[@id="summary-power"]/span[@class="value"]');
echo $health->item(0)->nodeValue."<br />";
echo $mana->item(0)->nodeValue."<br />";

Exact Talents:
This will return the exact talent in the form of xx/xx/xx for both talents.

$exactBuilds = $xpath->query('//span[@class="name-build"]/span[@class="build"]');
echo $exactBuilds->item(0)->nodeValue."<br />";
echo $exactBuilds->item(1)->nodeValue;

Stats and Resistances:
A stat listed in the comment above the code needs to be added to the $stat variable.

 * Valid $stat values:
 * strength, agility, stamina, intellect,
 * spirit, mastery, meleedamage, meleedps,
 * meleeattackpower, meleespeed, meleehaste,
 * meleehit, meleecrit, meleecrip, expertise,
 * rangeddamage, rangeddps, rangedattackpower,
 * rangedspeed, rangedhaste, rangedhit, rangedcrit,
 * spellpower, spellhaste, spellhit, spellcrit,
 * spellpenetration, manaregen, combatregen, armor,
 * dodge, parry, block, resilience, arcaneres, fireres,
 * frostres, natureres, shadowres,
$statName = $xpath->query('//li[@data-id="'.$stat.'"]/span[@class="name"]');
$statValue = $xpath->query('//li[@data-id="'.$stat.'"]/span[@class="value"]');
echo $statName->item(0)->nodeValue."<br />";
echo $statValue->item(0)->nodeValue."<br />";

Battleground Rating and Kills

$rating = $xpath->query('//li[@class="rating"]/span[@class="value"]');
$kills = $xpath->query('//li[@class="kills"]/span[@class="value"]');
echo $rating->item(0)->nodeValue."<br />";
echo $kills->item(0)->nodeValue."<br />";

My next post will cover looking into more interesting character information such as Achievements, Reputation, or Statistics.


Parsing the WoW Armory without XML

A month or so ago Blizzard moved the WoW Armory to Battle.net servers. Currently, the new WoW Armory does not offer XML feeds for the data.  I spent a few hours working with PHP and DOM to create a 'parser' for the new Armory.  The below script is a trimmed down version of what is currently being used for the We Know Roster. I am only providing the back end script that will do the parsing and store the information in a MySQL database. Front end displaying can easily be achieved by querying the database with the stored results.

The script will pull the following information for each member in a specified guild: Name, Level, Class, Rank, Achievement Points, Profession 1 Name+Level, Profession 2 Name+Level, Talent1, and Talent2.

The scripts below require modifications to work properly. I recommend having knowledge of PHP/CLI before working with this script. I will develop a more user friendly version of this script only if Blizzard does not supply useful XML or JSON feeds in a reasonable amount of time.

The Bash Script:

The bash script pulls the newest HTML Roster file from the new Armory. This could probably be pulled via the PHP script, but since the file is several thousand lines long, I found it more efficient to save the file first and read it locally.

Please pay special attention to the paths, they will need to be altered in order to work correctly.

#Replace YOUR_GUILD_NAME_HERE with your guild name. If your Guild Name is two or more words, it should be in the format
#of Your%20Guild%20Name
wget --directory-prefix=/path/to/your/desired/directory/ http://us.battle.net/wow/en/guild/YOUR_SERVER_HERE/YOUR_GUILD_NAME_HERE/roster
mv /path/to/your/desired/directory/roster /path/to/your/desired/directory/roster.html
php /path/to/php/file/ParseRoster.php

The SQL Dump:

Import this into a MySQL database.

-- Table structure for table `roster`
  `name` VARCHAR(255) NOT NULL,
  `race` VARCHAR(255) NOT NULL,
  `class` VARCHAR(255) NOT NULL,
  `level` VARCHAR(255) NOT NULL,
  `rank` VARCHAR(255) NOT NULL,
  `ap` VARCHAR(255) NOT NULL,
  `prof1name` VARCHAR(255) DEFAULT NULL,
  `prof1value` VARCHAR(255) DEFAULT NULL,
  `prof2name` VARCHAR(255) DEFAULT NULL,
  `prof2value` VARCHAR(255) DEFAULT NULL,
  `talent1` VARCHAR(255) DEFAULT NULL,
  `talent2` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`)

The PHP Backend:

The PHP file should be fairly straight forward.

A few notes:

  • I have a config file that holds information for my database, if you have a similar file you should include it, otherwise add in the proper mysql_connect() information.
  • Make sure the path to the Roster.html file is correct.
< ?php
 * This script will parse the new WoW Armory without an XML file.
 * This script will currently pull the Name, Level, Class, Race,
 * Achievement Points, Professions, and Talents of every member
 * In a specified guild. The script works for me but may not work
 * as expected on every system. Use at your own risk.
 * @author Josh Grochowski (josh[dot]kastang[at]gmail[dot]com)
function getRosterInformation() {
    $roster = file_get_contents("/path/to/roster/file/roster.html");
    $dom = new domDocument;
    $dom->preserveWhiteSpace = false;
    //The first tbody tag marks the start of the actual
    //'roster' part of the html.
    $roster = $dom->getElementsByTagName('tbody');
    //Each Character has its own tr block.
    $char = $roster->item(0)->getElementsByTagName('tr');
    foreach ($char as $c) {
        //Character information is split into individual
        //td blocks.
        $charInfo = $c->getElementsByTagName('td');
        $charImages = $c->getElementsByTagName('img');
        //I only care about active characters. Inactive characters
        //will display 0 Achievement points.
        if((int)$charInfo->item(5)->nodeValue > 0) {
                $name = $charInfo->item(0)->nodeValue;
                $race = $charImages->item(0)->getAttribute('src');
                $class = $charImages->item(1)->getAttribute('src');
                $level = $charInfo->item(3)->nodeValue;
                $rank = trim($charInfo->item(4)->nodeValue);
                $ap = trim($charInfo->item(5)->nodeValue);
                //Returns an array containing the professions name/level and
                //talents of each individual character.
                $charArray = getCharacterInformation($name);
                $query = "INSERT INTO roster(name,race,class,level,rank,ap,prof1name,prof1value,prof2name,prof2value,talent1,talent2)
                mysql_query($query) or die(mysql_error());
                //Wait 5 seconds inbetween queries to keep from getting banned from WoW Armory servers.
                //This can probably be adjusted to three or four seconds, but if you do get banned, it can
                //last las long as 48 hours.
function getCharacterInformation($charName) {
    //link to characters page on WoW Armory
    $charInfo = file_get_contents("http://us.battle.net/wow/en/character/eitrigg/".$charName."/simple");
    $dom = new domDocument;
    $dom->preserveWhiteSpace = false;
    //Profession Names
    $xpath = new DOMXPath($dom);
    $profName = $xpath->query('//span[@class="profession-details"]/span[@class="name"]');
    //Profession Values
    $profValue = $xpath->query('//span[@class="profession-details"]/span[@class="value"]');
    $talents = $xpath->query('//span[@class="name-build"]/span[@class="name"]');
    $charArray = array("profName1" => $profName->item(0)->nodeValue,
                        "profValue1" => $profValue->item(0)->nodeValue,
                        "profName2" => $profName->item(1)->nodeValue,
                        "profValue2" => $profValue->item(1)->nodeValue,
                        "talent1" => $talents->item(0)->nodeValue,
                        "talent2" => $talents->item(1)->nodeValue);
    return $charArray;

World of Warcraft Account Security

Recently there has been discussions in my Guild regarding World of Warcraft account security. I believe this is a perfect opportunity to give my opinion on measures that I believe must be taken to ensure increased general security of your computer along with your World of Warcraft account.

One thing I must make clear is there is no such thing as a completely secure networked computer. The suggestions listed below are simply extra precautions that must be taken to minimize the chance of your computer being compromised.

* - Applies to World of Warcraft only.

Get an Authenticator*
Having an Authenticator will virtually eliminate the chance of your account being compromised. The Blizzard Authenticator costs $6.50 from the Blizzard Store. If you are an iPhone/iTouch user, you can download the Mobile Authenticator for free. Having an Authenticator is no excuse not to do the remaining suggestions.

Web Browser
Use a secure browser. For the sake of speaking, that pretty much means anything besides Internet Explorer. My personal recommendation is Google Chrome or Firefox. For each, I highly recommend the WOT plugin.

WOT’s safe browsing tool warns you about risky sites that can’t be trusted: Online shops that cheat customers; download sites that deliver malware; sites that send spam; and those with inappropriate content for kids.

Web of Trust provides an additional layer of security when visiting websites. WOT is community managed, meaning if someone spots a phishing website, they can report it. The report is upload to WOT servers, if you try to access the website that has received a poor rating, WOT will block you from going to the website without your express permission. If you use Firefox, in addition to WOT, I also highly suggest NoScript. Currently, Google Chrome does not have a  NoScript extension available.

Your World of Warcraft password should be entirely different from any other service you use. Generally speaking, a password should be at least 8 characters long with upper/lower case letters, numbers, and symbols. Your World of Warcraft password (along with other sensitive passwords) should be changed at least once a month. It takes 2 minutes to do, don't be lazy. An example of a good password would be 'I3n&$VW49*'.

Anti-Virus, etc.
Windows users - Having AV software is not full proof. Consider it just another way to decrease the chances of having malicious software installed on your computer (for a long period of time). I personally recommend Avira or NOD32. Along with AV software, I also recommend Spybot and Malwarebytes (Free Edition is fine). Malwarebytes is specifically targeted to Malware, harmful software that is generally not picked up by AV software. AV software should be set to automatically update and run daily (Both NOD32 and Avira provide this option, as do many other AV's such as AVG and Avast).  I would recommend running anti-malware software at minimum once a week.

For Mac(OSX)/Linux users, The options for security software is rather slim. I can recommend ClamXav(Mac) and Clamav(Linux) for virus scanning. I also recommend rkhunter for OSX/Linux systems. Generally speaking, there is not much more that can be done for OSX systems in terms of AV software. Sadly, Apple has spread false information on commercials by suggesting OSX is immune to viruses, until OSX suffers a mass attack, it is unlikely much further production of AV software will occur. As for Linux systems, there are other precautions that can be taken, but I will assume if you use Linux, you should know how to properly secure your system.

Note: Debian based distrobutions can run the follow command to download rkhunter and clamav:

sudo apt-get install clamav rkhunter
#rkhunter -c to run
#clamscan -r in '/' directory to run

Windows users - Automatic Updates should be turned on. Keep your system updated at all times. Microsoft is constantly releasing security patches to fix potential vulnerabilities in your system. If you are still using XP (or anything older) update to Windows 7 as soon as possible. When updates for your system become available, do not postpone restarting your computer to take effect, do it immediately when it asks.

OSX users - By Default, OSX will check for System Updates once a week (This setting can be changed in System Preferences -> Software Update). Install updates whenever they are available.

Linux users - If you are using a Debian based system, the following commands can be executed from a Terminal:

sudo apt-get update
sudo apt-get upgrade

Other non-Debian based Distributions should consult the proper documentation.

Common Sense
Be smart when you use your computer.

  • One precaution that should be taken is when reading email. Never click on links masked by anchor tags (HTML), especially World of Warcraft related emails. If you receive an email from Blizzard asking you to log in to your account, or a beta key, it is most likely a scam.
  • When using your laptop on a public network, be very careful to use SSL connections while logging in/reading email or any other services. If you are on a public network, you should always assume that someone is watching and logging everything you do (this includes cleartext logins). For maximum security, I recommend always using hardwired connection wherever possible (this includes on a home network also).
  • If at any point you find your computer acting strange, immediately stop what you are doing, update and run your protection software.
  • If your World of Warcraft account is compromised, and virus scans show up nothing on your computer. Do not assume one is not there. Change the password for your email and WoW account on a different computer, then work on finding out what caused the security breach on your WoW computer.

Everything above may seem like a lot to take in at first, especially if you have little to no protection on your computer to begin with. The hour or two it will take to setup will be well worth it if your World of Warcraft account becomes compromised. Not only will following my suggestions increase the overall security of your system, it will also save you from possible embarrassment if your account becomes compromised. Once you get everything setup, it should not take more then a half hour of manual work per week to keep your system up to date and secure. I will repeat again, having this security software in place will not make your computer full proof against attack. The above software will only minimize the chances of your system becoming compromised.


Parsing the WoW Armory – Part 2.1

I forgot to post this information in Part 2 of Parsing the WoW Armory. When parsing the guild-info.xml file, some fields are represented by  numerical values. Below is conversion table from XML numerical representations to actual values.

0 - Male
1 - Female

1 - Human
2 - Orc
3 - Dwarf
4 - Night Elf
5 - Undead
6 - Tauren
7 - Gnome
8 - Troll
10 - Blood Elf
11 - Draenei

1 - Warrior
2 - Paladin
3 - Hunter
4 - Rogue
5 - Priest
6 - Death Knight
7 - Shaman
8 - Mage
9 - Warlock
11 - Druid

For easy converting from numerical to actual values I would recommend using a PHP array(). Below is an example of the Sorted Guild list from Part 2 with the addition of the class of each character included.

< ?php
function sortedList($x) {
    $classArray = array(1 => "Warrior", 2 => "Paladin", 3 => "Hunter", 4 => "Rogue", 5 => 
          "Priest", 6 => "Death Knight", 7 => "Shaman", 8 => "Mage", 9 => "Warlock", 11 => "Druid");
    $array = array();
    foreach($x as $char) {
        $array[] = getName($char)." - ".getLevel($char)." - ".$classArray[(int)getClassId($char)]."<br />";
    return $array;