File Coverage

blib/lib/Mojo/IRC/Server/Chinese/User.pm
Criterion Covered Total %
statement 6 154 3.9
branch 0 62 0.0
condition 0 20 0.0
subroutine 2 21 9.5
pod 0 17 0.0
total 8 274 2.9


line stmt bran cond sub pod time code
1             package Mojo::IRC::Server::Chinese::User;
2 1     1   5 use Mojo::IRC::Server::Chinese::Base 'Mojo::IRC::Server::Chinese::Object';
  1         1  
  1         5  
3 1     1   5 use List::Util qw(first);
  1         2  
  1         1900  
4             has [qw(id name io)];
5             has user => '*';
6             has pass => undef;
7             has nick => '*';
8             has mode => 'i';
9             has buffer => '';
10             has virtual => 0;
11             has host => sub{$_[0]->virtual?"virtualhost":"hidden"};
12             has port => sub{$_[0]->virtual?"virtualport":"hidden"};
13             has ctime => sub{time()};
14             has 'last_speak_time';
15             has 'last_active_time';
16             has ping_count => 0;
17             has close_reason => undef;
18             has channel => sub{[]};
19             has realname => 'unset';
20             has is_quit => 0;
21             has is_away => 0;
22             has away_info => undef;
23              
24             sub is_registered {
25 0     0 0   my $s = shift;
26 0 0         if(@_==0){return $s->{is_registered}}
  0            
27             else{
28 0           $s->{is_registered} = $_[0];
29 0           $s->{_server}->emit(user_registered=>$s);
30             }
31 0           return $s;
32             }
33             sub is_virtual {
34 0     0 0   $_[0]->virtual;
35             }
36             sub away {
37 0     0 0   my $s = shift;
38 0           my $away_info = shift;
39 0           $s->send($s->serverident,"306",$s->nick,"你已经被标记为离开");
40 0           $s->is_away(1);
41 0           $s->set_mode("+a");
42 0           $s->away_info($away_info);
43             }
44             sub back {
45 0     0 0   my $s = shift;
46 0           $s->send($s->serverident,"305",$s->nick,"你不再被标记为离开");
47 0           $s->is_away(0);
48 0           $s->set_mode("-a");
49 0           $s->away_info(undef);
50             }
51             sub quit{
52 0     0 0   my $s = shift;
53 0   0       my $quit_reason = shift || "";
54 0           $s->broadcast($s->ident,"QUIT",$quit_reason);
55 0           $s->info("[" . $s->name . "] 已退出($quit_reason)");
56 0 0         $s->io->close_gracefully() if not $s->is_virtual;
57 0           $s->{_server}->remove_user($s);
58             }
59             sub ident{
60 0     0 0   my $s = shift;
61 0           return $s->nick . '!' . $s->user . '@' . $s->host;
62             }
63             sub set_nick{
64 0     0 0   my $s = shift;
65 0           my $nick = shift;
66 0           $nick =~s/\s|\@|!//g;
67 0           my $user = $s->search_user(nick=>$nick);
68 0 0 0       if(defined $user and $user->id ne $s->id){
69 0 0         if($user->is_virtual){
70 0           $user->quit("虚拟帐号被移除");
71 0     0     $s->once(close=>sub{$s->{_server}->add_user($user)});
  0            
72 0           $s->broadcast($s->ident,NICK => $nick);
73 0           $s->info("[" . $s->nick . "] 修改昵称为 [$nick]");
74 0           $s->nick($nick);
75 0           $s->name($nick);
76 0 0 0       if(!$s->is_registered and $s->nick ne "*" and $s->user ne "*"){
      0        
77 0           $s->is_registered(1);
78             }
79             }
80             else{
81 0           $s->send($s->serverident,"433",$s->nick,$nick,'昵称已经被使用');
82 0           $s->info("昵称 [$nick] 已经被使用");
83             }
84             }
85             else{
86 0 0 0       if(defined $s->{_server}->auth and ref $s->{_server}->auth eq "CODE"){
87 0 0         if(! $s->{_server}->auth->($nick,$s->user,$s->pass)){
88 0           $s->send($s->serverident,"464",$s->nick,"认证失败");
89 0           return;
90             }
91             }
92 0           $s->broadcast($s->ident,NICK => $nick);
93 0           $s->info("[" . $s->nick . "] 修改昵称为 [$nick]");
94 0           $s->nick($nick);
95 0           $s->name($nick);
96 0 0 0       if(!$s->is_registered and $s->nick ne "*" and $s->user ne "*"){
      0        
97 0           $s->is_registered(1);
98             }
99             }
100             }
101             sub set_mode{
102 0     0 0   my $s = shift;
103 0           my $mode = shift;
104 0           my %mode = map {$_=>1} split //,$s->mode;
  0            
105 0 0         if(substr($mode,0,1) eq "+"){
    0          
106 0           $mode{$_}=1 for split //,substr($mode,1,);
107             }
108             elsif(substr($mode,0,1) eq "-"){
109 0           delete $mode{$_} for split //,substr($mode,1,);
110             }
111             else{
112 0           %mode = ();
113 0           $mode{$_}=1 for split //,$mode;
114             }
115 0           $s->mode(join "",keys %mode);
116 0           $s->send($s->ident,"MODE",$s->nick,$mode);
117 0           $s->info("[" . $s->nick . "] 模式设置为: " . $s->mode);
118             }
119             sub join_channel{
120 0     0 0   my $s = shift;
121 0           my $channel;
122 0 0         $channel = ref($_[0]) eq "Mojo::IRC::Server::Chinese::Channel"?$_[0]:$s->search_channel(id=>$_[0]);
123 0 0         return if not defined $channel;
124 0 0         if(not $s->is_join_channel($channel->id)){
125 0           push @{$s->channel},$channel->id;
  0            
126 0           $channel->add_user($s->id);
127 0           $channel->broadcast($s->ident,"JOIN",$channel->name);
128             }
129 0           else{$s->send($s->ident,"JOIN",$channel->name);}
130 0           $s->send($s->serverident,"332",$s->nick,$channel->name,$channel->topic);
131 0           $s->send($s->serverident,"353",$s->nick,'=',$channel->name,join " ",map {$_->nick} $channel->users);
  0            
132 0           $s->send($s->serverident,"366",$s->nick,$channel->name,"End of NAMES list");
133             #$s->send($s->serverident,"329",$s->nick,$channel->name,$channel->ctime);
134 0           $s->info("[" . $s->name . "] 加入频道 " . $channel->name);
135             }
136             sub part_channel{
137 0     0 0   my $s = shift;
138 0 0         my $channel = ref($_[0]) eq "Mojo::IRC::Server::Chinese::Channel"?$_[0]:$s->search_channel(id=>$_[0]);
139 0           my $part_info = $_[1];
140 0 0         return if not defined $channel;
141 0           $channel->broadcast($s->ident,"PART",$channel->name,$part_info);
142 0           for(my $i=0;$i<@{$s->channel};$i++){
  0            
143 0 0         if($channel->id eq $s->channel->[$i]){
144 0           splice @{$s->channel},$i,1;
  0            
145 0           last;
146             }
147             }
148 0           $channel->remove_user($s->id);
149 0           $s->info("[" . $s->nick . "] 离开频道 " . $channel->name);
150            
151             }
152             sub is_join_channel{
153 0     0 0   my $s = shift;
154 0 0         my $cid = ref($_[0]) eq "Mojo::IRC::Server::Chinese::Channel"?$_[0]->id:$_[0];
155 0 0         if(defined $cid){
156 0 0   0     return (first {$cid eq $_} @{$s->channel})?1:0;
  0            
  0            
157             }
158             else{
159 0           return 0+@{$s->channel};
  0            
160             }
161             }
162             sub forward{
163 0     0 0   my $s = shift;
164 0           my %unique;
165 0           for my $channel ($s->channels){
166 0           for my $user ($channel->users){
167 0 0         next if $user->id eq $s->id;
168 0 0         next if exists $unique{$user->id};
169 0           $user->send(@_);
170 0           $unique{$user->id} = 1;
171             }
172             }
173             }
174              
175             sub broadcast{
176 0     0 0   my $s = shift;
177 0           $s->send(@_);
178 0           my %unique;
179 0           for my $channel ($s->channels){
180 0           for my $user ($channel->users){
181 0 0         next if $user->id eq $s->id;
182 0 0         next if exists $unique{$user->id};
183 0           $user->send(@_);
184 0           $unique{$user->id} = 1;
185             }
186             }
187             }
188             sub channels{
189 0     0 0   my $s = shift;
190 0           my @channels = ();
191 0           for my $cid (@{$s->channel}){
  0            
192 0           my $channel = $s->search_channel(id=>$cid);
193 0 0         push @channels ,$channel if defined $channel;
194             }
195 0           return @channels;
196             }
197             sub each_channel{
198 0     0 0   my $s = shift;
199 0           my $callback = shift;
200 0 0         return if not $s->is_join_channel();
201 0           for my $cid (@{$s->channel}){
  0            
202 0           my $channel = $s->search_channel(id=>$cid);
203 0 0         $callback->($s,$channel,@_) if defined $channel;
204             }
205             }
206              
207             sub send{
208 0     0 0   my $s = shift;
209 0 0         return if $s->is_virtual ;
210 0           my($prefix,$command,@params)=@_;
211 0           my $msg = "";
212 0 0         $msg .= defined $prefix ? ":$prefix " : "";
213 0           $msg .= $command;
214 0           my $trail;
215 0           $trail = pop @params;
216 0           $msg .= " $_" for @params;
217 0 0         $msg .= defined $trail ? " :$trail" : "";
218 0           $msg .= "\r\n";
219 0           $s->io->write($msg);
220 0           $s->debug("S[".$s->name."] $msg");
221             }
222             sub is_localhost{
223 0     0 0   my $s = shift;
224 0 0         return 0 if $s->is_virtual;
225 0 0         return 1 if $s->io->handle->peerhost eq "127.0.0.1";
226             }
227             1;