diff -urN tiarra-20040418/ChangeLog tiarra-20040508/ChangeLog --- tiarra-20040418/ChangeLog 2004-04-18 16:45:56.000000000 +0900 +++ tiarra-20040508/ChangeLog 2004-05-08 17:15:56.000000000 +0900 @@ -1,3 +1,40 @@ +2004-05-08 Topia + + * HACKING: + - typo を修正した。 + - IrcIO::Server->remark に isupport と uid を追加した。 + - ChannelInfo->remark に creation-time を追加した。 + + * main/Multicast.pm: + - $server_sent, $client_sent: RPL_CREATIONTIME へ対応した。 + - $client_sent: admin コマンドを追加した。 + + * main/NumericReply.pm: + - RPL_BOUNCE を RPL_REDIR に変更。 RPL_BOUNCE はエイリアスとして + そのまま残すようにした。 + - RPL_CREATIONTIME を追加した。 + - RPL_TOPICWHOTIME を RPL_TOPIC_WHO_TIME に変更した。 + RPL_TOPICWHOTIME はエイリアスとしてそのまま残すようにした。 + - irc2.11 なものをいくつか追加した。 + + RPL_HELLO(020) + + RPL_YOURID(042) + + RPL_SAVENICK(043) + + RPL_REOPLIST(344) + + RPL_ENDOFREOPLIST(345) + + * main/IrcIO/Server.pm: + - RPL_{CREATIONTIME,ISUPPORT,YOURID} に対応した。 + (_receive_while_logging_in): + - RPL_HELLO 対策を追加した。 + (modify_nick): + - 第二引数で nicklen を指定できるようにした。 + (_set_to_next_nick): + - ISUPPORT に NICKLEN が含まれていれば、それを使うようにした。 + + * module/Client/Cache.pm: + (_send_mode_cache): + - creation-time が存在すれば、それも返すようにした。 + 2004-04-18 Topia * HACKING: @@ -1586,7 +1623,7 @@ * これ以前のログは書いていません。 -# Id: $Id: ChangeLog,v 1.146 2004/04/18 07:44:46 topia Exp $ +# Id: $Id: ChangeLog,v 1.147 2004/05/08 08:11:30 topia Exp $ # Author: $Author: topia $ -# Date: $Date: 2004/04/18 07:44:46 $ -# Revision: $Revision: 1.146 $ +# Date: $Date: 2004/05/08 08:11:30 $ +# Revision: $Revision: 1.147 $ diff -urN tiarra-20040418/HACKING tiarra-20040508/HACKING --- tiarra-20040418/HACKING 2004-04-18 16:45:56.000000000 +0900 +++ tiarra-20040508/HACKING 2004-05-08 17:15:56.000000000 +0900 @@ -49,7 +49,7 @@ - BulletinBoard(main/BulletinBoard.pm) ここで紹介する関数は、全て BulletinBoard->shared->function(...) と呼んで下さい。 + set($key, $value) 掲示板に $key という名前で値 $value をセットします。 - $value を __PACKAGE__."/key" という名前にすれば + $key を __PACKAGE__."/key" という名前にすれば 被りにくいと思います。 + get($key) $key でセットした値を得ます。 + keys BulletinBoard が保持しているテーブルを返します。 @@ -66,6 +66,12 @@ + 情報取得系 * server_hops 自分のつながっている server と、あるサーバの hop 数の対応を (情報が得られたときに)記録しています。 + * isupport RPL_ISUPPORT が送ってくる情報を記録しています。 + RPL_ISUPPORT の詳細は http://www.irc.org/tech_docs/005.html 等を + 参照してください。 + 対応していないサーバでは remark は存在しません。 + * uid RPL_YOURID が送ってくる情報を記録しています。 + 対応していないサーバでは remark は存在しません。 - IRCMessage + 情報取得系 * affected-channels NICK や QUIT などの全チャンネルに波及するメッセージのときに @@ -84,5 +90,6 @@ * kicked-out そのチャンネルから蹴り出されている(すでにそのチャンネルに いない)かどうか。 * switches-are-known チャンネルモードを取得済みかどうか。 + * creation-time RPL_CREATIONTIME が返した値。 - PersonInChannel - PersonalInfo diff -urN tiarra-20040418/main/IrcIO/Server.pm tiarra-20040508/main/IrcIO/Server.pm --- tiarra-20040418/main/IrcIO/Server.pm 2004-04-18 16:45:57.000000000 +0900 +++ tiarra-20040508/main/IrcIO/Server.pm 2004-05-08 17:15:57.000000000 +0900 @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# $Id: Server.pm,v 1.55 2004/04/07 11:49:57 admin Exp $ +# $Id: Server.pm,v 1.56 2004/05/08 08:11:31 topia Exp $ # ----------------------------------------------------------------------------- # IrcIO::ServerはIRCサーバーに接続し、IRCメッセージをやり取りするクラスです。 # このクラスはサーバーからメッセージを受け取ってチャンネル情報や現在のnickなどを保持しますが、 @@ -402,6 +402,10 @@ $this->_set_to_next_nick($first_msg->param(1)); return; # 何も返さない→クライアントにはこの結果を知らせない。 } + elsif ($reply eq RPL_HELLO) { + # RPL_HELLO (irc2.11.x) + return; # 何もしない + } else { # それ以外。手の打ちようがないのでconnectionごと切断してしまう。 # 但し、ニューメリックリプライでもERRORでもなければ無視する。 @@ -501,8 +505,9 @@ foreach ( map("RPL_$_", qw(CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME - WHOREPLY NAMREPLY ENDOFNAMES - WHOISUSER WHOISSERVER AWAY ENDOFWHOIS), + CREATIONTIME WHOREPLY NAMREPLY ENDOFNAMES + WHOISUSER WHOISSERVER AWAY ENDOFWHOIS + ISUPPORT YOURID), map({("${_}LIST", "ENDOF${_}LIST");} qw(INVITE EXCEPT BAN)), )) { @@ -872,6 +877,14 @@ } } +sub _RPL_CREATIONTIME { + my ($this,$msg) = @_; + my $ch = $this->channel($msg->param(1)); + if (defined $ch) { + $ch->remark('creation-time', $msg->param(2)); + } +} + sub _RPL_INVITELIST { my ($this,$msg) = @_; my $ch = $this->channel($msg->param(1)); @@ -997,10 +1010,49 @@ Params => \@args)); } +sub _RPL_ISUPPORT { + # 歴史的な理由で、 RPL_ISUPPORT(005) は + # RPL_BOUNCE(005) として使われていることがある。 + my ($this,$msg) = @_; + if ($msg->n_params >= 2 && # nick + [params] + 'are supported by this server' + $msg->param($msg->n_params - 1) =~ /supported/i) { + my $isupport = $this->remark('isupport'); + foreach my $param ((@{$msg->params})[1...($msg->n_params - 2)]) { + my ($negate, $key, $value) = $param =~ /^(-)?([[:alnum:]]+)(?:=(.+))?$/; + if (!defined $negate) { + # empty value + $value = '' unless defined $value; + $isupport->{$key} = $value; + } elsif (!defined $value) { + # negate a previously specified parameter + delete $isupport->{$key}; + } else { + # inconsistency param + carp("inconsistency RPL_ISUPPORT param: $param"); + } + } + $this->remark('isupport', $isupport); + } +} + +sub _RPL_YOURID { + my ($this,$msg) = @_; + + $this->remark('uid', $msg->param(1)); +} + sub _set_to_next_nick { my ($this,$failed_nick) = @_; # failed_nickの次のnickを試します。nick重複でログインに失敗した時に使います。 - my $next_nick = modify_nick($failed_nick); + my $nicklen = do { + if (defined $this->remark('isupport') && + defined $this->remark('isupport')->{NICKLEN}) { + $this->remark('isupport')->{NICKLEN}; + } else { + 9; + } + }; + my $next_nick = modify_nick($failed_nick, $nicklen); my $msg_for_user = "Nick $failed_nick was already in use in the ".$this->network_name.". Trying ".$next_nick."..."; $this->send_message( @@ -1017,26 +1069,31 @@ sub modify_nick { my $nick = shift; - if ($nick =~ /(\d+)$/) { + my $nicklen = shift || 9; + + if ($nick =~ /^(.*\D)?(\d+)$/) { # 最後の数文字が数字だったら、それをインクリメント - my $base = $`; - my $next_num = $1 + 1; - if (length($base . $next_num) <= 9) { - # 9文字以内に収まるのでこれで試す。 + my $base = $1; + my $next_num = $2 + 1; + if (($next_num - 1) eq $next_num) { + # 桁あふれしているので数字部分を全部消す。 + $nick = $base; + } elsif (length($base . $next_num) <= $nicklen) { + # $nicklen 文字以内に収まるのでこれで試す。 $nick = $base . $next_num; } else { - # 収まらないので9文字に縮める。 - $nick = substr($base,0,9 - length($next_num)) . $next_num; + # 収まらないので $nicklen 文字に縮める。 + $nick = substr($base,0,$nicklen - length($next_num)) . $next_num; } } - elsif ($nick =~ /_$/ && length($nick) >= 9) { + elsif ($nick =~ /_$/ && length($nick) >= $nicklen) { # 最後の文字が_で、それ以上_を付けられない場合、それを0に。 $nick =~ s/_$/0/; } else { # 最後に_を付ける。 - if (length($nick) >= 9) { + if (length($nick) >= $nicklen) { $nick =~ s/.$/_/; } else { diff -urN tiarra-20040418/main/Multicast.pm tiarra-20040508/main/Multicast.pm --- tiarra-20040418/main/Multicast.pm 2004-04-18 16:45:57.000000000 +0900 +++ tiarra-20040508/main/Multicast.pm 2004-05-08 17:15:57.000000000 +0900 @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# $Id: Multicast.pm,v 1.24 2004/04/07 11:49:58 admin Exp $ +# $Id: Multicast.pm,v 1.25 2004/05/08 08:11:31 topia Exp $ # ----------------------------------------------------------------------------- # サーバーからクライアントにメッセージが流れるとき、このクラスはフィルタとして # ネットワーク名を付加します。 @@ -356,7 +356,8 @@ } ((map {"RPL_$_"} ((map { ("$_", "ENDOF$_"); } qw(INVITELIST EXCEPTLIST BANLIST)), (map {"ENDOF$_"} qw(WHO NAMES)), - qw(LIST CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME))), + qw(LIST CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME), + qw(CREATIONTIME))), qw(ERR_TOOMANYCHANNELS ERR_NOTONCHANNEL ERR_NOSUCHCHANNEL))}, do { no strict 'refs'; @@ -395,7 +396,7 @@ 'SERVLIST' => \&_MODE_from_client, # これも良く分からない。MODEと同じに。 'SERVSET' => \&_MODE_from_client, # これも。 'SQUERY' => \&_MODE_from_client, # これも - 'STATS' => \&_MODE_from_client, + 'STATS' => \&_MODE_from_client, # サーバ名はうしろにつくのでこれはよくないかも 'SUMMON' => \&_MODE_from_client, 'TIME' => \&_MODE_from_client, 'TOPIC' => \&_MODE_from_client, @@ -405,6 +406,7 @@ 'USERHOST' => \&_ISON_from_client, 'USERS' => \&_MODE_from_client, 'VERSION' => \&_MODE_from_client, + 'ADMIN' => \&_MODE_from_client, 'WHO' => \&_WHOIS_from_client, 'WHOIS' => \&_WHOIS_from_client, 'WHOWAS' => \&_WHOIS_from_client, @@ -430,7 +432,7 @@ ((map { ("$_", "ENDOF$_"); } qw(INVITELIST EXCEPTLIST BANLIST)), (map {"ENDOF$_"} qw(WHO NAMES)), qw(LIST CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME), - qw(INVITING UNIQOPIS WHOREPLY))), + qw(CREATIONTIME INVITING UNIQOPIS WHOREPLY))), qw(ERR_TOOMANYCHANNELS ERR_NOTONCHANNEL ERR_NOSUCHCHANNEL))}, do { no strict 'refs'; diff -urN tiarra-20040418/main/NumericReply.pm tiarra-20040508/main/NumericReply.pm --- tiarra-20040418/main/NumericReply.pm 2004-04-18 16:45:57.000000000 +0900 +++ tiarra-20040508/main/NumericReply.pm 2004-05-08 17:15:57.000000000 +0900 @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# $Id: NumericReply.pm,v 1.2 2004/02/14 11:48:19 topia Exp $ +# $Id: NumericReply.pm,v 1.3 2004/05/08 08:11:31 topia Exp $ # ----------------------------------------------------------------------------- # このファイルでは、各ニューメリックリプライに対するシンボルを定義し、exportします。 # ----------------------------------------------------------------------------- @@ -21,12 +21,21 @@ RPL_CREATED 003 RPL_MYINFO 004 RPL_ISUPPORT 005 + + # irc2.11.x or +hemp RPL_BOUNCE 010 + RPL_REDIR 010 + RPL_MAP 015 RPL_MAPMORE 016 RPL_MAPEND 017 RPL_MAPSTART 018 + # irc2.11.x + RPL_HELLO 020 + RPL_YOURID 042 + RPL_SAVENICK 043 + RPL_NONE 300 RPL_AWAY 301 @@ -56,13 +65,20 @@ RPL_CHANNELMODEIS 324 RPL_UNIQOPIS 325 + RPL_CREATIONTIME 329 + RPL_NOTOPIC 331 RPL_TOPIC 332 RPL_TOPICWHOTIME 333 + RPL_TOPIC_WHO_TIME 333 RPL_INVITING 341 RPL_SUMMONING 342 + # irc2.11 + RPL_REOPLIST 344 + RPL_ENDOFREOPLIST 345 + RPL_INVITELIST 346 RPL_ENDOFINVITELIST 347 diff -urN tiarra-20040418/module/Client/Cache.pm tiarra-20040508/module/Client/Cache.pm --- tiarra-20040418/module/Client/Cache.pm 2004-04-18 16:45:57.000000000 +0900 +++ tiarra-20040508/module/Client/Cache.pm 2004-05-08 17:15:57.000000000 +0900 @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# $Id: Cache.pm,v 1.9 2004/04/18 07:44:47 topia Exp $ +# $Id: Cache.pm,v 1.10 2004/05/08 08:11:31 topia Exp $ # ----------------------------------------------------------------------------- # copyright (C) 2003-2004 Topia . all rights reserved. package Client::Cache; @@ -255,6 +255,22 @@ }, ) ); + if (defined $ch->remark('creation-time')) { + $sendto->send_message( + IRCMessage->new( + Prefix => RunLoop->shared_loop->sysmsg_prefix('system'), + Command => RPL_CREATIONTIME, + Params => [ + RunLoop->shared_loop->current_nick, + $ch_name, + $ch->remark('creation-time'), + ], + Remarks => { + 'fill-prefix-when-sending-to-client' => 1, + }, + ) + ); + } } 1;