Авторские статьи @ mrim.pl: Написание скриптов, работающих по протоколу MMP

Discussion in 'Статьи' started by Digimortal, 16 Apr 2007.

  1. C!klodoL

    C!klodoL Elder - Старейшина

    Joined:
    5 Jun 2007
    Messages:
    302
    Likes Received:
    208
    Reputations:
    4
    автор статьи выкладывал скрипт смс флудера, его можно найти в поиске, но теперь он не работает
     
  2. Digimortal

    Digimortal Banned

    Joined:
    22 Aug 2006
    Messages:
    471
    Likes Received:
    248
    Reputations:
    189
    модуль Mmpsms

    скачал щас с cpan'a модуль для работы с МАгентом:
    Code:
    http://search.cpan.org/~aau/Net-MRIM/
    обнаружил, что он весьма разросся с того момента, как я его в последний раз видел (но кусочки кода из моей статьи в нем все еще проглядуются +) ).. вобщем, там вроде уже и отправка смс есть.. т.ч. я подумал, что стоит и свой модуль выложить, может, кому пригодится - он в отличие от того, что на cpan'е очень прост и легок, т.к., собственно, только для отправки смс по MMP и служит.. )
    пускай примером к статье будет.. +) вобщем, вот:
    Code:
    package MMPSMS;
    
    $VERSION = '0.1';
    
    =pod
    
    =head1 NAME
    
    MMPSMS - sends sms messages using MMP proto.
    
    =head1 DESCRIPTION
    
    Read about Mail.ru Agent SMS functionality here: 
    http://agent.mail.ru/help/3/1.html
    
    =head1 SYNOPSIS
    
    To construct object and login to mrim-server:
    
     my $mmpsms = MMPSMS->new('[email protected]', 'password');
    
    To add a phone number to contact list:
    
     my $cid = $mmpsms->add_contact('no_spoon', '+79123456789');
    
    To remove a phone number from contact list:
    
     $mmpsms->delete_contact($cid, 'no_spoon', '+79123456789');
    
    To send sms:
    
     $mmpsms->send_sms('no_spoon', 'sms_text_here');
    
    Ping:
    
     $mmpsms->ping();
    
    Disconnecting:
    
     $mmpsms->close();
    
    
    =head1 AUTHOR
    
    Digimortal
    
    =head1 COPYRIGHT
    
    Copyright (c) 2007 Digimortal. 0x48k Crew.
    
    =cut
    
    
    
    use IO::Socket::INET;
    
    use constant {
    
    	CS_MAGIC			=> 0xDEADBEEF,
    	PROTO_VERSION			=> 0x10008,
    
    	MRIM_CS_HELLO 			=> 0x1001,
    	MRIM_CS_HELLO_ACK 		=> 0x1002,
    
    	MRIM_CS_LOGIN2      		=> 0x1038,
    	MRIM_CS_LOGIN_ACK 		=> 0x1004,
    	MRIM_CS_LOGIN_REJ 		=> 0x1005,
    	MRIM_CS_LOGOUT			=> 0x1013,
    
    	MRIM_CS_PING 			=> 0x1006,
    
    	MRIM_CS_USER_STATUS		=> 0x100f,
    	    STATUS_OFFLINE	 	=> 0,
    
    	MRIM_CS_ADD_CONTACT 		=> 0x1019,
      	    CONTACT_FLAG_REMOVED	=> 1,
    	    CONTACT_FLAG_SMS		=> 0x100000,
    
     	MRIM_CS_ADD_CONTACT_ACK		=> 0x101A,
    	    CONTACT_OPER_SUCCESS	=> 0,
    	    CONTACT_OPER_ERROR 		=> 1,
    	    CONTACT_OPER_INTERR 	=> 2,
    	    CONTACT_OPER_INVALID_INFO 	=> 4,
    
     	MRIM_CS_MODIFY_CONTACT		=> 0x101B,
     	MRIM_CS_MODIFY_CONTACT_ACK	=> 0x101C,
    
     	MRIM_CS_CONTACT_LIST2		=> 0x1037,
    
    	MRIM_CS_SMS 			=> 0x1039,
    	MRIM_CS_SMS_ACK 		=> 0x1040,
    
    	MRIM_UA 			=> 'MRA 5.0 (build 2094);',
    
    	MRIM_ADDR			=> 'mrim.mail.ru',
    	MRIM_PORT			=> 2042
    };
    
    $|++;
    
    
    	############################
    	## Основные методы класса ##
    	############################
    
    
    sub new {
    
    	my ($pkgname, $login, $password, $debug) = @_;
    
    	my $self = {};
    
    	$self->{_seq_real} = 1;
    	$self->{_debug} = $debug;
    
    	bless $self;
    
    	## получаем хост и порт:
    
    	my $sock1 = IO::Socket::INET->new(
    
    		PeerAddr  => MRIM_ADDR,
    		PeerPort  => MRIM_PORT,
    		PeerProto => 'tcp', 
    		TimeOut   => 5 );
    
    	if (!defined $sock1) {
    
    		_debug($self, 'error: can\'t connect to mrim.mail.ru');
    		return 0;
    	}
    
    	$sock1->recv(my $answ, 18);
    	close $sock1;
    	chomp $answ;
    
       	my ($host, $port) = split /:/,  $answ;	
    
    	## коннектимся на полученный хост:
    
    	$self->{_sock} = IO::Socket::INET->new(
    
      		PeerAddr  => $host,
    		PeerPort  => $port,
     	 	PeerProto => 'tcp',
    		TimeOut   => 5 );
    
    	if (!defined $self->{_sock}) {
    
    		_debug($self, "error: can\'t connect to $host:$port");
    		return 0;
    	}
    
    	## посылаем пакет HELLO:
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_HELLO));
    
    	_recv_packet($self);
    
    	## логинимся:
    
    	my $data = _lps($login) 
    		 . _lps($password) 
    		 . pack('L', STATUS_OFFLINE) 
    		 . _lps(MRIM_UA);
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_LOGIN2, $data));
    	
    	my ($msg, $data_rcv) = _recv_packet($self);
    
    	if ($msg != MRIM_CS_LOGIN_ACK) {
    
    		_debug($self, "auth error: $data_rcv");
    		return 0;
    	}
    	
    	return $self;
    }
    
    
    
    sub send_sms {
    
    	my ($self, $phone, $sms_text) = @_;
    
    	my $data = pack('L', 0) 
    		 . _lps($phone) 
    		 . _lps($sms_text);
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_SMS, $data));
    
    	my ($msg, $data_rcv) = _recv_packet($self);
    
    	return(unpack('L', $data_rcv));
    }
    
    
    
    sub add_contact {
    
    	my ($self, $name, $phone) = @_;
    
    	my $data = pack('L2', CONTACT_FLAG_SMS, 0x67) 
    		 . _lps('phone')
    		 . _lps($name)
    		 . _lps($phone)
    		 . pack('L', 0);
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_ADD_CONTACT, $data));
    	
    	my ($msg, $data_rcv) = _recv_packet($self);
    
    	my ($status, $cid) = unpack('L2', $data_rcv);
    
    	if ($status == CONTACT_OPER_SUCCESS) { return $cid }
    
    	elsif ($status == CONTACT_OPER_ERROR) {
    		_debug($self, 'add_contact error: incorrect contact data'); 
    	}
    	elsif ($status == CONTACT_OPER_INTERR) { 
    		_debug($self, 'add_contact error: internal server error');
    	}
    	elsif ($status == CONTACT_OPER_INVALID_INFO) { 
    		_debug($self, 'add_contact error: incorrect username');
    	}
    
    	return 0;
    }
    
    
    
    sub delete_contact {
    
    	my ($self, $contact_id, $name, $phone) = @_;
    
    	my $flag = (CONTACT_FLAG_SMS | CONTACT_FLAG_REMOVED);
    
    	my $data = pack("L3", $contact_id, $flag, 0x67) 
    		 . _lps('phone') 
    		 . _lps($name) 
    		 . _lps($phone);
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_MODIFY_CONTACT, $data));
    
    	my ($msg, $data_rcv) = _recv_packet($self);
    
    	my $status = unpack('L', $data_rcv);
    
    	if ($status == CONTACT_OPER_SUCCESS) { return 1 }
    
    	elsif ($status == CONTACT_OPER_ERROR) {
    		_debug($self, 'delete_contact error: incorrect contact data'); 
    	}
    	elsif ($status == CONTACT_OPER_INTERR) { 
    		_debug($self, 'delete_contact error: internal server error');
    	}
    	elsif ($status == CONTACT_OPER_INVALID_INFO) { 
    		_debug($self, 'delete_contact error: incorrect username');
    	}
    
    	return 0;
    }
    
    
    
    sub ping {
    
    	my $self = shift;
    
    	$self->{_sock}->send(_make_mrim_packet($self, MRIM_CS_PING));
    
    	_recv_packet($self);
    
    	return 1;
    }
    
    
    
    sub close {
    
    	my $self = shift;
    
    	$self->{_sock}->close;
    
    	return 1;
    }
    
    
    
    	#############################
    	## Приватные методы класса ##
    	#############################
    
    
    ## создание пакета:
    
    sub _make_mrim_packet {
    
    	my ($self, $msg, $data) = @_;
    
    	my $dlen = 0;
    	$dlen = length($data) if $data;
    
    	my $mrim_packet = pack('L5', CS_MAGIC, PROTO_VERSION, 
    				++$self->{_seq_real}, $msg, $dlen) 
    			. pack('L', 0) x 6;
    
    	$mrim_packet .= $data if $data;
    
    	return $mrim_packet;
    }
    
    
    ## LPS
    
    sub _lps { return pack('L', length $_[0]) . $_[0]; }
    
    
    ## получение пакета c текущим значением seq_real:
    
    sub _recv_packet {	
    
    	my ($self) = shift;
    
    	while (1) {
    
    		$self->{_sock}->recv(my $ack, 44);
    
    		my ($magic, $proto, $seq, $msg, $dlen, @other) = unpack('L11', $ack);
    
    		my $data;
    
    		$self->{_sock}->recv($data, $dlen) if $dlen;
    	
    		return($msg, $data) if ($seq == $self->{_seq_real});
    	}
    }
    
    
    ## вывод отладочной информации:
    
    sub _debug {
    
    	my ($self, $msg) = @_;
    
    	print "$msg\n" if $self->{_debug};
    }
    
    
    return 1;
     
    #42 Digimortal, 10 Mar 2008
    Last edited: 13 Mar 2008
  3. Digimortal

    Digimortal Banned

    Joined:
    22 Aug 2006
    Messages:
    471
    Likes Received:
    248
    Reputations:
    189
    использовать примерно так +) :
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use MMPSMS;
    
    
    my $user = '[email protected]';
    my $pass = 'passw00rd';
    
    my $text = 'смско! смско! смско!';
    
    my $name = 'lalala';
    my $phone = '+7998xxxxxxx';
    
    
    
    my $sms = MMPSMS->new($user, $pass, 1);
    
    my $id = $sms->add_contact($name, $phone);
    
    $sms->send_sms($phone, $text);
    
    $sms->delete_contact($id, $name, $phone);
    
    $sms->close();
     
  4. btrfly

    btrfly New Member

    Joined:
    6 Apr 2008
    Messages:
    1
    Likes Received:
    1
    Reputations:
    5
    Кто-нибудь может мне уделить часик и помочь разобраться с протоколом?
    тоже самое,только на плюсах,так как с perl'om не знаком,поэтому и спрашиваю.
    з.ы.
    Если никто по доброте душевной не хочет,
    то с меня символическое вознаграждение размером в 10-20$ :)
    icq 445408977
     
  5. -Hormold-

    -Hormold- Кто, если не ты?

    Joined:
    29 Sep 2007
    Messages:
    418
    Likes Received:
    290
    Reputations:
    44
    Может кто выложить рабочий протокол, желательно на php =)
     
  6. -Hormold-

    -Hormold- Кто, если не ты?

    Joined:
    29 Sep 2007
    Messages:
    418
    Likes Received:
    290
    Reputations:
    44
    http://hormold.ru/index.php?newsid=69
    Вот у меня на сайте, class на php.
     
  7. iluxa77

    iluxa77 New Member

    Joined:
    27 May 2008
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    у когонибудь осталос????? :confused: очень хочеться знать как смс отправить правильно... а то у меня с некоторых акков почемуто неотправляеться :confused:
     
  8. BEGINER

    BEGINER New Member

    Joined:
    16 Aug 2008
    Messages:
    18
    Likes Received:
    1
    Reputations:
    0
    Привет. В перле вообще ничего не понимаю.
    Кто-нибудь знает как заполнить заголовок пакета для М-агента, используя С?
    Получаю адрес и порт сервера, отправляю Нелло и жду ответа, ответа нет, может что делаю не так?
    код:
    SOCKET nMailSocket;
    struct mrim_packet_header_t header;
    char* pheader=(char*)&header;
    char buf[255];

    header.magic=PROTO_VERSION;
    header.proto=MRIM_CS_HELLO;
    header.seq=1;
    header.msg=1;
    header.dlen=0;
    header.from=0;
    header.fromport=0;

    send(nMailSocket, pheader, (int)sizeof(struct mrim_packet_header_t), 0);
    memset(buf, 0, 255);
    recv(nMailSocket, (LPSTR)buf, 48, 0);
    cout<<buf<<endl;