Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2018
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.87 KB | None | 0 0
  1. ##
  2. ## AHLGOALBOT
  3. ##
  4. use Date::Parse;
  5. use Mojo::DOM;
  6. use Time::Piece;
  7. use Time::HiRes qw( sleep );
  8. use Data::Dumper;
  9. use feature "switch";
  10. use Irssi qw(command_bind signal_add timeout_remove timeout_add);
  11. use JSON;
  12. #use strict;
  13. use warnings;
  14. use constant {
  15. owner => "grateful",
  16. DEBUG => 1,
  17. BOT_OWNER_PASSWORD => "uticacomets",
  18. FOLLOW_PERIOD => 5000,
  19. };
  20.  
  21.  
  22. my $httpref;
  23. my $t;
  24. my $fp;
  25. my $h;
  26. my $Home;
  27. my $Away;
  28. use constant UA => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.26 Safari/537.36";
  29. my $presentgoallist;
  30. my $tag;
  31. my %follow;
  32. my %recentgoal;
  33. my $periodold;
  34.  
  35. # initally owner's mask impossible to match
  36. my $bot_owner = '$@$';
  37.  
  38. sub wget {
  39. my( $url, $extra ) = @_;
  40. my $UA = UA;
  41. return `LD_PRELOAD='' wget -t 3 -T 3 --no-proxy -q -O - '$url' -U '$UA' $extra 2>/dev/null`;
  42. }
  43. sub curlhead {
  44. my $url = shift;
  45. return `LD_PRELOAD='' curl -I '$url' 2>/dev/null`;
  46. }
  47.  
  48. sub lget {
  49. my $extra = $httpref ? "-http.fake-referer '$httpref' -http.referer 2" : "";
  50. $_ = shift;
  51. $_ = `LD_PRELOAD='' links -receive-timeout 3 -unrestartable-receive-timeout 10 $extra -source '$_' 2>/dev/null | gunzip -f 2>/dev/null`;
  52. $_ = "" if( length($_) < 200 && /404|Not Found/i );
  53. return $_;
  54. }
  55.  
  56. sub links {
  57. $_ = shift;
  58. return `LD_PRELOAD='' links -width 400 -receive-timeout 3 -dump '$_' 2>/dev/null`;
  59. }
  60.  
  61.  
  62. sub shorturl{
  63. my $url = shift;
  64. $_ = wget( 'https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyDVHP4V0bz7PZKwdpEitqwD5tlY03z-OYE', "--header 'Content-Type: application/json' --post-data='{\"longUrl\": \"$url\"}'" );
  65. return /"id":\s*"(http.*?)"/ ? $1 : $url;
  66. }
  67.  
  68. our %httpcache;
  69. sub download {
  70. no warnings;
  71. my( $url, $nocache ) = @_;
  72. $url =~ s/'/'"'"'/g;
  73. return lget( $url ) if( $nocache );
  74. my $t = time;
  75. for my $c ( 1 .. 5 ) {
  76. if( $t > $httpcache{$c}{timer} && $httpcache{$c}{url} ) {
  77. $httpcache{$c}{url} = "";
  78. $httpcache{$c}{data} = "";
  79. $httpcache{$c}{timer} = 0;
  80. }
  81. }
  82. for my $c ( 1 .. 5 ) {
  83. if( $httpcache{$c}{url} eq $url ) {
  84. $httpcache{hits}++;
  85. return $httpcache{$c}{data};
  86. }
  87. }
  88. my $tmp = lget( $url );
  89. if( $tmp ) {
  90. $httpcache{index}++;
  91. $httpcache{index} = 1 if( $httpcache{index} > 5 );
  92. $httpcache{$httpcache{index}}{url} = $url;
  93. $httpcache{$httpcache{index}}{data} = $tmp;
  94. $httpcache{$httpcache{index}}{timer} = time + 300;
  95. }
  96. return $tmp;
  97. }
  98.  
  99. sub GetDate {
  100. my( $date, $fmt ) = @_;
  101. $date =~ s/'//g;
  102. my( $ret ) = `date --date='$date' "+$fmt" 2>&1` =~ /(.*)/;
  103. return $ret;
  104. }
  105.  
  106. require Irssi;
  107. Irssi::signal_add("event privmsg", "irssi_pre");
  108.  
  109. sub irssi_pre {
  110. my ($shash, $ircdata, $nick, $mask) = @_;
  111. $ircdata =~ /(.*?) :(.*)/;
  112. %h = ( shash => $shash, nick => $nick, target => $1, text => $2, host => $mask );
  113.  
  114. # don't process if target is not a channel, unless is "identify" private message from (perhaps) an owner
  115. if (!$shash->ischannel($h{target})) {
  116. if ($h{text} eq "identify ".BOT_OWNER_PASSWORD) {
  117. ahldebug("bot owner identified from: ".$h{nick}."!".$h{host});
  118. $bot_owner = $h{host};
  119. $shash->command("^notice ".$h{nick}." you are now identified as my owner");
  120. }
  121. return;
  122. }
  123.  
  124. # for rud0lf's test purposes - work only on freenode/#ahltest
  125. # comment out if you want to run it everywhere
  126. # return if (lc($h{target}) ne "#ahltest" || lc($shash->{tag}) ne "freenode");
  127.  
  128. my $t = ".";
  129.  
  130. return if(
  131. $shash->ignore_check($nick, $mask, $h{target},$h{text}, MSGLEVEL_PUBLIC) ||
  132. $h{text} !~ /${t}\w/
  133. );
  134.  
  135. $h{server} = $shash->{tag};
  136. $h{server_obj} = $shash;
  137. my $channel = $shash->channel_find( $h{target} );
  138. if ( $shash->ischannel( $h{target} ) ) {
  139. if (defined $fp{"$h{target}$h{server}"}) {
  140. return if( $fp{"$h{target}$h{server}"} > time );
  141. }
  142. } else {
  143. if(defined $fp{"priv$h{server}"} ) {
  144. return if( $fp{"priv$h{server}"} > time );
  145. }
  146. $fp{"priv$h{server}"} = time + 1;
  147. $h{target} = $nick;
  148. }
  149. event_privmsg( \%h );
  150. }
  151.  
  152. ##cooldown to prevent flooding.
  153. my $not_until = 0;
  154. use constant COOLDOWN => 3;
  155.  
  156. sub event_privmsg {
  157. my $params = shift;
  158. %h = %$params;
  159. my $noticereply;
  160. my @ret;
  161. my( $target, $text, $scorebot, $goalbot ) = ( $h{target}, $h{text}, $h{scorebot}, $h{goalbot} );
  162. my( $address ) = $h{host};
  163.  
  164. my $t = qr/^\./;
  165. return if( $text !~ $t );
  166.  
  167. return if ($not_until > time());
  168. $not_until = time() + COOLDOWN;
  169.  
  170. foreach( lc( $text ) ) {
  171. if ( /^${t}followahl (\w.*)/ ) {
  172. my $string = $1;
  173.  
  174. # get game id
  175. my $result = get_match_id($string);
  176. if (!defined($result)) {
  177. $h{shash}->command("msg $target $string: Game not found.");
  178. return;
  179. }
  180.  
  181. my %data = %$result;
  182. # list of follows will be stored in hash "$follow" under key "server_tag;channel_name;game_id"
  183. # i.e. "freenode;#ahl;10133789"
  184. my $key = $h{server} . ";" . $target . ";" . $data{gameid};
  185. my $userhost = $h{host};
  186.  
  187. if (defined($follow{$key})) {
  188. if (defined($follow{$key}{users}{$userhost})) {
  189. $h{shash}->command("msg $target You're already following this game. (".$data{shortname}.")");
  190. return;
  191. }
  192. }
  193.  
  194. $follow{$key}{fullname} = $data{fullname};
  195. # don't add periodic info if another user is already watching this game on this server and channel,
  196. # just add the fact that another user is watching it to the hash
  197. if (!scalar(keys %{ $follow{$key}{users} } )) {
  198. $recentgoal{$key} = "-1";
  199. $follow{$key}{shortname} = $data{shortname};
  200. $follow{$key}{tag} = timeout_add(FOLLOW_PERIOD, "FollowAHL", $key);
  201. }
  202. else {
  203. ahldebug("Users already exists.");
  204. }
  205. $follow{$key}{users}{$userhost} = 1;
  206.  
  207. $h{shash}->command("msg $target Now following ".$data{fullname});
  208. $h{shash}->command("msg $target ".$data{radiocast});
  209. FollowAHL($key);
  210. }
  211. if ( /^${t}listahl/ ) {
  212. ahllist(\%h);
  213. }
  214.  
  215. if ( /^${t}unfollowahl (\w.*)/ ) {
  216. my $string = $1;
  217.  
  218. # get game id
  219. my $result = get_match_id($string);
  220. if (!defined($result)) {
  221. $h{shash}->command("msg $target $string: Game not found.");
  222. return;
  223. }
  224.  
  225. my %data = %$result;
  226.  
  227. my $key = $h{server} . ";" . $target . ";" . $data{gameid};
  228. my $userhost = $h{host};
  229.  
  230. if (defined($follow{$key})) {
  231. if (!defined($follow{$key}{users}{$userhost})) {
  232. if ($userhost eq $bot_owner) {
  233. $h{shash}->command("msg $target Bot owner ".$h{nick}." removed game watch ".$follow{$key}{shortname});
  234. timeout_remove($follow{$key}{tag});
  235. delete $follow{$key};
  236. delete $recentgoal{$key};
  237. return;
  238. }
  239. my $isop = 0;
  240. my $chan = $h{shash}->channel_find($target);
  241. if (defined $chan) {
  242. my $nick = $chan->nick_find($h{nick});
  243. if (defined $nick) {
  244. $isop = $nick{op};
  245. }
  246. }
  247. if ($isop) {
  248. $h{shash}->command("msg $target Chanop ".$h{nick}." removed game watch ".$follow{$key}{shortname});
  249. timeout_remove($follow{$key}{tag});
  250. delete $follow{$key};
  251. delete $recentgoal{$key};
  252. return;
  253. }
  254. }
  255. if (defined($follow{$key}{users}{$userhost})) {
  256. if (!$follow{$key}{users}{$userhost}) {
  257. # channel operator and bot owner can remove whole game watch (purge all user list)
  258. $h{shash}->command("msg $target You didn't follow this game.");
  259. return;
  260. }
  261. else {
  262. delete $follow{$key}{users}{$userhost};
  263. if (scalar(keys %{ $follow{$key}{users} } )) {
  264. $h{shash}->command("msg $target No longer following your game, but another user still is. (".$follow{$key}{shortname}.")");
  265. return;
  266.  
  267. }
  268. else {
  269. $h{shash}->command("msg $target Not following ".$follow{$key}{shortname}." any more.");
  270. timeout_remove($follow{$key}{tag});
  271. delete $follow{$key};
  272. delete $recentgoal{$key};
  273. return;
  274. }
  275. }
  276. }
  277. }
  278.  
  279.  
  280. if (defined($follow{$key})) {
  281. $h{shash}->command("msg $target You didn't follow ".$follow{$key}{shortname}." and you have no rights to remove it from someone else.");
  282. }
  283. else {
  284. $h{shash}->command("msg $target You didn't follow ".$data{shortname}.".");
  285. }
  286. }
  287. }
  288. }
  289.  
  290.  
  291. sub FollowAHL {
  292. my $key = shift;
  293. my @goallist;
  294. # ahldebug("FollowAHL...");
  295.  
  296. my ($servertag, $channel, $gameid) = split(/;/, $key);
  297. my $server = Irssi::server_find_tag($servertag);
  298.  
  299. # not connected to server with tag stored in the key - don't go any further
  300. return unless (defined $server);
  301. # not on channel stored in the key - don't proceed
  302. return unless ($server->ischannel($channel));
  303.  
  304. ##$ The below will pull the @goallist, what we will need to compare.
  305.  
  306. my $url = 'https://lscluster.hockeytech.com/game_reports/official-game-report.php?client_code=ahl&game_id=' . $gameid;
  307. my $data = download( $url, 1 );
  308.  
  309. if ($data eq "No such game") {
  310. #something went wrong
  311. ahldebug("Game not found on server, removing timeout (game ID: $gameid full name: ".$follow{$key}{fullname}.")");
  312. timeout_remove($follow{$key}{tag});
  313. delete $follow{$key};
  314. delete $recentgoal{$key};
  315. return;
  316. }
  317. my @period;
  318. my @jsinfolist;
  319. my @goals = ();
  320. my $url2 = "http://cluster.leaguestat.com/lsconsole/json.php?client_code=ahl";
  321. my $data2 = download( $url2 );
  322. my ($jsondata) = ( $data2 =~ /"ID":"$gameid".(.*?)}\s*}\s*,/gs);
  323. my (@jsondata) = ( $jsondata =~ /".*?":"(.*?)"/gs);
  324. foreach ($jsondata[1]) {
  325. my ($Number, $Letter, $Label, $Date, $Att, $Time, $Zone, $Ticket, $GameSummary, $GameReport, $PlayerReport, $TextReport, $Venue, $Status, $ShortStatus, $SmallStatus, $StatusID, $Clock, $Period, $SchedNote, $GameNote, $AID, $Away, $AwayCode, $AwayUrl, $AwayVidUrl, $AwayWebCast, $AwayScore, $AShootOut, $HID, $Home, $HomeCode, $HomeUrl, $HomeVidUrl, $HomeWebCast, $HomeScore, $HShootOut) = (@jsondata);
  326. $HomeUrl =~ s/\\//sg;
  327. $AwayUrl =~ s/\\//sg;
  328. $Home =~ s/\\//gs;
  329. $Away =~ s/\\//gs;
  330. push @jsinfolist, "$Away $AwayScore @ $Home $HomeScore";
  331. my $period = "$Status";
  332. print "@jsinfolist - S $Status | SM $SmallStatus | ID $StatusID | C $Clock | P $Period";
  333. }
  334.  
  335.  
  336. my ($shotstable) = ( $data =~ /SHOTS(.*?)<\/tbody>/s );
  337. my (@shotsonnet) = ( $shotstable =~ /<tr.*?>(.*?)<\/tr>/gs ) if ($shotstable);
  338. my @SOG;
  339. my @SOGT;
  340. foreach (@shotsonnet) {
  341. my (@SOG) = ( /<td.*?>(.*?)<\/td>/gs);
  342. push @SOGT, "$SOG[-1]";
  343. }
  344.  
  345. my ($gameend) = ( $data =~ /Game End/s ); # every "/" inside needs "\"
  346. my ($scoringtable) = ( $data =~ /tSides">(.*?)<\/table>/s );
  347. if (defined $scoringtable) {
  348. my (@goals) = ( $scoringtable =~ /<tr.*?>(.*?)<\/tr>/gs );
  349. my $T1;
  350. my $T2;
  351. foreach (@goals) {
  352. my ($GVH, $GNum, $GPer, $GTeam, $GTime, $GGoal, $GAssists, $GType) = ( /<td.*?>(.*?)<\/td>/gs);
  353. my ($T1, $T2) = $GVH =~ /\d/g; if ($T1 > $T2) { $GVH = "\x02$T1\x02-$T2"; } elsif ($T2 > $T1) { $GVH = "$T1-\x02$T2\x02"; } else { $GVH = "$T1-$T2"; }
  354. push @goallist, "\x02$GTeam $GGoal\x02 $GAssists $GType ($GTime $GPer) [$GVH]";
  355. }
  356. }
  357.  
  358. shift @goallist;
  359. ### used to announce period changes/starting/end game ####
  360. my ($gamestatus) = ( $data =~ /Game Status.*?<\/b><\/td><td valign="top">(.*?)<\/td><\/tr>/s);
  361. if ($gameend) { $gamestatus = "FINAL"; }
  362.  
  363. ### tidy up the goalist
  364.  
  365. s/&nbsp;//gs for @goallist;
  366. tr/a-z/A-Z/ for @goallist;
  367. s/ / /g for @goallist;
  368. ahldebug("goallist: ".join("/",@goallist));
  369.  
  370. my $lastgoal = $recentgoal{$key};
  371. if ($lastgoal < $#goallist) {
  372. for my $i ($#goallist) {
  373. $server->command("msg $channel \x02AHL GOAL\x02: ".$goallist[$i]);
  374. }
  375. $recentgoal{$key} = $#goallist;
  376. }
  377.  
  378.  
  379. if (defined $period eq "In Progress (0:00 remaining in 1st)" && (!$periodold)) {
  380. $server->command("msg $channel \x02AHL Game 1st Period Over!\x02 @jsinfolist");
  381. $periodold = $period;
  382. print "$period";
  383. } elsif (defined $period eq "In Progress (0:00 remaining in 2nd)" && (!$periodold)) {
  384. $server->command("msg $channel \x02AHL Game 2nd Period Over!\x02 @jsinfolist");
  385. $periodold = $period;
  386. }
  387.  
  388. if (defined $gamestatus && $gamestatus eq "FINAL") {
  389. ahldebug("@jsinfolist Final - Timer has been removed.");
  390. $server->command("msg $channel \x02AHL Game has finished!\x02 @jsinfolist Final | SOG " . $SOGT[0] . "-" . $SOGT[1]);
  391. timeout_remove($follow{$key}{tag});
  392. delete $follow{$key};
  393. delete $recentgoal{$key};
  394. }
  395.  
  396. }
  397.  
  398. # return match_id for HomeCode Home AwayCode Away ID and other data or undef if not found
  399. sub get_match_id {
  400. my $tomatch = shift;
  401.  
  402. my $date = GetDate( 'today', '%Y-%m-%d' );
  403. # my $url = "http://www.tanknation.xyz/test.json";
  404. my $url = "http://cluster.leaguestat.com/lsconsole/json.php?client_code=ahl&forcedate=$date";
  405. ahldebug($url);
  406. my $data = download( $url, 1 );
  407. my $GameStatus;
  408. my @gsinfo;
  409. ( $data ) = ( $data =~ /var todayData = '(.*?)'\;/gs );
  410. my ( @games ) = ( $data =~ /Game.*?"\:\{(.*?)\}\}/gs );
  411. foreach (@games) {
  412. my ($ID, $Number, $Letter, $Label, $Date, $Time, $Zone, $Status, $ShortStatus, $SmallStatus, $StatusID, $Clock, $Period, $Away, $AwayCode, $AwayUrl, $AwayScore, $Home, $HomeCode, $HomeUrl, $HomeScore) = ( /"ID"\:"(.*?)".*?Number"\:"(.*?)".*?Letter"\:"(.*?)".*?Label"\:"(.*?)".*?Date"\:"(.*?)".*?ScheduledTime"\:"(.*?)".*?Timezone"\:"(.*?)".*?Status"\:"(.*?)".*?ShortStatus"\:"(.*?)".*?SmallStatus"\:"(.*?)".*?StatusID"\:"(.*?)".*?GameClock"\:"(.*?)".*?"Period"\:"(.*?)".*?Name"\:"(.*?)".*?Code"\:"(.*?)".*?AudioUrl"\:"(.*?)".*?Score"\:"(.*?)".*?Name"\:"(.*?)".*?Code"\:"(.*?)".*?AudioUrl"\:"(.*?)".*?Score"\:"(.*?)"/gs );
  413.  
  414. ### Change this to have both the string to search and the game_id, this'll make things easier later. you can also add in anything else from above if you need it.
  415. push @gsinfo, {game_id => $ID, search_string => "$HomeCode $Home $AwayCode $Away $ID"};
  416. }
  417.  
  418. ### find all the games that matchl, and just get their game ids
  419. my @matched_games = map {$_->{game_id}} grep {$_->{search_string} =~ /$tomatch/i} @gsinfo;
  420.  
  421. ### We'll just get the first game
  422. my $game = $matched_games[0];
  423.  
  424. # return undef (nothing) if $game is empty
  425. return if (!$game);
  426.  
  427. my ($jsondata) = ( $data =~ /"ID":"$game".(.*?)}\s*}\s*/gs);
  428. my (@jsondatalist) = ( $jsondata =~ /".*?":"(.*?)"/gs);
  429. my ($Number, $Letter, $Label, $Date, $Att, $Time, $Zone, $Ticket, $GameSummary, $GameReport, $PlayerReport, $TextReport, $Venue, $Status,
  430. $ShortStatus, $SmallStatus, $StatusID, $Clock, $Period, $SchedNote, $GameNote, $AID, $Away, $AwayCode, $AwayUrl, $AwayVidUrl, $AwayWebCast, $AwayScore,
  431. $AShootOut, $HID, $Home, $HomeCode, $HomeUrl, $HomeVidUrl, $HomeWebCast, $HomeScore, $HShootOut) = (@jsondatalist);
  432. $Date = GetDate( $Date, '%b %e, %Y' );
  433. my $TEAMSTOFOLLOW = "$Away vs $Home - $Time $Zone @ $Venue";
  434. my $shortname = "$Away vs $Home";
  435.  
  436. # ahldebug("TEAMSTOFOLLOW: ".$TEAMSTOFOLLOW);
  437.  
  438. $HomeUrl =~ s/\\//sg;
  439. $AwayUrl =~ s/\\//sg;
  440.  
  441. my $RADIOCAST = "\x02Home Radio:\x02 $HomeUrl | \x02Away Radio:\x02 $AwayUrl ";
  442. my %return = ( gameid => $game, fullname => $TEAMSTOFOLLOW, shortname => $shortname, radiocast => $RADIOCAST);
  443.  
  444. return \%return;
  445. }
  446.  
  447. sub ahldebug {
  448. return unless DEBUG;
  449. my $txt = join(" ", @_);
  450. Irssi::print("[AHL Debug] ".$txt, MSGLEVEL_CLIENTCRAP);
  451. }
  452.  
  453.  
  454. sub ahllist {
  455. my $param = shift;
  456. my %h = %$param;
  457. my $channel_name = $h{target};
  458. my $server = $h{shash};
  459. my $server_tag = $server->{tag};
  460. my $channel = $server->channel_find($channel_name);
  461. my @result = ();
  462. foreach my $key (keys %follow) {
  463. next unless ($key =~ /^${server_tag};${channel_name}.*$/);
  464. my $game_name = $follow{$key}{shortname};
  465. foreach my $user (keys % { $follow{$key}{users} }) {
  466. my $username = $user;
  467. if (defined $channel) {
  468. # ahldebug($channel->{name});
  469. my $snick = $channel->nick_find_mask("*!".$username);
  470. if (defined $snick) {
  471. $username = $snick->{nick};
  472. }
  473. }
  474. push @result, "$game_name by $username";
  475. }
  476. }
  477. for my $i (0..$#result) {
  478. $server->command("msg $channel_name ".$result[$i]);
  479. }
  480. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement