Skip to content
Browse files

added autoupdater

  • Loading branch information...
1 parent dca39f6 commit 430e6251e1a477f2c7467febf23afb7302ca38e5 @apocalypse committed
Showing with 281 additions and 16 deletions.
  1. +224 −0 dota_autoupdate.pl
  2. +57 −16 getdota.pl
View
224 dota_autoupdate.pl
@@ -0,0 +1,224 @@
+#!/usr/bin/perl
+use strict; use warnings;
+
+# Load our modules
+use LWP::UserAgent;
+use HTML::TreeBuilder::XPath;
+use Data::Dumper;
+use IO::Socket;
+use File::Spec;
+
+# ghost@wc3:~$ crontab -l
+# # m h dom mon dow command
+# 0 * * * * /home/ghost/dota_autoupdate.pl
+
+# Set some config variables
+my $dota_mainpage = 'http://www.getdota.com/map_archive/map/last/lang/en';
+my $dota_getmap = 'http://www.getdota.com/app/getmap/';
+my $ghost_dir = '/home/ghost/GHostOne';
+my $ghost_host = 'localhost';
+my $ghost_port = 6969;
+my $ghost_mapcfg = 'dota.cfg';
+my $debug = 1;
+
+# Set some global variables
+my $ua = LWP::UserAgent->new;
+
+# Go off and do it's stuff!
+main();
+
+# all done!
+exit;
+
+sub main {
+ # okay, first of all we need to get the current version
+ my $dota_current = get_currentversion();
+
+ if ( $debug ) {
+ print "Current DotA file: $dota_current\n";
+ }
+
+ # Okay, check the website!
+ my $dota_data = get_webdata();
+
+ if ( $debug ) {
+ print "Website DotA file: $dota_data->{'file_name'}\n";
+ }
+
+ # Do we need to update?
+ if ( $dota_current ne $dota_data->{'file_name'} ) {
+ update_dota( $dota_data );
+ }
+
+ return;
+}
+
+sub get_currentversion {
+ # Look in the GHost folder for the dota stuff
+ my $file = File::Spec->catfile( $ghost_dir, 'mapcfgs', $ghost_mapcfg );
+ if ( -e $file ) {
+ open( my $fh, '<', $file ) or die "Unable to open $file: $!";
+ my @contents = <$fh>;
+ close( $fh ) or die "Unable to close $file: $!";
+
+ # parse the ghost dota.cfg file for dota filename
+ return parse_ghostcfg( \@contents );
+ } else {
+ die "Could not find $file on the system";
+ }
+}
+
+sub parse_ghostcfg {
+ my $contents = shift;
+
+# ghost@wc3:~/GHostOne/mapcfgs$ cat dota.cfg
+# map_path = Maps\Download\DotA Allstars v6.66b.w3x
+# map_type = dota
+# map_matchmakingcategory = dota_elo
+# map_localpath = DotA Allstars v6.66b.w3x
+# map_defaulthcl =
+# map_loadingame = 1
+
+ # I should use a proper INI-style loader, but blah!
+ foreach my $l ( @$contents ) {
+ if ( $l =~ /^map_localpath\s+\=\s+(.+)$/ ) {
+ return $1;
+ }
+ }
+
+ # Couldn't find it!
+ die "Unable to find 'map_localpath' in $ghost_mapcfg file!";
+}
+
+sub get_webdata {
+ # Get the website!
+ my $response = $ua->get( $dota_mainpage );
+ if ( ! $response->is_success ) {
+ die "Failed to GET: " . $response->status_line;
+ }
+
+ # Get some misc data from the content
+ my( $map_id, $map_name );
+ my $tree = HTML::TreeBuilder::XPath->new_from_content( $response->content );
+
+ # <input type="hidden" name="map_id" value="249" id="input_map_id1"/>
+ my @nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_map_id1"]' );
+ if ( defined $nodes[0] ) {
+ $map_id = $nodes[0]->attr( 'value' );
+ } else {
+ die "Unable to get map_id";
+ }
+
+ # <input type="hidden" name="file_name" value="DotA Allstars v6.66b.w3x" id="input_file_name1"/>
+ @nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_file_name1"]' );
+ if ( defined $nodes[0] ) {
+ $map_name = $nodes[0]->attr( 'value' );
+ } else {
+ die "Unable to get file_name";
+ }
+
+ # get the map location!
+ my %dota_data = (
+ 'mirror_id' => 0, # <input type="hidden" name="mirror_id" value="0" id="input_mirror1"/>
+ 'mirror_nr' => 2, # selects the latest map
+ 'language' => 'en', # <input type="hidden" name="language" value="en" id="input_language1"/>
+ 'language_id' => 2, # <input type="hidden" name="language_id" value="2" id="input_language_id1"/>
+ 'map_id' => $map_id,
+ 'as_zip' => 0, # <input type="checkbox" name="as_zip1" value="1" id="as_zip1"/> # why is it 1 in the HTML when 0 is what we want?
+ 'file_name' => $map_name,
+ );
+
+ # Return the data!
+ return \%dota_data;
+}
+
+sub update_dota {
+ my $data = shift;
+
+ if ( $debug ) {
+ print "Executing DotA update!\n";
+ }
+
+ # mirror it!
+ mirror_dota( $data );
+
+ # Okay, we need to update the dota.cfg file
+ update_dotacfg( $data->{'file_name'} );
+
+ # Tell GHostOne to update the cfg + send announcement
+ update_ghost( $data->{'file_name'} );
+
+ return;
+}
+
+sub update_dotacfg {
+ my $data = shift;
+
+ if ( $debug ) {
+ print "Updating GHostOne $ghost_mapcfg file!\n";
+ }
+
+ # Construct the data
+ my $contents = <<"END";
+map_path = Maps\\Download\\$data
+map_type = dota
+map_matchmakingcategory = dota_elo
+map_localpath = $data
+map_defaulthcl =
+map_loadingame = 1
+END
+
+ if ( $debug ) {
+ print "New GHostOne $ghost_mapcfg contents: \n$contents\n";
+ }
+
+ # Okay, overwrite the dotacfg
+ my $file = File::Spec->catfile( $ghost_dir, 'mapcfgs', $ghost_mapcfg );
+ open( my $fh, '>', $file ) or die "Unable to open $file: $!";
+ print $fh $contents;
+ close( $fh ) or die "Unable to close $file: $!";
+
+ return;
+}
+
+sub update_ghost {
+ my $data = shift;
+
+ if ( $debug ) {
+ print "Telling GHostOne to reload $ghost_mapcfg!\n";
+ }
+
+ my $sock = IO::Socket::INET->new( Proto => 'udp', PeerPort => $ghost_port, PeerAddr => $ghost_host ) or die "Could not create socket: $!\n";
+ $sock->send( "load $ghost_mapcfg" ) or die "Send error: $!\n";
+
+ if ( $debug ) {
+ print "Telling GHostOne to send the announcement!\n";
+ }
+
+ $sock->send( "say New version of DotA loaded, time to own some n00bs! ( $data )" ) or die "Send error: $!";
+
+ return;
+}
+
+sub mirror_dota {
+ my $data = shift;
+
+ # Send the request to the website for the mirror link
+ my $response = $ua->post( $dota_getmap, $data );
+ if ( ! $response->is_success ) {
+ die "Failed to POST: " . $response->status_line;
+ }
+
+ if ( $debug ) {
+ print "Mirroring the latest DotA map from ( " . $response->content . " )!\n";
+ }
+
+ # Okay, mirror the file!
+ my $localpath = File::Spec->catfile( $ghost_dir, 'maps', $data->{'file_name'} );
+ my $response2 = $ua->mirror( $response->content, $localpath );
+ if ( ! $response2->is_success ) {
+ die "Failed to mirror: " . $response2->status_line;
+ }
+
+ return;
+}
View
73 getdota.pl
@@ -7,19 +7,19 @@
use Data::Dumper;
# Set some variables we need to control the fetcher
-my $dota_mainpage = 'http://www.getdota.com';
+my $dota_mainpage = 'http://www.getdota.com/map_archive/map/last/lang/en';
my $dota_getmap = 'http://www.getdota.com/app/getmap/';
# get the misc data we need to request the map!
my $ua = LWP::UserAgent->new;
-#my $response = $ua->get( $dota_mainpage );
-#if ( ! $response->is_success ) {
-# die "Failed to GET: " . $response->status_line;
-#}
+my $response = $ua->get( $dota_mainpage );
+if ( ! $response->is_success ) {
+ die "Failed to GET: " . $response->status_line;
+}
# Get some misc data from the content
-my $tree = HTML::TreeBuilder::XPath->new_from_file( 'getdota.htm' );
-#my $tree = HTML::TreeBuilder::XPath->new_from_content( $response->content );
+#my $tree = HTML::TreeBuilder::XPath->new_from_file( 'getdota.htm' );
+my $tree = HTML::TreeBuilder::XPath->new_from_content( $response->content );
# TODO this works fine, but I worry for the day it "finds" the old map...
# <div class="header">Latest Map: <span class="version">6.65</span></div>
@@ -28,32 +28,73 @@
my $dota_ver = ( $nodes[0]->content_list )[0];
print "Dota Version: $dota_ver\n";
-exit;
-
+#exit;
-@nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_map_id2"]' );
+# <input type="hidden" name="map_id" value="249" id="input_map_id1"/>
+@nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_map_id1"]' );
my $map_id = $nodes[0]->attr( 'value' );
-@nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_file_name2"]' );
+# <input type="hidden" name="file_name" value="DotA Allstars v6.66b.w3x" id="input_file_name1"/>
+@nodes = $tree->findnodes( '/html/body//table[@class="tbl-downloads"]//input[@id="input_file_name1"]' );
my $map_name = $nodes[0]->attr( 'value' );
# get the map location!
my %dota_data = (
- 'mirror_id' => 0, # selects the random mirror
+ 'mirror_id' => 0, # <input type="hidden" name="mirror_id" value="0" id="input_mirror1"/>
'mirror_nr' => 2, # selects the latest map
- 'language' => 'en', # <input type="hidden" name="language" value="en" id="input_language2"/>
- 'language_id' => 2, # <input type="hidden" name="language_id" value="2" id="input_language_id2"/>
+ 'language' => 'en', # <input type="hidden" name="language" value="en" id="input_language1"/>
+ 'language_id' => 2, # <input type="hidden" name="language_id" value="2" id="input_language_id1"/>
'map_id' => $map_id,
- 'as_zip' => 0, # <input type="checkbox" name="as_zip2" value="1" id="as_zip2"/> # why is it 1 in the HTML when 0 is what we want?
+ 'as_zip' => 0, # <input type="checkbox" name="as_zip1" value="1" id="as_zip1"/> # why is it 1 in the HTML when 0 is what we want?
'file_name' => $map_name,
);
print Dumper( \%dota_data );
-my $response = $ua->post( $dota_getmap, \%dota_data );
+$response = $ua->post( $dota_getmap, \%dota_data );
if ( $response->is_success ) {
print $response->content, "\n";
} else {
die "Failed to POST: " . $response->status_line;
}
+
+
+
+
+
+
+# After all this is done, send to GHostOne to load dota!
+# ghost@wc3:~$ echo -n "load dota" | nc -u -v -v 127.0.0.1 6969
+#
+#[Mon Feb 1 16:03:05 2010] [UDPCMDSOCK] Relaying cmd [!load dota] to server [uswest.battle.net]
+#[Mon Feb 1 16:03:05 2010] [WSPR: USWest] [the_ap0calypse] !load dota
+#[Mon Feb 1 16:03:05 2010] [BNET: USWest] admin [the_ap0calypse] sent command [!load dota]
+#[Mon Feb 1 16:03:05 2010] [QUE: USWest] /w the_ap0calypse Loading config file [mapcfgs/dota.cfg].
+#[Mon Feb 1 16:03:05 2010] [CONFIG] loading file [mapcfgs/dota.cfg]
+#[Mon Feb 1 16:03:05 2010] [MAP] loading MPQ file [maps/DotA Allstars v6.66b.w3x]
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_size = 176 69 103 0
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_info = 193 148 215 8
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_crc = 155 89 252 206
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_sha1 = 157 115 111 121 18 48 195 98 249 148 244 211 41 156 154 240 196 166 181 216
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_width = 118 0
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_height = 120 0
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_numplayers = 10
+#[Mon Feb 1 16:03:05 2010] [MAP] calculated map_numteams = 2
+#[Mon Feb 1 16:03:05 2010] [MAP] found 10 slots
+#[Mon Feb 1 16:03:05 2010] [ERROR: USWest] That user is not logged on.
+
+# echo -n "say DotA 6.66b Loaded, yay" | nc -u -v -v 127.0.0.1 6969
+#
+#[Mon Feb 1 16:06:11 2010] [UDPCMDSOCK] Relaying cmd [!say DotA 6.66b Loaded, yay] to server [uswest.battle.net]
+#[Mon Feb 1 16:06:11 2010] [WSPR: USWest] [the_ap0calypse] !say DotA 6.66b Loaded, yay
+#[Mon Feb 1 16:06:11 2010] [BNET: USWest] admin [the_ap0calypse] sent command [!say DotA 6.66b Loaded, yay]
+#[Mon Feb 1 16:06:11 2010] [QUE: USWest] DotA 6.66b Loaded, yay
+
+
+# Recipe 17.5 of the Perl Cookbook is handy:
+
+# use IO::Socket;
+# use strict;
+# my $sock = IO::Socket::INET->new( Proto => 'udp', PeerPort => 5000, PeerAddr => 'hostname', ) or die "Could not create socket: $!\n";
+# $sock->send('a file to have your advice') or die "Send error: $!\n";

0 comments on commit 430e625

Please sign in to comment.
Something went wrong with that request. Please try again.