) { chop; $completed{$_}++; } close(QUESTS);
# all our starting init crap. yawn.
my $browser = LWP::UserAgent->new;
my %headers = ('User-Agent' => 'Mozilla/5.0 Gecko/20051107 Firefox/1.5');
my $zones_url = 'http://wow.allakhazam.com/db/qzone.html?x';
my $specials_url = 'http://wow.allakhazam.com/db/qspecial.html?x';
my $root_url = 'http://wow.allakhazam.com';
my $side_regexp = qr/($options{side}|BothSides|\?)/;
my @zone_urls; # will hold all the zones discovered.
my $zones_content = $browser->get($zones_url, %headers)->content;
while ($zones_content =~ /(\/db\/qlookup.html\?zone=\d+?)">(.*?)<\/a>/g) {
next if $2 eq 'Darkmoon Faire'; # use "Special Category" version.
push (@zone_urls, { name => $2, url => "$root_url$1" }); # slurpee.
}
# now we need to load in the "Special Category" and "Unknown" zones.
my $specials_content = $browser->get($specials_url, %headers)->content;
while ($specials_content =~ /(\/db\/qlookup.html\?special=\-?\d+?)">(.*?)<\/a>/g) {
push (@zone_urls, { name => $2, url => "$root_url$1" }); # slurpee. I ARR STONE MASTAH.
} # dunno how many unknown zones there are, but annoying nonetheless.
foreach (-365, -366, -367, 1977) { # add some of the unknown zones.
push (@zone_urls, { name => "Unknown ($_)", url => "$root_url/db/qlookup.html?special=$_" });
}
# sort the zones from our different groups alphabetically.
@zone_urls = sort { lc $a->{'name'} cmp lc $b->{'name'} } @zone_urls;
# skipped sides, total, completed zone, total. a waste of my's.
my $x_zone = 0; my $x_total = 0; my $c_zone = 0; my $c_total = 0;
my $o_zone = 0; my $o_total = 0; # number of quests available to us.
# we've got all our zones.
print header(); # HTML header.
foreach my $zone (@zone_urls) {
my $zone_content = $browser->get($zone->{'url'}, %headers)->content;
my @te_headers = ["Name","Starts in","Side","Level","Start Npc"];
my %te_config = (keep_html => 1, strip_html_on_match => 0); # bah.
my $te = HTML::TableExtract->new(headers=>@te_headers, %te_config);
$te->parse($zone_content); print STDERR "Finding quests in $zone->{name}.\n";
foreach my $ts ($te->table_states) {
print "\n";
print " | ID | Name | Starts in | ".
"Level | Start NPC | Side |
\n";
foreach my $r ($ts->rows) {
@$r[0] =~ /wquest=(\d+)/; my $q = $1;
@$r[0] =~ s/(\/db.*)/$root_url$1/g;
@$r[0] =~ s/(\/images.*)/$root_url$1/g;
@$r[2] = @$r[2] ? @$r[2] : '?'; next unless $q;
@$r[4] = @$r[4] ? @$r[4] : '?'; # no NPC? Whoops.
if (@$r[2] !~ /$side_regexp/) { $x_zone++; next; }
$o_zone++; # we can do this quest, so count it, eh?
my $s = ''; if ($completed{$q}) { $c_zone++; $s = '*'; }
print "$s | $q | ".
"@$r[0] | @$r[1] | @$r[3] | ".
"@$r[4] | @$r[2] |
\n";
} print "
"; # all done this zone, so print out some stats.
print "Unlisted quests not matching our side: $x_zone. "; # stat one.
print "Listed quests matching our side: $o_zone. "; # stat two. mmMm.
print "Quests completed for this zone: $c_zone.
"; # stat three.
$x_total += $x_zone; $c_total += $c_zone; $x_zone = $c_zone = 0;
$o_total += $o_zone; $o_zone = 0; # BOoirring.
last; # we only care about quests STARTING here.
}
} # HTML footer and final counts. cos counting is fun.
print "Total unlisted quests not matching our side: $x_total. ";
print "Total listed quests matching our side: $o_total. ";
print "Total quests completed: $c_total.
";
print footer();
################################################################
# HTML headers and footers. nothing too exciting here. #
################################################################
sub header {
my $updated = localtime(time);
return <
World of Warcraft Quest Tracker
World of Warcraft Quest Tracker ($options{side})
The below contains a listing for all known World
of Warcraft quests available to the $options{side}, and was last generated
$updated. It was created
by a Perl script from Morbus Iff that collects quest and zone data from the
Allakhazam World of Warcraft site. Quests
with asterisks next to them have been completed for this particular character.
EVIL_HEREDOC_HEADER_OF_ORMS_BY_GORE
}
sub footer { return ""; }