#!/usr/bin/perl
#===============================================================================
#
#         FILE:  dc-msg-dload.pl
#
#        USAGE:  ./dc-msg-dload.pl -l 'game_login' -p 'game_password'
#                -t account_type -o logfile_name -d mail_directory
#
#  DESCRIPTION:  Выгрузка почты из коммуникатора. Выгружает "Входящие" и
#                "Отправленные" с сохранением в виде отдельных html-файлов
#                в папках "inbox" и "outbox" соответственно.
#                Папки для сохранения необходимо создать вручную.
#
#      OPTIONS:  -l : логин в игре; -p : игровой пароль; -t : тип аккаунта (www
#                для бесплатных или не указывать для платных); -o : имя
#                лог-файла, в который буду записаны данные загруженных писем;
#                -d - родительский каталог для загрузки писем (внутри него
#                должны быть созданы каталоги inbox и outbox)
#
# REQUIREMENTS:  Perl 5.8.8 or highest
#       AUTHOR:  b00
#      VERSION:  1.0
#===============================================================================
#
use strict;
use warnings;
require 5.008_008;
use utf8;
use LWP::UserAgent;
use HTTP::Cookies;
use Getopt::Std;

### set options ###
my %option = (
    'o' => './LOG.log',
    'd' => './messages',
    't' => q{},
);
getopts( 'l:p:t:o:d:h', \%option );
die usage(), "\n" if ( $option{h} || !$option{l} );

### main ###
my $browser = init_browser();

my $acc_id = game_login( \%option, $browser );

get_game_messages( \%option, $browser, $acc_id );

game_logout( \%option, $browser, $acc_id );

### SUB ###
sub get_game_messages {
    my ( $opt, $browser, $acc_id ) = @_;

    my $response = $browser->get(
        'http://' . $opt->{t} . '.the-game.ru/communicator/' . $acc_id );
    die "$response->status_line\n" if !$response->is_success;

    my $log_fh;
    open( $log_fh, '>:encoding(UTF-8)', $opt->{o} )
        or die "Can't open logfile $opt->{o} : $!\n";
    print $log_fh "DD.MM-hh.mm(turn)_from_to_subject\n\n";

    my $src = $response->decoded_content;

    while ($src) {
        my $tmp;
        my $message_type;
        my $tail;

        if ($src =~ m/var\sAllMessages\s=\s\{x(\d{1,3}):(\d),m\d{1,3}:\[/xms )
        {
            $tail = $tmp = $';
            $message_type = "$1:$2";

            if ( $tail =~ m/x(\d{1,3}):(\d),m\d{1,3}:\[/xms ) {
                $tmp = $`;
            }
        }

        while ( $tmp
            =~ m/\{r:(\d),s:'(.*?)',d:'(\d{2})-(\d{2})\s(\d{2}):(\d{2})',i:'(\d{1,10})',t:\d+?,f:'(.*?)',o:'(.*?)',h:\d,toString:TS,c:\d,m:(\d{3,5}?),x:0,y:0,pid:\d{1,6}?\}/gcxms
            )
        {

            if ( $message_type eq '100:1' ) {
                my $out_msg_fh;
                open( $out_msg_fh, '>:encoding(UTF-8)',
                    "$opt->{d}/inbox/$4.$3-$5.$6($8).html" )
                    or die "Can't open outfile : $!\n";

                $response
                    = $browser->get(
                    "http://$opt->{t}.the-game.ru/blackframes/comm_browse_msg/on/$7"
                    );

                print $out_msg_fh $response->decoded_content,
                    "\n\n

Subj: $2; From: $8; To: $9

"; close($out_msg_fh) or die "Can't close uotfile : $!\n"; print $log_fh "$4.$3-$5.$6($10)_$8_$9_$2\n"; } elsif ( $message_type eq '102:0' ) { my $out_msg_fh; open( $out_msg_fh, '>:encoding(UTF-8)', "$opt->{d}/outbox/$4.$3-$5.$6($8).html" ) or die "Can't open outfile : $!\n"; $response = $browser->get( "http://$opt->{t}.the-game.ru/blackframes/comm_browse_msg/on/$7" ); print $out_msg_fh $response->decoded_content, "\n\n

Subj: $4; From: $10; To: $11

"; close($out_msg_fh) or die "Can't close uotfile : $!\n"; print $log_fh "$4.$3-$5.$6($10)_$8_$9_$2\n"; } } last if $tmp =~ m/var\sMessages\s=/xms; $src = $tail; } close($log_fh) or die "Can't close logfile $opt->{o} : $!\n"; return 1; } sub game_logout { my ( $opt, $browser, $acc_id ) = @_; my $response = $browser->get("http://$opt->{t}.the-game.ru/logoff/"); if ( $response->decoded_content =~ m/new( 'file' => './cookies.lwp', 'autosave' => 0 ); my $browser = LWP::UserAgent->new( 'agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15)', 'cookie_jar' => $cookies, 'requests_redirectable' => [ 'GET', 'POST' ] ); $browser->default_header( 'Accept' => 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1', 'Accept-Charset' => 'utf-8; *;q=0.1', 'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3', 'Accept-Encoding' => 'deflate, gzip, x-gzip, identity, *;q=0', ); #$browser->proxy([qw(http https)], 'http://127.0.0.1:50000'); return $browser; } sub game_login { my ( $opt, $browser ) = @_; my $acc_id; my $response = $browser->post( 'http://www.the-game.ru/overview/', [ 'action' => 'login', 'login' => $opt->{l}, 'pwd' => $opt->{p}, ] ); if ( $response->is_success ) { print "Ok\n" } if ( $response->decoded_content =~ m/{l}: invalid user name and/or password. Please check this manually.\n"; exit; } if ( $response->decoded_content =~ m/var\sPlayerId=(\d{6});/xms ) { $acc_id = $1; print "Logged us ID: $acc_id\n"; return $acc_id; } } sub usage { return <<'END_USAGE'; Usage: dc-msg-dload.pl [required options] Required options: -l : game login -p : game password -t : game account type (set 'www' for free or blank for paid account) Optional options: -o : output logfile name (default is 'LOG.log') -d : messages output directiry name (default is 'messages') -h : show this help and exit Example: dc-msg-dload.pl -l 'my_login' -p 'my_password' -t www -o LOG.log -d DC_mail WARNING: before running the script to create a directory to retrieve messages (-d opt.) from the two sub-directories (inbox & outbox) END_USAGE }