Now the systrayicon change it's color when a download is in progress. I simply change...
[kdenetwork.git] / ksirc / ksirc.pl
bloba1768f638ac788338a234e09374ba5cc6b9bd860
2 # $$Id$$
5 &addhelp("server",
6 "\cbAdded by KSirc.pl\cb
7 Usage: server server [port] [password]
8 Connects to a new server opening it in a new window.
9 If server name is prefixed with a + then an ssl connection
10 is used. Port and password are optional.");
12 &addhelp("Ban",
13 "\cbAdded by KSirc.pl\cb
14 Usage: BAN <nickname>
15 bans the specified user on the current channel. Only channel operators
16 can use this command. Bans the user in the form *!*user\@hostmask.
17 hostmask is xxx.xxx.xxx.* if the hostname is in dotted quad form, otherwise
18 it is *.domain.com
19 See Also: UNBAN, CLRBAN, BANLIST");
21 &addhelp("UnBan",
22 "\cbAdded by KSirc.pl\cb
23 Usage: UNBAN <nickname>
24 Unbans the specified user on the given channel. Only channel operators
25 can use this command.
26 See Also: BAN, CLRBAN, BANLIST");
28 &addhelp("ClrBan",
29 "\cbAdded by KSirc.pl\cb
30 Usage: CLRBAN [<#channel>]
31 Removes ALL bans from the given channel. Only channel operators can use
32 this command. The channel defaults to your current one.
33 See Also: MODE [-b], BAN, UNBAN, CLRBAN, BANLIST");
35 &addhelp("BanList",
36 "\cbAdded by KSirc.pl\cb
37 Usage: BANLIST [<#channel>]
38 Shows all bans on the given channel. The channel defaults to your current one.
39 See Also: BAN, UNBAN, CLRBAN");
41 &addhelp("FC",
42 "\cbAdded by KSirc.pl\cb
43 Usage: FC [<#channel>] <Filter> <command>
44 Does /names on the given channel. Uses the current channel if none
45 specified. Does a userhost on each person received. if their name
46 (in form nick!user\@host) matches your filter (in perl regex form)
47 then command is executed, in command $1 is expanded to the nick of
48 the matchee.
49 Examples:
50 /fc #dragonrealm *!*\@*.com msg $1 you are on a host that ends in .com
51 /fc *!*\@((\\d+)\\.){3}\\.(\\d+) say $1 has a numeric host.");
53 &addhelp("Pig",
54 "\cbAdded by KSirc.pl\cb
55 Usage: PIG <message>
56 Translates your message into piglatin and says it on the current channel.");
58 &addhelp("WallOP",
59 "\cbAdded by KSirc.pl\cb
60 Usage: WALLOP [<#channel>] <message>
61 Sends a message to all of the channel operators on the given channel.
62 Defaults the the current channel.");
64 &addhelp("Amarok",
65 "\cbAdded by KSirc.pl\cb
66 Usage: AMAROK
67 Sends a message to the current channel saying what are you playing in amarok.");
69 sub cmd_wallop {
70 &getarg;
71 unless ($newarg =~ /^#/) {
72 $args = $newarg." ".$args;
73 $newarg = $talkchannel;
75 &notice("\@$newarg","[KSirc-Wall/$newarg]: $args");
77 &addcmd("wallop");
80 sub modeb {
81 ($which) = @_;
82 $user =~ s/^~//;
83 if (length($user) > 8) {
84 $user = substr($user,0, 7);
85 $user .= "*";
87 @quad = split(/\./, $host);
88 if ($host =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
89 pop @quad;
90 $toban = join('.', @quad);
91 $toban .= ".*";
92 } else {
93 $toban = "*".$quad[@quad-2].".".$quad[@quad-1];
95 &docommand("mode $talkchannel ${which}b *!*$user*\@$toban");
98 sub cmd_ban {
99 &getarg;
100 if ($newarg) {
101 &userhost($newarg, "&modeb(\"+\");");
102 } else {
103 &tell("*\cbE\cb* Usage: /ban <nick>.");
106 &addcmd("ban");
108 sub cmd_unban {
109 &getarg;
110 if ($newarg) {
111 &userhost($newarg, "&modeb(\"-\");");
112 } else {
113 &tell("*\cbE\cb* Usage: /unban <nick>.");
116 &addcmd("unban");
118 sub cmd_banlist {
119 &getarg;
120 $newarg = $talkchannel unless $newarg;
121 &docommand("mode $newarg b");
122 &addhook("367", "banlist");
123 &addhook("368","rmbanlist");
125 &addcmd("banlist");
127 sub hook_banlist {
128 $silent = 1;
129 my (undef, $channel, $mask, $banner, $time) = split(/ +/, $_[0]);
130 &print("~!default~*** \cb$mask\cb banned from \cb$channel\cb by \cb$banner\cb on \cb" . localtime($time). "\cb");
133 sub hook_rmbanlist {
134 &remhook("367","banlist");
135 &remhook("368","rmbanlist");
138 sub cmd_k {
139 &getarg;
140 $args = "You have been kicked by a KSirc user." unless $args;
141 if ($newarg) {
142 &docommand("kick $talkchannel $newarg $args");
143 } else {
144 &tell("*\cbE\cb* Usage: /k <nick> [reason]");
147 &addcmd("k");
149 sub cmd_kb {
150 &getarg;
151 if ($newarg) {
152 &docommand("ban $newarg");
153 &docommand("k $newarg $args");
154 } else {
155 &tell("*\cbE\cb* Usage: /kb <nick> [reason]");
158 &addcmd("kb");
160 sub cmd_clrban {
161 &getarg;
162 $newarg = $talkchannel unless $newarg;
163 &addhook("367", "tban");
164 &addhook("368","rm367");
165 &docommand("mode $newarg b");
167 &addcmd("clrban");
169 sub hook_tban {
170 $silent = 1;
171 my ($shit, $channel, $mask, $banner, $time) = split(/ +/, $_[0]);
172 push @bans, $mask;
173 if (@bans == 6) {
174 &print("mode $channel -bbbbbb @bans");
175 @bans = ();
179 sub hook_rm367 {
180 @bans = ();
181 &remhook("367","tban");
182 &remhook("368","rm367");
185 sub hook_disconnectd {
186 &docommand("server 1");
188 &addhook("disconnect","disconnectd");
190 #sub hook_kickd {
191 # &docommand("join $_[1]") if $_[0] eq $nick;
193 #&addhook("kick","kickd");
195 sub cmd_fcmd {
196 ($names,$mask,$command) = split(/ /, $args,3);
197 $mask =~ s/\!/\!/;
198 $mask =~ s/\@/\@/;
199 $mask =~ s/\./\\./g;
200 $mask =~ s/\*/.*/g;
201 &addhook("353","filtercommand");
202 &addhook("366","removefiltercommand");
203 &tell("\t\cb~4Matching /$mask/i on $names...");
204 &docommand("names $names");
206 &addcmd("fcmd");
208 sub hook_filtercommand {
209 ($shit, $_[0]) = split(/:/, $_[0]);
210 my @names = split(/ /, $_[0]);
211 for (@names) {
212 $_ =~ s/^\@//;
213 &userhost($_, "&dofilter");
215 $silent=1;
218 sub dofilter {
219 $s = "$who\!$user\@$host";
220 #&tell("$s =~ /$mask/");
221 if ($s =~ /$mask/i) {
222 $d = $command;
223 $d =~ s/\$1/$who/;
224 &docommand($d);
228 sub hook_removefiltercommand {
229 &remhook("353","filtercommand");
230 &remhook("366","removefiltercommand");
231 &tell("*\cbI\cb* Filter on $names, /$mask/i, Done.");
234 sub cmd_fc {
235 my ($mask, $cmd) = split(/ /, $args, 2);
236 &docommand("fcmd $talkchannel $mask $cmd");
238 &addcmd("fc");
240 sub cmd_pig {
241 $_[0] =~ s/^pig //i;
242 &say(&topiglatin($_[0]));
244 &addcmd("pig");
246 sub topiglatin {
247 @words = split(/ /, $_[0]);
248 for (@words) {
249 if ($_ =~ /^([bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])([aeiouAEIOU])/) {
250 $_ .= substr($_,0,1)."ay";
251 $_ = substr($_,1);
252 } elsif ($_ =~ /^([bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])([bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])/) {
253 $_ .= $1.$2."ay";
254 $_ = substr($_,2);
255 } elsif ($_ =~ /^[aeiouAEIOU]/) {
256 $_ .= "way";
257 } else {
258 print "shouldn't print me\n";
261 return "@words";
264 &addhelp("follow",
265 "\cbAdded by KSirc.pl\cb
266 Usage: follow <nick>
267 Highlight <nick> in colour when ever they say anything");
269 &addhelp("unfollow",
270 "\cbAdded by KSirc.pl\cb
271 Usage: unfollow <nick>
272 Stop highlighting the nick");
274 &addhelp("showfollows",
275 "\cbAdded by KSirc.pl\cb
276 Usage: showfollows
277 Shows who you are currently following");
279 #### Start follow script from caracas
281 &addcmd ('follow');
282 &addcmd ('unfollow');
283 &addcmd ('showfollows');
286 @follow_colors = ( '~1', '~2', '~3', '~4', '~5', '~6', '~7', '~8', '~9', '~10', '~11', '~12', '~13', '~14', '~15' );
287 undef %following;
290 sub cmd_follow
292 my ($fnick) = shift;
293 my ($color);
295 $fnick =~ s/^follow\s+//;
296 $fnick =~ tr/A-Z/a-z/;
297 if (defined ($following{$fnick}))
299 &tell ("*\cbI\cb* Already following " . $following{$fnick});
301 else
303 $color = $follow_colors [int (rand scalar (@follow_colors))];
304 &docommand ("^ksircappendrule DESC==Follow $fnick !!! " .
305 "SEARCH==<\\S*$fnick\\S*> !!! FROM==<\\S*($fnick)\\S*> !!! TO==\"<$color\$1~c>\"");
306 $following{$fnick} = "${color}${fnick}~c";
307 &tell ("*\cbI\cb* Following ${color}$fnick~c ...");
312 sub cmd_unfollow
314 my ($fnick) = shift;
315 my ($filter);
317 $fnick =~ s/^unfollow\s+//;
318 $fnick =~ tr/A-Z/a-z/;
319 for ($filter = 0; $filter <= $#KSIRC_FILTER; $filter++)
321 if ($KSIRC_FILTER [$filter]{'DESC'} =~ /Follow $fnick/i)
323 &docommand ("^ksircdelrule $filter");
324 delete ($following{$fnick});
325 &tell ("*\cbI\cb* $fnick no longer followed");
326 return;
329 &tell ("*\cbI\cb* Wasn't following $fnick");
333 sub cmd_showfollows
335 my ($fnick);
337 if (scalar (keys %following) > 0)
339 foreach $fnick (sort keys %following)
341 &tell ("*\cbI\cb* Following " . $following {$fnick});
344 else
346 &tell ("\*cbI\cb* Not currently following anyone");
350 #### End follow
352 sub cmd_refresh
354 &tell("*** Refresh nick list");
355 &docommand("^extnames_forget $dest_chan");
356 &docommand("extnames $dest_chan");
358 &addcmd("refresh");
360 sub hook_url_who_list {
361 my @info = split(/\s+/, $_[0]);
362 &print("*I* URL: http://$info[3]:<port>/");
363 $silent = 1;
366 sub hook_url_end_who {
367 &remhook("352", "url_who_list");
368 &remhook("315", "url_end_who");
369 $args = "";
372 &addhelp("url",
373 "\cbAdded by KSirc.pl\cb
374 Usage: URL
375 Prints out your url");
378 sub cmd_url
380 &addhook("352", "url_who_list");
381 &addhook("315", "url_end_who");
382 &sl("who :$nick");
384 &addcmd("url");
386 %WHO_IGNORE = "";
388 sub cmd_extnames
390 &dosplat;
391 &getarg;
392 $newarg =~ tr/A-Z/a-z/;
393 return if $WHO_IGNORE{$newarg} == 1;
394 if($who_active == 0){
395 &addhook("352", "ksirc_who_list");
396 &addhook("315", "ksirc_who_end");
398 &sl("who :$newarg");
399 $who_active++;
400 $WHO_INFO{$newarg} = "";
401 $WHO_TIME{$newarg} = 0;
402 $WHO_COUNT{$newarg} = 0;
404 &addcmd("extnames");
406 sub hook_ksirc_who_end {
407 $who_active--;
408 if($who_active == 0){
409 &remhook("352", "ksirc_who_list");
410 &remhook("315", "ksirc_who_end");
412 my @info = split(/\s+/, $_[0]);
413 # 0: our nick
414 # 1: channel
415 # 2 Onwards: misc info
416 $info[1] =~ tr/A-Z/a-z/;
417 chop($WHO_INFO{$info[1]}); # Remove trailing space
418 my $c = ($WHO_TIME{$info[1]} == 0) ? "C" : "!";
419 if(length($WHO_INFO{$info[1]}) > 0){
420 &print("~$info[1]~*$c* Users on $info[1]: $WHO_INFO{$info[1]}");
421 $WHO_COUNT{$info[1]}++;
423 &print("~$info[1]~*c* Done Parsing Who");
426 # print "*I* Parsing: extnames done, $info[1], count: " . $WHO_COUNT{$info[1]} . "\n";
427 if($WHO_COUNT{$info[1]} > 25){
428 if($WHO_IGNORE{$info[1]} != 1){
429 $WHO_IGNORE{$info[1]} = 1;
430 &print('*$*' . " Extended nick list info turned off for $info[1], too many people in channel\n");
431 &print("*I* Extended nick list info turned off for $info[1], too many people in channel\n");
434 else {
435 $WHO_IGNORE{$info[1]} = 0;
438 delete($WHO_COUNT{$info[1]});
439 delete($WHO_INFO{$info[1]});
440 delete($WHO_TIME{$info[1]});
441 $args = "";
444 sub hook_ksirc_who_list {
445 my @info = split(/\s+/, $_[0]);
446 # 0: our nick
447 # 1: channel
448 # 2: ident
449 # 3: one server
450 # 4: another server
451 # 5: nick
452 # 6: status
453 # 7: rest is useless
454 $silent = 1;
455 my $who_nick = $info[5];
456 # print "*I* Parsing: $_[0], info6: $info[6]\n";
457 if($info[6] =~ /G/){
458 $who_nick = "#" . $who_nick;
460 if($info[6] =~ /\+/){
461 $who_nick = "+" . $who_nick;
463 if($info[6] =~ /\@/){
464 $who_nick = "@" . $who_nick;
466 if($info[6] =~ /\*/){
467 $who_nick = "*" . $who_nick;
469 $info[1] =~ tr/A-Z/a-z/;
470 $WHO_COUNT{$info[1]}++;
472 $WHO_INFO{$info[1]} .= $who_nick . " ";
473 if(length($WHO_INFO{$info[1]}) > 350){
474 my $c = ($WHO_TIME{$info[1]} == 0) ? "C" : "!";
475 &print("~$info[1]~*$c* Users on $info[1]: $WHO_INFO{$info[1]}");
476 $WHO_INFO{$info[1]} = "";
477 $WHO_TIME{$info[1]}++;
481 sub cmd_extnames_forget
483 &dosplat;
484 &getarg;
485 $newarg =~ tr/A-Z/a-z/;
486 $WHO_IGNORE{$newarg} = 0;
489 &addcmd("extnames_forget");
491 sub hook_nicks_on_join {
492 my $channel = shift;
493 if(&eq($who, $nick)){
494 &docommand("^extnames_forget $channel");
496 &docommand("^extnames $channel");
499 addhook("join", "nicks_on_join");
502 &tell("*** \0032,4\cbLoaded KSirc.pl\003");
503 &tell("*** \00313,3\cbWith: Super Willy Enhancements, LotR's exec\003");
504 sub cmd_exec {
506 my $how, $to;
508 &getarg;
509 $how = "x";
510 if (&eq($newarg, "-OUT")) { $how = 'c'; }
511 if (&eq($newarg, "-MSG")) { $how = 'm'; &getarg; $to = $newarg; }
512 if (&eq($newarg, "-NOTICE")) { $how = 'n'; &getarg; $to = $newarg; }
513 if ($how eq "x") { $args = $newarg . " " . $args; }
514 open (CMD, "$args|");
515 while (<CMD>) {
516 chomp;
517 if ($how eq 'c') {
518 &say(" $_");
519 } elsif ($how eq 'm') {
520 &msg($to, $_);
521 } elsif ($how eq 'n') {
522 &notice($to, $_);
523 } else {
524 print "$_\n";
527 close CMD;
530 &addcmd("exec");
531 &addhelp("exec", "Usage: EXEC <shell commands>\n" .
532 "EXEC -OUT <shell commands]\n" .
533 "EXEC -MSG <nickname> <shell commands>]\n" .
534 "EXEC -NOTICE <nickname> <shell commands>]\n" );
536 $k_highlight = 1;
538 if(open(FH, "<$HOME/.ksirc_highlight")){
539 chomp($k_highlight = <FH>);
540 close(FH);
543 sub hook_fixcolours {
544 if($k_highlight == 1){
545 $_[1] =~ s/(^|\s)\*([^*]+?)\*($|\s)/$1\002$2\002$3/g;
546 $_[1] =~ s/(^|\s)_([^_]+?)_($|\s)/$1\037$2\037$3/g;
547 $_[1] =~ s/(^|\s)#([^#]+?)#($|\s)/$1\026$2\026$3/g;
551 &addhook("send_text", "fixcolours");
553 sub cmd_dishighlight {
555 print "*I* Highlight parsing: ";
556 if($k_highlight == 0) {
557 $k_highlight = 1;
558 print "Enabled\n";
560 else {
561 $k_highlight = 0;
562 print "Disabled\n";
565 if(open(FH, ">$ENV{HOME}/.ksirc_highlight")){
566 print FH "$k_highlight\n";
567 close(FH);
569 else {
570 print "*E* Can't save highlight state $!\n";
575 &addcmd("dishighlight");
576 &addhelp("dishighlight", "Usage: dishighlight\n" .
577 "Toggles the convertion of *bold* into \cbbold\cb\n" .
578 "and _underline_ into \c_underline\c_ and #reverse#\n" .
579 "into \cvreverse\cv. It saves the state into\n" .
580 "~/.ksirc_highlight for convenience");
582 sub cmd_help {
583 &tell("*\cbH\cb* Help not available"), return unless @help;
584 my $found ='';
586 &getarg;
587 if($newarg =~ /^\s*$/){
588 my $line = '';
589 my %once;
590 foreach (@help) {
591 if (/^\@/) {
592 if (&eq($_, "\@main")) {
593 $found=1;
594 &tell("*\cbH\cb* Help on $newarg") if $newarg ne 'main'; # KSIRC MOD
596 else {
597 $found=0;
600 else {
601 &tell("*\cbH\cb* $_") if $found;
604 foreach (@help) {
605 if(/^\@/){
606 if(!&eq($_, "\@main")){
607 $found = 0;
608 my $cmd = /\@(\S+)/;
609 next if $once{$1};
610 $once{$1} = 1;
611 $line .= "$1 " . " "x(15-length("$1 ")); # KSIRC MOD
612 if(length($line) > 50){
613 &tell("*\cbH\cb* $line");
614 $line = "";
619 &tell("*\cbH\cb* $line");
620 $found=1;
622 else{
623 $newarg =~ s/ *$//;
624 foreach (@help) {
625 if (/^\@/) {
626 last if $found;
627 if (&eq($_, "\@$newarg")) {
628 $found=1;
629 &tell("*\cbH\cb* Help on $newarg") if $newarg ne 'main';
631 } else {
632 &tell("*\cbH\cb* $_") if $found;
635 } # KSIRC MOD
636 &tell("*\cbH\cb* Unknown help topic; try /help") unless $found;
639 &addcmd("help");
642 # New DCC resume/get features
645 my %A_RESUME_WAIT = ();
647 sub hook_ctcp_resume_reply {
648 my $towho = shift;
649 my $what = shift;
650 my $args = shift;
652 if($what eq 'DCC'){
653 my ($which, $file, $port, $pos) = split(/ +/, $args);
654 &tell("Got which: $which");
655 if($which eq 'ACCEPT'){
656 # &print("Got resume from $who port $port file: $file pos: $pos args: $args");
657 if($A_RESUME_WAIT{$port}){
658 &print("*\cbI\cb* DCC Resume with $who accepted");
659 &tell("~!dcc~DCC GET resumed who: $who file: " . $dgresume{$port}{"file"});
660 &tell("~!dcc~DCC GET read: " . $dgresume{$port}{"file"} . " bytes: " . $dgresume{$port}{"pos"}); # KSIRC MOD FOR 971217
661 $dgresume{$port}{"GotReply"} = 1;
662 delete $A_RESUME_WAIT{$port};
663 $skip = 1;
665 if($A_AUTOSTART{$port}){
666 &docommand($A_AUTOSTART{$port});
667 delete $A_AUTOSTART{$port};
671 elsif($which eq 'RESUME'){
672 my($lfh, $myport);
673 while(($lfh, $myport) = each %dsport){
674 if($port == $myport){
675 $skip = 1;
676 my $size = (-s $dfile{$dswait{$lfh}});
677 if($pos < $size){
678 seek($dswait{$lfh}, $pos, SEEK_SET);
679 $dsoffset{$lfh} = $pos;
680 &docommand("ctcp $who DCC ACCEPT $file $port $pos");
681 &tell("~!dcc~DCC SEND resumed who: $who file: " . $dfile{$dswait{$lfh}});
682 &tell("~!dcc~DCC SEND write: " . $dfile{$dswait{$lfh}} . " bytes: " . $pos); # KSIRC MOD FOR 971217
684 else {
685 &tell("*\cbE\cb* Got DCC resume with invalid size from $who for " . $dfile{$dswait{$lfh}});
693 &addhook("ctcp", "ctcp_resume_reply");
695 sub hook_ctcp_reject_reply {
696 my $towho = shift;
697 my $what = shift;
698 my $args = shift;
700 if($what eq 'DCC'){
701 my ($which, $type, $file) = split(/ +/, $args);
702 if($which eq 'REJECT'){
703 &tell("Got reject");
704 if($type eq 'CHAT'){
705 $no_reject = 1;
706 &tell("*\cbI\cb* DCC CHAT with $who rejected");
707 &docommand("/dcc close chat $who");
708 $skip = 1;
710 elsif($type eq 'GET'){
711 $no_reject = 1;
712 &tell("*\cbI\cb* DCC GET rejected by $who for $file");
713 &docommand("/dcc close get $who $file");
714 $skip = 1;
716 elsif($type eq 'SEND'){
717 $no_reject = 1;
718 &tell("*\cbI\cb* DCC SEND rejected by $who file $file");
719 &docommand("/dcc close send $who $file");
720 $skip = 1;
726 &addhook("ctcp_reply", "ctcp_reject_reply");
728 sub cmd_resume {
729 &getarg;
730 my $who = $newarg;
731 &getarg;
732 my $file = $newarg;
734 foreach $i (keys(%dgoffered)) {
735 my($h, $p, $f) = split(/ /, $i);
736 if (&eq($f, $file) && &eq($dgoffered{$i}, $who)) {
737 if(my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
738 $atime,$mtime,$ctime,$blksize,$blocks)
739 = stat($file)){
740 &print("*\cbI\cb* Doing resume for $f with $who ($p)");
741 &docommand("ctcp $who DCC RESUME $f $p $size");
742 $dgresume{$p}{"pos"} = $size;
743 $dgresume{$p}{"file"} = $f;
744 $dgresume{$p}{"who"} = $who;
745 $A_RESUME_WAIT{$p} = 1;
747 else {
748 &print("*\cbE\cb* Error getting file ($file) size: $!");
754 &addcmd("resume");
757 sub cmd_amarok
759 $dcop=`dcop amarok`;
760 if(! ($dcop =~ /player/) ) {
761 &print("Error: Amarok is *not* running");
762 return;
765 $dcop=`dcop amarok player isPlaying`;
766 if(! ($dcop =~ /true/) ) {
767 &print("Amarok is not playing anything");
768 return
771 $output='is playing "$dcop" with Amarok';
772 $dcop= `dcop amarok player nowPlaying` ;
773 $dcop =~ s/^\s+//;
774 $dcop =~ s/\s+$//;
775 $output=~ s/(\$\w+)/$1/eeg;
776 &me( $output );
778 &addcmd("amarok");