1 # -*- mode: perl; coding: utf-8 -*-
3 # $Id: IrcBuffer.pm,v 1.20 2008-08-06 06:56:49 morimoto Exp $
4 # $Source: /home/ishikawa/work/keitairc/tmp/keitairc/lib/Keitairc/IrcBuffer.pm,v $
6 # Copyright (c) 2008 Jun Morimoto <morimoto@mrmt.net>
7 # This program is covered by the GNU General Public License 2
9 package Keitairc::IrcBuffer;
15 ################################################################
21 $me->{history} = $arg->{history};
23 # join しているchannelの名称を記録するハッシュ。
24 # - cid および name2cid ハッシュに格納されている値は整数。
25 # - cid2nameハッシュに格納されている文字列、および name2cid の
26 # ハッシュキーは iso-2022-jp (ないしはそのircチャネルで使われ
27 # ているcharset)のまま。これは歴史的理由でこうするしかない。
31 # join しているtopicの名称を記録するハッシュ
32 # charset: perl internal
37 $me->{tbuffer} = {}; # time, ref to array
38 $me->{nbuffer} = {}; # nick, ref to array
39 $me->{mbuffer} = {}; # message, perl internal, ref to array
40 $me->{rbuffer} = {}; # read flag, ref to array
45 # timestamp of last posted message
51 ################################################################
53 my($me, $cid, $nick, $chop, $realname) = @_;
54 $me->{nicks}->{$cid}->{$nick}->{realname} = $realname;
55 $me->{nicks}->{$cid}->{$nick}->{chop} = $chop;
58 ################################################################
60 my($me, $cid, $nick, $chop, $realname) = @_;
61 keys %{$me->{nicks}->{$cid}};
64 ################################################################
66 my($me, $cid, $nick) = @_;
67 delete $me->{nicks}->{$cid}->{$nick};
70 ################################################################
71 sub get_nick_realname{
72 my($me, $cid, $nick) = @_;
73 $me->{nicks}->{$cid}->{$nick}->{realname};
76 ################################################################
78 my($me, $cid, $nick) = @_;
79 if(defined $me->{nicks}->{$cid}){
80 if(defined $me->{nicks}->{$cid}->{$nick}){
81 $me->{nicks}->{$cid}->{$nick}->{chop} = 1;
86 ################################################################
88 my($me, $cid, $nick) = @_;
89 if(defined $me->{nicks}->{$cid}){
90 if(defined $me->{nicks}->{$cid}->{$nick}){
91 $me->{nicks}->{$cid}->{$nick}->{chop} = 0;
96 ################################################################
98 my($me, $cid, $nick) = @_;
99 if(defined $me->{nicks}->{$cid}){
100 if(defined $me->{nicks}->{$cid}->{$nick}){
101 return $me->{nicks}->{$cid}->{$nick}->{chop};
106 ################################################################
113 $me->mtime($b) <=> $me->mtime($a)
114 } keys %{$me->{cid2name}});
117 ################################################################
119 my ($sec, $min, $hour) = localtime(time);
120 sprintf('%02d:%02d', $hour, $min);
123 ################################################################
124 # 引数の $name (チャネル名) は、生の iso-2022-jp のまま、ないしは irc
125 # チャネルで扱われている charset のまま扱うこと。こういう慣習なので
129 $name =~ tr/A-Z[\\]^/a-z{|}~/;
131 unless(defined $me->{name2cid}->{$name}){
132 my $cid = (sort { $b - $a } (keys %{$me->{cid2name}}))[0];
134 $me->{cid2name}->{$cid} = $name;
135 $me->{name2cid}->{$name} = $cid;
138 $me->{name2cid}->{$name};
141 ################################################################
144 $me->{cid2name}->{$cid};
147 ################################################################
150 delete $me->{cid2name}->{$cid};
151 delete $me->{name2cid}->{$cid};
152 delete $me->{topic}->{$cid};
153 delete $me->{nicks}->{$cid};
154 delete $me->{tbuffer}->{$cid};
155 delete $me->{nbuffer}->{$cid};
156 delete $me->{mbuffer}->{$cid};
157 delete $me->{rbuffer}->{$cid};
160 ################################################################
162 my ($me, $name) = @_;
163 my $cid = $me->name2cid($name);
164 $me->{cid2name}->{$cid} = $name;
167 ################################################################
170 $me->{mtime}->{$cid} || 0;
173 ################################################################
176 scalar grep(/0/, @{$me->{rbuffer}->{$cid}});
179 ################################################################
181 my($me, $cid, $topic) = @_;
183 $me->{topic}->{$cid} = $topic;
185 $me->{topic}->{$cid};
188 ################################################################
191 ($me->{tbuffer}->{$cid}, $me->{nbuffer}->{$cid},
192 $me->{mbuffer}->{$cid}, $me->{rbuffer}->{$cid});
195 ################################################################
196 # 引数の $msg の charset は perl internal
197 # $channel は iso-2022-jp または irc channel specific
199 my($me, $cid, $message, $who) = @_;
201 unless(defined $me->{tbuffer}->{$cid}){
202 $me->{tbuffer}->{$cid} = [];
204 unless(defined $me->{nbuffer}->{$cid}){
205 $me->{nbuffer}->{$cid} = [];
207 unless(defined $me->{mbuffer}->{$cid}){
208 $me->{mbuffer}->{$cid} = [];
210 unless(defined $me->{rbuffer}->{$cid}){
211 $me->{rbuffer}->{$cid} = [];
214 push @{$me->{tbuffer}->{$cid}}, now();
215 push @{$me->{nbuffer}->{$cid}}, $who;
216 push @{$me->{mbuffer}->{$cid}}, $message;
217 push @{$me->{rbuffer}->{$cid}}, 0;
219 if(@{$me->{tbuffer}->{$cid}} > $me->{history}){
220 shift @{$me->{tbuffer}->{$cid}};
222 if(@{$me->{nbuffer}->{$cid}} > $me->{history}){
223 shift @{$me->{nbuffer}->{$cid}};
225 if(@{$me->{mbuffer}->{$cid}} > $me->{history}){
226 shift @{$me->{mbuffer}->{$cid}};
228 if(@{$me->{rbuffer}->{$cid}} > $me->{history}){
229 shift @{$me->{rbuffer}->{$cid}};
232 if($me->{cid2name}->{$cid} eq '*console*') {
233 $me->{mtime}->{$cid} = -1;
235 $me->{mtime}->{$cid} = time;
239 ################################################################
241 # 返り値は Perl internal code
242 sub compact_channel_name{
245 my $name = $me->cid2name($cid);
247 return undef unless defined $name;
249 # この後の置換処理は、チャネル名の文字列が実際に運用されている
250 # charset で行う必要がある。日本語が用いられている従来の irc チャ
251 # ネルであれば iso-2022-jp-1 だし、ないしは utf8 のまま。
252 $name = Encode::decode($::cf->irc_charset(), $name);
254 # #name:*.jp を %name に
255 if($name =~ s/:\*\.jp$//){
259 # 末尾の単独の @ は取る (plumプラグインのmulticast.plm対策)
260 # @ の後に空白が入ることもあるようだ。理由はわからない。
265 ################################################################
277 ################################################################
284 2 => '#000080', # Navy Blue
291 9 => '#32cd32', # Lime Green
294 12 => '#4169e1', # Royal Blue
295 13 => '#ff69b4', # Hot Pink
296 14 => '#a9a9a9', # Dark Gray
297 15 => '#d3d3d3', # Light Gray
301 return undef unless defined $_;
305 s|\x03(\d{1,2})|sprintf('</font><font color="%s">', $ct{0+$1})|e;
310 if(s|\x03(\d{1,2})|sprintf('<font color="%s">', $ct{0+$1})|e){
314 }while(m|\x03\d{1,2}|);
323 ################################################################
324 # 同一秒間の連続発言を防ぐためのチェック。
326 # 前回 update_timestamp() が呼ばれた時刻と同じ時刻に
327 # 再度 update_timestamp() が呼ばれたら 0 を返す。
329 # 前回 update_timestamp() が呼ばれた時刻と異なる時刻に
330 # 再度 update_timestamp() が呼ばれたら 1 を返す。
332 sub update_timestamp{
336 if($me->{timestamp} != $time){
337 $me->{timestamp} = $time;