root/lang/perl/XIRCD/trunk/lib/XIRCD/Server.pm

Revision 27341, 4.3 kB (checked in by tokuhirom, 4 years ago)

added authorization stuff

Line 
1package XIRCD::Server;
2use strict;
3use MooseX::POE;
4
5with qw(MooseX::POE::Aliased);
6
7use Clone qw/clone/;
8use Encode;
9
10use XIRCD::Component;
11use POE qw/Component::Server::IRC/;
12
13has 'ircd' => (
14    isa => 'POE::Component::Server::IRC',
15    is  => 'rw',
16);
17
18has 'ircd_option' => (
19    isa => 'HashRef',
20    is  => 'rw',
21    default => sub { {} },
22);
23
24has 'servername' => (
25    isa => 'Str',
26    is  => 'rw',
27    default => sub { 'xircd' },
28);
29
30has 'server_nick' => (
31    isa => 'Str',
32    is  => 'rw',
33    default => sub { 'xircd' },
34);
35
36has 'port' => (
37    isa => 'Int',
38    is  => 'rw',
39    default => sub { 6667 },
40);
41
42has 'client_encoding' => (
43    isa => 'Str',
44    is  => 'rw',
45    default => sub { 'utf-8' },
46);
47
48has auth => (
49    isa => 'ArrayRef',
50    is => 'rw',
51    default => sub { [ {master => '*@*'} ] },
52);
53
54has 'nicknames' => (
55    isa => 'HashRef',
56    is  => 'rw',
57    default => sub { {} },
58);
59
60has 'message_stack' => (
61    isa => 'HashRef',
62    is  => 'rw',
63    default => sub { {} },
64);
65
66has 'joined' => (
67    isa => 'HashRef',
68    is  => 'rw',
69    default => sub { {} },
70);
71
72has 'components' => (
73    isa => 'HashRef',
74    is  => 'rw',
75    default => sub { {} },
76);
77
78sub START {
79    self->alias('ircd');
80
81    debug "start irc";
82
83    self->ircd(
84        POE::Component::Server::IRC->spawn(
85            config => { servername => self->servername, %{ self->ircd_option } }
86        )
87    );
88    for my $auth (@{ self->auth }) {
89        self->ircd->add_auth( %{$auth} );
90    }
91    self->ircd->yield('register');
92    self->ircd->add_listener( port => self->port );
93
94    self->ircd->yield( add_spoofed_nick => { nick => self->server_nick } );
95}
96
97event ircd_daemon_join => sub {
98    my($user, $channel) = get_args;
99
100    return unless my($nick) = $user =~ /^([^!]+)!/;
101    return if self->nicknames->{$channel}->{$nick};
102    return if $nick eq self->server_nick;
103
104    self->joined->{$channel} = 1;
105
106    for my $message ( @{ self->message_stack->{$channel} || [] } ) {
107        self->ircd->yield( daemon_cmd_privmsg => $message->{nick}, $channel, $_ )
108            for split /\r?\n/, $message->{text};
109    }
110    self->message_stack->{$channel} = [];
111};
112
113event ircd_daemon_quit => sub {
114    my($user,) = get_args;
115
116    return unless my($nick) = $user =~ /^([^!]+)!/;
117    return if $nick eq self->server_nick;
118
119    for my $channel ( keys %{self->joined} ) {
120        next if self->nicknames->{$channel}->{$nick};
121        self->joined->{$channel} = 0;
122    }
123};
124
125event ircd_daemon_part => sub {
126    my($user, $channel) = get_args;
127
128    return unless my($nick) = $user =~ /^([^!]+)!/;
129    return if self->nicknames->{$channel}->{$nick};
130    return if $nick eq self->server_nick;
131
132    self->joined->{$channel} = 0;
133};
134
135event ircd_daemon_public => sub {
136    my($nick, $channel, $text) = get_args;
137
138    debug "public [$channel] $nick : $text";
139
140    my $component = self->components->{$channel};
141    return unless $component;
142    debug "send to $component";
143
144    post $component => send_message => decode( self->client_encoding, $text );
145};
146
147event _publish_message => sub {
148    my ($nick, $channel, $message) = get_args;
149
150    debug "publish to irc: [$channel] $nick : $message";
151
152    self->nicknames->{$channel} ||= {};
153    if ($nick && !self->nicknames->{$channel}->{$nick}) {
154        self->nicknames->{$channel}->{$nick}++;
155        self->ircd->yield( add_spoofed_nick => { nick => $nick } );
156        self->ircd->yield( daemon_cmd_join => $nick, $channel );
157    }
158
159    #$message = encode( self->client_encoding, $message );
160
161    if ( self->joined->{$channel} ) {
162        self->ircd->yield( daemon_cmd_privmsg => $nick => $channel, $_ )
163            for split /\r?\n/, $message;
164    } else {
165        self->message_stack->{$channel} ||= [];
166        push @{self->message_stack->{$channel}}, { nick => $nick, text => $message };
167    }
168};
169
170event _publish_notice => sub {
171    my ($channel, $message) = get_args;
172
173    debug "notice to irc: [$channel] $message";
174
175    #$message = encode( self->client_encoding, $message );
176
177    self->ircd->yield( daemon_cmd_notice => self->server_nick => $channel, $_ )
178        for split /\r?\n/, $message;
179};
180
181event join_channel => sub {
182    my ($channel, $component) = get_args;
183
184    debug "join channel: $channel";
185    debug "register: $channel => $component";
186
187    self->components->{$channel} = $component;
188    self->ircd->yield( daemon_cmd_join => self->server_nick, $channel );
189};
190
1911;
Note: See TracBrowser for help on using the browser.