root/lang/perl/mobirc/trunk/mobirc/lib/Mobirc/IRCClient.pm @ 874

Revision 874, 7.9 kB (checked in by tokuhirom, 6 years ago)

lang/perl/mobirc: detail design change.
lang/perl/mobirc: reconnect, connect, snotice is now in the *server* pseudo channel.

Line 
1package Mobirc::IRCClient;
2use strict;
3use warnings;
4
5use POE;
6use POE::Sugar::Args;
7use POE::Component::IRC;
8
9use Encode;
10use Carp;
11
12use Mobirc::Util;
13
14sub init {
15    my ($class, $config) = @_;
16
17    # irc component
18    my $irc = POE::Component::IRC->spawn(
19        Alias    => 'mobirc_irc',
20        Nick     => $config->{irc}->{nick},
21        Username => $config->{irc}->{username},
22        Ircname  => $config->{irc}->{desc},
23        Server   => $config->{irc}->{server},
24        Port     => $config->{irc}->{port},
25        Password => $config->{irc}->{password}
26    );
27
28    POE::Session->create(
29        heap => {
30            seen_traffic   => false,
31            disconnect_msg => true,
32            channel_topic  => {},
33            channel_name   => {},
34            config         => $config,
35            irc            => $irc,
36        },
37        inline_states => {
38            _start           => \&on_irc_start,
39            _default         => \&on_irc_default,
40
41            irc_001          => \&on_irc_001,
42            irc_join         => \&on_irc_join,
43            irc_part         => \&on_irc_part,
44            irc_public       => \&on_irc_public,
45            irc_notice       => \&on_irc_notice,
46            irc_topic        => \&on_irc_topic,
47            irc_332          => \&on_irc_topicraw,
48            irc_ctcp_action  => \&on_irc_ctcp_action,
49            irc_kick         => \&on_irc_kick,
50            irc_snotice      => \&on_irc_snotice,
51
52            autoping         => \&do_autoping,
53            connect          => \&do_connect,
54
55            irc_disconnected => \&on_irc_reconnect,
56            irc_error        => \&on_irc_reconnect,
57            irc_socketerr    => \&on_irc_reconnect,
58        }
59    );
60}
61
62# -------------------------------------------------------------------------
63
64sub on_irc_default {
65    DEBUG "ignore unknown event: $_[ARG0]";
66}
67
68sub on_irc_start {
69    my $poe = sweet_args;
70    DEBUG "START";
71
72    $poe->kernel->alias_set('irc_session');
73
74    DEBUG "input charset is: " . $poe->heap->{config}->{irc}->{incode};
75
76    $poe->heap->{irc}->yield( register => 'all' );
77    $poe->heap->{irc}->yield( connect  => {} );
78}
79
80sub on_irc_001 {
81    my $poe = sweet_args;
82
83    DEBUG "CONNECTED";
84
85    add_message( $poe,
86        decode( 'utf8', '*server*' ),
87        undef, decode('utf8', 'Connected to irc server!'), 'connect' );
88
89    $poe->heap->{disconnect_msg} = true;
90    $poe->heap->{channel_name} = {'*server*' => '*server*'};
91    $poe->kernel->delay( autoping => $poe->heap->{config}->{ping_delay} );
92}
93
94sub on_irc_join {
95    my $poe = sweet_args;
96
97    DEBUG "JOIN";
98
99    my $who = $poe->args->[0];
100    $who =~ s/!.*//;
101
102    # chop off after the gap (bug workaround of madoka)
103    my $channel = decode($poe->heap->{config}->{irc}->{incode}, $poe->args->[1]);
104    $channel =~ s/ .*//;
105    my $canon_channel = canon_name($channel);
106
107    $poe->heap->{channel_name}->{$canon_channel} = $channel;
108    my $irc = $poe->heap->{irc};
109    unless ( $who eq $irc->nick_name ) {
110        add_message(
111            $poe,
112            $channel,
113            undef,
114            decode( $poe->heap->{config}->{irc}->{incode}, "$who joined" ),
115            'join',
116        );
117    }
118    $poe->heap->{seen_traffic}   = true;
119    $poe->heap->{disconnect_msg} = true;
120}
121
122sub on_irc_part {
123    my $poe = sweet_args;
124
125    my $who = $poe->args->[0];
126    $who =~ s/!.*//;
127
128    # chop off after the gap (bug workaround of POE::Filter::IRC)
129    my $channel = $poe->args->[1];
130    $channel =~ s/ .*//;
131    my $canon_channel = canon_name($channel);
132
133    my $irc = $poe->heap->{irc};
134    if ( $who eq $irc->nick_name ) {
135        delete $poe->heap->{channel_name}->{$canon_channel};
136    }
137    else {
138        add_message(
139            $poe,
140            decode( $poe->heap->{config}->{irc}->{incode}, $channel ),
141            undef,
142            decode( $poe->heap->{config}->{irc}->{incode}, "$who leaves" ),
143            'leave',
144        );
145    }
146    $poe->heap->{seen_traffic}   = true;
147    $poe->heap->{disconnect_msg} = true;
148}
149
150sub on_irc_public {
151    my $poe = sweet_args;
152
153    DEBUG "IRC PUBLIC";
154    my $who = $poe->args->[0];
155    $who =~ s/!.*//;
156    my $channel = $poe->args->[1];
157    $channel = $channel->[0];
158
159    my $msg = $poe->args->[2];
160
161    add_message(
162        $poe, decode( $poe->heap->{config}->{irc}->{incode}, $channel ),
163        $who, decode( $poe->heap->{config}->{irc}->{incode}, $msg ),
164        'public',
165    );
166
167    $poe->heap->{seen_traffic}   = true;
168    $poe->heap->{disconnect_msg} = true;
169}
170
171sub on_irc_notice {
172    my $poe = sweet_args;
173
174    my $who = $poe->args->[0];
175    my $channel = $poe->args->[1];
176    my $msg = $poe->args->[2];
177
178    DEBUG "IRC NOTICE";
179
180    $who =~ s/!.*//;
181    $channel = $channel->[0];
182
183    add_message(
184        $poe, decode( $poe->heap->{config}->{irc}->{incode}, $channel ),
185        $who, decode( $poe->heap->{config}->{irc}->{incode}, $msg ),
186        'notice',
187    );
188    $poe->heap->{seen_traffic}   = true;
189    $poe->heap->{disconnect_msg} = true;
190}
191
192sub on_irc_topic {
193    my $poe = sweet_args;
194
195    my $who = $poe->args->[0];
196    $who =~ s/!.*//;
197
198    my $channel = $poe->args->[1];
199    $channel = decode($poe->heap->{config}->{irc}->{incode}, $channel);
200
201    my $topic = $poe->args->[2];
202    $topic = decode($poe->heap->{config}->{irc}->{incode}, $topic);
203
204    DEBUG "SET TOPIC";
205
206    add_message( $poe,
207        $channel,
208        undef, "$who set topic: $topic",
209        'topic',
210        );
211
212    $poe->heap->{channel_topic}->{canon_name($channel)} = $topic;
213
214    $poe->heap->{seen_traffic}                  = true;
215    $poe->heap->{disconnect_msg}                = true;
216}
217
218sub on_irc_topicraw {
219    my $poe = sweet_args;
220
221    DEBUG "SET TOPIC RAW";
222
223    my $raw = decode( $poe->heap->{config}->{irc}->{incode}, $poe->args->[1] );
224    my ( $channel, $topic ) = split( / :/, $raw, 2 );
225
226    $poe->heap->{channel_topic}->{ canon_name($channel) } = $topic;
227    $poe->heap->{seen_traffic}                  = true;
228    $poe->heap->{disconnect_msg}                = true;
229}
230
231sub on_irc_ctcp_action {
232    my $poe = sweet_args;
233
234    my $who = $poe->args->[0];
235    my $channel = $poe->args->[1];
236    my $msg = $poe->args->[2];
237
238    $who =~ s/!.*//;
239    $channel = $channel->[0];
240    $msg = sprintf( '* %s %s', $who, decode( $poe->heap->{config}->{irc}->{incode}, $msg) );
241    add_message( $poe, decode($poe->heap->{config}->{irc}->{incode}, $channel), '', $msg, 'ctcp_action', );
242    $poe->heap->{seen_traffic}   = true;
243    $poe->heap->{disconnect_msg} = true;
244}
245
246sub on_irc_kick {
247    my $poe = sweet_args;
248
249    DEBUG "DNBKICK";
250
251    my ($kicker, $channel, $kickee, $msg) = map { decode($poe->heap->{config}->{irc}->{incode}, $_) } @{ $poe->args };
252    $msg ||= 'Flooder';
253
254    add_message(
255        $poe, $channel, '', "$kicker has kicked $kickee($msg)", 'kick'
256    );
257    $poe->heap->{seen_traffic}   = true;
258    $poe->heap->{disconnect_msg} = true;
259}
260
261sub do_connect {
262    my $poe = sweet_args;
263
264    $poe->heap->{irc}->yield( connect => {} );
265}
266
267sub do_autoping {
268    my $poe = sweet_args;
269
270    $poe->kernel->post( mobirc_irc => time ) unless $poe->heap->{seen_traffic};
271    $poe->heap->{seen_traffic} = false;
272    $poe->kernel->delay( autoping => $poe->heap->{config}->{ping_delay} );
273}
274
275sub on_irc_snotice {
276    my $poe = sweet_args;
277
278    my ($message, ) = _get_args($poe);
279
280    DEBUG "getting snotice : $message";
281
282    add_message(
283        $poe,
284        decode( 'utf8', '*server*' ),
285        undef,
286        decode( 'utf8', $message),
287        'snotice',
288    );
289}
290
291sub on_irc_reconnect {
292    my $poe = sweet_args;
293
294    if ( $poe->heap->{disconnect_msg} ) {
295        add_message(
296            $poe,
297            decode( 'utf8', '*server*' ),
298            undef,
299            decode( 'utf8', 'Disconnected from irc server, trying to reconnect...'),
300            'reconnect',
301        );
302    }
303    $poe->heap->{disconnect_msg} = false;
304    $poe->kernel->delay( connect => $poe->heap->{config}->{reconnect_delay} );
305}
306
307sub _get_args {
308    my $poe = shift;
309
310    return map { decode($poe->heap->{config}->{irc}->{incode}, $_) } @{ $poe->args };
311}
312
3131;
Note: See TracBrowser for help on using the browser.