#!/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<html><p>Subj: $2; From: $8; To: $9</p></html>";

                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<html><p>Subj: $4; From: $10; To: $11</p></html>";

                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/<input/xms ) {
        print "User $acc_id logged off\n";
        exit;
    }

    return 1;
}

sub init_browser {

    my $cookies
        = HTTP::Cookies->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/<input/xms ) {
        print
            "\n!WARNING! Account $opt->{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] <optional 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
}