2007年07月15日(日)

Patch for Net::MSN 1.22

インターネットに関するりばにしの記事

数年前から Perl で Windows Live Messenger 用の bot をちょこちょこ作っています.

CPAN の Net::MSN というモジュールをベースに作っているのですが,接続処理に問題があって使いにくいのと,メンバーのステータス変更イベントを拾えないのとで,パッチを当てて使っています.もちろん,前のエントリーの bot プログラムでも使ってます.

接続処理に問題があって使いにくい件は,こちらこちらで紹介されているのと同じように対応.これで接続できるようになるし,接続時に名前をいじることも可能になる.この修正は,草の根的なパッチではなく,本家にも反映されるべきだと思うが・・・.

次に,メンバーのステータス変更イベントを拾えない件は,自前のサービス mmrss の実現のために必要不可欠だったので入れてみた.この修正により,メンバーの Screen Name (名前)が変更されたり,ステータス(オンラインとか取り込み中)が変更されたときに,クライアントプログラムの on_status というイベントとして拾うことができるようになります.

というわけで,そのパッチを思い切って公開してみることにする.

まずはモジュールそのものへのパッチ.

*** MSN.pm.1.22	2003-10-30 07:21:48.000000000 +0900
--- MSN.pm	2007-07-14 16:54:44.000000000 +0900
***************
*** 549,558 ****
} else {
$self->{'Handle'} = $data[2];
$self->{'ScreenName'} = $self->normalize($data[3]);
&{$self->{Callback}->{on_connect}}
if ($self->if_callback_exists('on_connect'));
- 	$this_self->send('CHG', 'NLN');
- 	$this_self->send('SYN', '0');
}
} else {
die "Unsupported authentication method: \"",
--- 549,558 ----
} else {
$self->{'Handle'} = $data[2];
$self->{'ScreenName'} = $self->normalize($data[3]);
+ 	$this_self->send('SYN', '0');
+ 	$this_self->send('CHG', 'NLN');
&{$self->{Callback}->{on_connect}}
if ($self->if_callback_exists('on_connect'));
}
} else {
die "Unsupported authentication method: \"",
***************
*** 668,677 ****
--- 668,685 ----
$self->buddyupdate($username, $fname, $status);
} elsif ($cmd eq 'NLN') {
my ($status, $username, $fname) = @data;
+     my $last_status = $self->{Buddies}->{$username}->{StatusCode};
$self->buddyupdate($username, $fname, $status);
+     if ($self->if_callback_exists('on_status')) {
+       &{$self->{Callback}->{on_status}}($this_self, $username, $fname, $status, $last_status);
+     }
} elsif ($cmd eq 'FLN') {
my ($username) = @data;
+     my $last_status = $self->{Buddies}->{$username}->{StatusCode};
$self->buddyupdate($username, undef, $cmd);
+     if ($self->if_callback_exists('on_status')) {
+       &{$self->{Callback}->{on_status}}($this_self, $username, undef, $cmd, $last_status);
+     }
} elsif ($cmd =~ /^[0-9]+$/) {
if (defined $this_self->{PendingCall} &&
$this_self->{PendingCall} == 1) {

次にモジュールについてくる client.pl へのパッチ.この例では,オフラインだったメンバーがサインインしてきたときに,話しかけることができます.あとはお好きなように改造してください(笑).

*** client.pl.1.22	2007-07-14 17:33:34.000000000 +0900
--- client.pl	2007-07-14 17:34:03.000000000 +0900
***************
*** 127,133 ****
}

sub on_status {
!   # FIXME
}

sub on_message {
--- 127,136 ----
}

sub on_status {
!   my ($sb, $chandle, $friendly, $status, $last_status) = @_;
!   if ($status ne 'FLN' && $last_status eq 'FLN') {
!     $client->sendmsg($chandle, 'Hi! '. $friendly. '!');
!   }
}

sub on_message {

とまぁこんな感じ.本家の人に連絡してみようかなぁ.

2007年07月15日17時54分 | Permalink
Trackback URL
Comment Form