2004年09月01日

現在CPANからDownload出来るNet::MSNには物足りない部分があったのでパッチを作ってみた。
バージョン1.22のMSN.pmを対象としています。
ちなみにこのモジュールの詳細な解析をしたわけでもMSNメッセンジャーのプロトコルに詳しいわけでもないので
不正確な事を書いているかもしれません。と言ってる時点で不正確ですな。


*** MSN_orig.pm 2004-08-27 15:16:48.000000000 +0900
--- MSN.pm 2004-09-01 04:58:47.408143656 +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: \"",
***************
*** 617,623 ****
} elsif ($cmd eq 'BYE') {
my ($chandle) = @data;
$self->_disconnect_SB($this_self);
!
if ($self->if_callback_exists('on_bye')) {
&{$self->{Callback}->{on_bye}}($chandle);
}
--- 617,628 ----
} elsif ($cmd eq 'BYE') {
my ($chandle) = @data;
$self->_disconnect_SB($this_self);
! if ($self->if_callback_exists('on_bye_idle') && defined $data[1]) {
! &{$self->{Callback}->{on_bye_idle}}($chandle);
! }
! if ($self->if_callback_exists('on_bye_win') && ! defined $data[1]) {
! &{$self->{Callback}->{on_bye_win}}($chandle);
! }
if ($self->if_callback_exists('on_bye')) {
&{$self->{Callback}->{on_bye}}($chandle);
}
***************
*** 638,643 ****
--- 643,653 ----
if ($self->if_callback_exists('on_answer')) {
&{$self->{Callback}->{on_answer}}($this_self, @data);
}
+ } elsif ($cmd eq 'IRO') {
+ #Socket Open Event
+ if ($self->if_callback_exists('on_iro')) {
+ &{$self->{Callback}->{on_iro}}($this_self, $data[3], $data[4]);
+ }
} elsif ($cmd eq 'MSG') {
my ($chandle, $friendly, $length) = @data;
my ($msg, $response) = ();

前回のサインインが出来ない問題の修正も含んでおきました。
on_connectハンドラを呼び出す前にサインインするメッセージを送っています。
そうしておけばon_connectの中でスクリーンネーム変更や状態変更が行なえるようになって使い勝手がよくなるからです。
作成者の思想が分からんので、これがいいのかは分かりませんが。

あとは、ソケットを開いた時のイベントもハンドリング出来るようにしています。
on_iroハンドラを設定しておけば

sub on_iro {
my ($sb, $chandle, $friendly) = @_;

$sb->sendmsg("Open Window");
}


な感じでチャットウインドウを開いた瞬間にメッセージを送りつけることが出来ます。
正確には相手とのソケットを開いた時に発生するイベントのようなので
idleでソケットが閉じられた後に再接続処理をした時にも、このイベントが呼び出されちゃいます。

ソケットが閉じられた時にはon_byeイベントハンドラが呼び出されるのですが
ウインドウを閉じたのか、idleで閉じられちゃったのかの判断がつきません。
そこでon_bye_idleとon_bye_winというハンドラを新たに作りました。
それぞれの使い方はon_byeと同じです。
違いは_idleはidleによってソケットが閉じられた時に呼ばれて
_winはチャットウインドウが閉じられた時に呼ばれます。

on_byeもあって、ごちゃごちゃしますが互換性も考えてハンドラ量産しました。

on_iroとon_bye_winをうまく使って、チャットウインドウの状態を把握しておくのが良いと思われます。
先の人口無脳エージェントは、この手法を使っています。
自分の環境では意外とうまく動いていてくれます。

他にも相手が文字入力をする度に空データが送られているので、それを補足する事も出来るのですが
これ以上ハンドラ増えるのもアレだし、需要がなさそうなので放置してみたり。
もっと他にも色々機能追加は出来るみたい。


本来なら開発者にパッチ送ってみたりネゴシエーションしなきゃいけないんだろうけど
そこまでやるのもアレゲなので有用だと思ってくれた方がネゴしてくれる事を祈ってみたり。
実はもっと良い改良が加えられてたりするかもですが。

しっかし暫くperlやらんうちに状況が随分と変わっているようで。

Posted by Yappo at 2004年09月01日 05:19 | TrackBack | Perl
Comments
Post a comment









Remember personal info?






コメントを投稿する前に↓の場所にnospamと入力してください。