From 3f65d48264430428a2165f6a9f5a4e16f823f6b8 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Thu, 19 May 2016 19:49:39 -0400 Subject: Start new design docs --- lib/IRC/Client.pm6 | 174 ------------------------------------- lib/IRC/Client/Plugin.pm6 | 3 - lib/IRC/Client/Plugin/Debugger.pm6 | 8 -- lib/IRC/Client/Plugin/PingPong.pm6 | 2 - lib/IRC/Grammar.pm6 | 20 ----- lib/IRC/Grammar/Actions.pm6 | 26 ------ lib/IRC/Parser.pm6 | 7 -- 7 files changed, 240 deletions(-) delete mode 100644 lib/IRC/Client/Plugin.pm6 delete mode 100644 lib/IRC/Client/Plugin/Debugger.pm6 delete mode 100644 lib/IRC/Client/Plugin/PingPong.pm6 delete mode 100644 lib/IRC/Grammar.pm6 delete mode 100644 lib/IRC/Grammar/Actions.pm6 delete mode 100644 lib/IRC/Parser.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 700739c..e69de29 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -1,174 +0,0 @@ -use v6; -use IRC::Parser; # parse-irc -use IRC::Client::Plugin::PingPong; -use IRC::Client::Plugin; -unit class IRC::Client; - -has Bool:D $.debug = False; -has Str:D $.host = 'localhost'; -has Str $.password; -has Int:D $.port where 0 <= $_ <= 65535 = 6667; -has Str:D $.nick = 'Perl6IRC'; -has Str:D $.username = 'Perl6IRC'; -has Str:D $.userhost = 'localhost'; -has Str:D $.userreal = 'Perl6 IRC Client'; -has Str:D @.channels = ['#perl6bot']; -has IO::Socket::Async $.sock; -has @.plugins = []; -has @.plugins-essential = [ - IRC::Client::Plugin::PingPong.new -]; -has @!plugs = [|@!plugins-essential, |@!plugins]; - -method handle-event ($e) { - $e = {}; - - for @!plugs.grep(*.^can: 'irc-all-events') -> $p { - my $res = $p.irc-all-events(self, $e); - return unless $res === IRC_NOT_HANDLED; - } - - # Wait for END_MOTD or ERR_NOMOTD before attempting to join - if $e eq '422' | '376' { - $.ssay("JOIN {@!channels[]}\n"); - .irc-connected: self for @!plugs.grep(*.^can: 'irc-connected'); - } - - my $nick = $!nick; - if ( ( $e eq 'PRIVMSG' and $e[0] eq $nick ) - or ( $e eq 'NOTICE' and $e[0] eq $nick ) - or ( $e eq 'PRIVMSG' - and $e[1] ~~ /:i ^ $nick <[,:]> \s+/ - ) - ) { - my %res = :where($e ), - :who( $e ), - :how( $e ), - :what( $e[1] ); - - %res = $e[0] # this message was said in the channel - unless ( $e eq 'PRIVMSG' and $e[0] eq $nick ) - or ( $e eq 'NOTICE' and $e[0] eq $nick ); - - %res.subst-mutate: /:i ^ $nick <[,:]> \s+/, '' - if %res ~~ /^ <[#&]>/; - - for @!plugs.grep(*.^can: 'irc-to-me') -> $p { - my $res = $p.irc-to-me(self, $e, %res); - return unless $res === IRC_NOT_HANDLED; - } - } - - if ( $e eq 'PRIVMSG' and $e[0] eq $!nick ) { - for @!plugs.grep(*.^can: 'irc-privmsg-me') -> $p { - my $res = $p.irc-privmsg-me(self, $e); - return unless $res === IRC_NOT_HANDLED; - } - } - - if ( $e eq 'NOTICE' and $e[0] eq $!nick ) { - for @!plugs.grep(*.^can: 'irc-notice-me') -> $p { - my $res = $p.irc-notice-me(self, $e); - return unless $res === IRC_NOT_HANDLED; - } - } - - my $cmd = 'irc-' ~ $e.lc; - for @!plugs.grep(*.^can: $cmd) -> $p { - my $res = $p."$cmd"(self, $e); - return unless $res === IRC_NOT_HANDLED; - } - - for @!plugs.grep(*.^can: 'irc-unhandled') -> $p { - my $res = $p.irc-unhandled(self, $e); - return unless $res === IRC_NOT_HANDLED; - } -} - -method notice (Str $who, Str $what) { - my $msg = "NOTICE $who :$what\n"; - $!debug and "{plug-name}$msg".put; - $!sock.print("$msg\n"); - self; -} - -method privmsg (Str $who, Str $what) { - my $msg = "PRIVMSG $who :$what\n"; - $!debug and "{plug-name}$msg".put; - $!sock.print("$msg\n"); - self; -} - -method respond ( - Str:D :$how = 'privmsg', - Str:D :$where is required, - Str:D :$what is required is copy, - Str:D :$who, - :$when where Any|Dateish|Instant; - # TODO: remove Any: https://rt.perl.org/Ticket/Display.html?id=127142 -) { - $what = "$who, $what" if $who and $where ~~ /^<[#&]>/; - my $method = $how.fc eq 'PRIVMSG'.fc ?? 'privmsg' - !! $how.fc eq 'NOTICE'.fc ?? 'notice' - !! fail 'Unknown :$how specified. Use PRIVMSG or NOTICE'; - - if $when { - Promise.at($when).then: { self."$method"($where, $what) }; - CATCH { warn .backtrace } - } - else { - self."$method"($where, $what); - } - self; -} - -method run { - .irc-start-up: self for @!plugs.grep(*.^can: 'irc-start-up'); - - await IO::Socket::Async.connect( $!host, $!port ).then({ - $!sock = .result; - $.ssay("PASS $!password\n") if $!password.defined; - $.ssay("NICK $!nick\n"); - $.ssay("USER $!username $!username $!host :$!userreal\n"); - - # my $left-overs = ''; - react { - whenever $!sock.Supply :bin -> $buf is copy { - my $str = try $buf.decode: 'utf8'; - $str or $str = $buf.decode: 'latin-1'; - # $str ~= $left-overs; - $!debug and "[server {DateTime.now}] {$str}".put; - my $events = parse-irc $str; - for @$events -> $e { - self.handle-event: $e; - CATCH { warn .backtrace } - } - } - - CATCH { warn .backtrace } - } - - say "Closing connection"; - $!sock.close; - - # CATCH { warn .backtrace } - }); -} - -method ssay (Str:D $msg) { - $!debug and "{plug-name}$msg".put; - $!sock.print("$msg\n"); - self; -} - -#### HELPER SUBS - -sub plug-name { - my $plug = callframe(3).file; - my $cur = $?FILE; - return '[core] ' if $plug eq $cur; - $cur ~~ s/'.pm6'$//; - $plug ~~ s:g/^ $cur '/' | '.pm6'$//; - $plug ~~ s/'/'/::/; - return "[$plug] "; -} diff --git a/lib/IRC/Client/Plugin.pm6 b/lib/IRC/Client/Plugin.pm6 deleted file mode 100644 index d73d7bd..0000000 --- a/lib/IRC/Client/Plugin.pm6 +++ /dev/null @@ -1,3 +0,0 @@ -constant IRC_HANDLED = "irc plugin handled \x1"; -constant IRC_NOT_HANDLED = "irc plugin not-handled \x2"; -unit class IRC::Client::Plugin; diff --git a/lib/IRC/Client/Plugin/Debugger.pm6 b/lib/IRC/Client/Plugin/Debugger.pm6 deleted file mode 100644 index 13b1461..0000000 --- a/lib/IRC/Client/Plugin/Debugger.pm6 +++ /dev/null @@ -1,8 +0,0 @@ -use Data::Dump; -use IRC::Client::Plugin; -unit class IRC::Client::Plugin::Debugger is IRC::Client::Plugin; - -method irc-all-events ($irc, $e) { - say Dump $e, :indent(4); - return IRC_NOT_HANDLED; -} diff --git a/lib/IRC/Client/Plugin/PingPong.pm6 b/lib/IRC/Client/Plugin/PingPong.pm6 deleted file mode 100644 index 2651fd6..0000000 --- a/lib/IRC/Client/Plugin/PingPong.pm6 +++ /dev/null @@ -1,2 +0,0 @@ -unit class IRC::Client::Plugin::PingPong; -method irc-ping ($irc, $e) { $irc.ssay("PONG {$irc.nick} $e[0]") } diff --git a/lib/IRC/Grammar.pm6 b/lib/IRC/Grammar.pm6 deleted file mode 100644 index c05322c..0000000 --- a/lib/IRC/Grammar.pm6 +++ /dev/null @@ -1,20 +0,0 @@ -unit grammar IRC::Grammar; -token TOP { + } -token SPACE { ' '+ } -token message { [':' ]? \n } - token prefix { - [ || ['!' ]? ['@' ]? ] - > - } - token servername { } - token nick { [ | | ]* } - token user { <-[\ \x0\r\n]>+? | '@']>} - token host { <-[\s!@]>+ } - token command { + | **3 } - token params { * [ ':' | ]? } - token middle { <-[:\ \x0\r\n]> <-[\ \x0\r\n]>* } - token trailing { <-[\x0\r\n]>* } - - token letter { <[a..zA..Z]> } - token number { <[0..9]> } - token special { <[-_\[\]\\`^{}]> } diff --git a/lib/IRC/Grammar/Actions.pm6 b/lib/IRC/Grammar/Actions.pm6 deleted file mode 100644 index 234e392..0000000 --- a/lib/IRC/Grammar/Actions.pm6 +++ /dev/null @@ -1,26 +0,0 @@ -unit class IRC::Grammar::Actions; -method TOP ($/) { $/.make: $>>.made } -method message ($/) { - my $pref = $/; - my %args = command => ~$/; - for qw/nick user host/ { - $pref{$_}.defined or next; - %args{$_} = $pref{$_}.Str; - } - %args = ~$pref if $pref.defined; - - my $p = $/; - - for ^100 { # bail out after 100 iterations; we're stuck - if ( $p.defined ) { - %args.append: ~$p; - } - if ( $p.defined ) { - %args.append: ~$p; - last; - } - $p = $p; - } - - $/.make: %args; -} diff --git a/lib/IRC/Parser.pm6 b/lib/IRC/Parser.pm6 deleted file mode 100644 index dda05e6..0000000 --- a/lib/IRC/Parser.pm6 +++ /dev/null @@ -1,7 +0,0 @@ -use IRC::Grammar; -use IRC::Grammar::Actions; -unit class IRC::Parser; - -sub parse-irc (Str:D $input) is export { - IRC::Grammar.parse($input, actions => IRC::Grammar::Actions).made // []; -} -- cgit v1.1 From 0daa494480f7abe37a6e593c6238811009b7b914 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Fri, 3 Jun 2016 07:01:14 -0400 Subject: Start rewrite --- lib/IRC/Client.pm6 | 56 ++++++++++++++++++++++++++++++++++++++ lib/IRC/Client/Grammar.pm6 | 21 ++++++++++++++ lib/IRC/Client/Grammar/Actions.pm6 | 31 +++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 lib/IRC/Client/Grammar.pm6 create mode 100644 lib/IRC/Client/Grammar/Actions.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index e69de29..7c30c4a 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -0,0 +1,56 @@ +unit class IRC::Client; + +use IRC::Client::Grammar; +use IRC::Client::Grammar::Actions; + +has Str:D $.host = 'localhost'; +has Bool $.debug = False; +has Str $.password; +has Int:D $.port where 0 <= $_ <= 65535 = 6667; +has Str:D $.nick = 'Perl6IRC'; +has Str:D $.username = 'Perl6IRC'; +has Str:D $.userhost = 'localhost'; +has Str:D $.userreal = 'Perl6 IRC Client'; +has Str:D @.channels = ['#perl6']; +has @.plugins; +has IO::Socket::Async $!sock; + +method run { + await IO::Socket::Async.connect( $!host, $!port ).then({ + $!sock = .result; + self!ssay: "PASS $!password\n" if $!password.defined; + self!ssay: "NICK $!nick\n"; + self!ssay: "USER $!username $!username $!host :$!userreal\n"; + + my $left-overs = ''; + react { + whenever $!sock.Supply :bin -> $buf is copy { + my $str = try $buf.decode: 'utf8'; + $str or $str = $buf.decode: 'latin-1'; + $str ~= $left-overs; + $!debug and "[server {DateTime.now}] {$str}".put; + (my $events, $left-overs) = IRC::Client::Grammar.parse( + $str, actions => IRC::Client::Grammar::Actions + ).made; + + for @$events -> $e { + say "[event] $e"; + CATCH { warn .backtrace } + } + } + + CATCH { warn .backtrace } + } + + say "Closing connection"; + $!sock.close; + + # CATCH { warn .backtrace } + }); +} + +method !ssay (Str:D $msg) { + $!debug and "$msg".put; + $!sock.print("$msg\n"); + self; +} diff --git a/lib/IRC/Client/Grammar.pm6 b/lib/IRC/Client/Grammar.pm6 new file mode 100644 index 0000000..255528a --- /dev/null +++ b/lib/IRC/Client/Grammar.pm6 @@ -0,0 +1,21 @@ +unit grammar IRC::Client::Grammar; +token TOP { + } +token leftovers { \N* } +token SPACE { ' '+ } +token message { [':' ]? \n } + token prefix { + [ || ['!' ]? ['@' ]? ] + > + } + token servername { } + token nick { [ | | ]* } + token user { <-[\ \x0\r\n]>+? | '@']>} + token host { <-[\s!@]>+ } + token command { + | **3 } + token params { * [ ':' | ]? } + token middle { <-[:\ \x0\r\n]> <-[\ \x0\r\n]>* } + token trailing { <-[\x0\r\n]>* } + + token letter { <[a..zA..Z]> } + token number { <[0..9]> } + token special { <[-_\[\]\\`^{}]> } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 new file mode 100644 index 0000000..74ae4e8 --- /dev/null +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -0,0 +1,31 @@ +unit class IRC::Client::Grammar::Actions; + +method TOP ($/) { $/.make: ($».made, $) } +method left-overs ($/) { + $/.made: $/.defined ?? !$/ !! ''; +} + +method message ($/) { + my $pref = $/; + my %args = command => ~$/; + for qw/nick user host/ { + $pref{$_}.defined or next; + %args{$_} = $pref{$_}.Str; + } + %args = ~$pref if $pref.defined; + + my $p = $/; + + for ^100 { # bail out after 100 iterations; we're stuck + if ( $p.defined ) { + %args.append: ~$p; + } + if ( $p.defined ) { + %args.append: ~$p; + last; + } + $p = $p; + } + + $/.make: %args; +} -- cgit v1.1 From cb0a6cace8871d17c9701edc1ccba26d1e6e0bfe Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sat, 4 Jun 2016 10:32:49 -0400 Subject: Wtf --- lib/IRC/Client.pm6 | 30 +++++++++++++++++------------- lib/IRC/Client/Grammar.pm6 | 6 +++--- lib/IRC/Client/Grammar/Actions.pm6 | 34 +++++++++++++++++++++++++++++----- lib/IRC/Client/Message.pm6 | 9 +++++++++ lib/IRC/Client/Message/Numeric.pm6 | 4 ++++ 5 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 lib/IRC/Client/Message.pm6 create mode 100644 lib/IRC/Client/Message/Numeric.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 7c30c4a..7d8369a 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -13,6 +13,7 @@ has Str:D $.userhost = 'localhost'; has Str:D $.userreal = 'Perl6 IRC Client'; has Str:D @.channels = ['#perl6']; has @.plugins; +has @.servers; has IO::Socket::Async $!sock; method run { @@ -28,24 +29,17 @@ method run { my $str = try $buf.decode: 'utf8'; $str or $str = $buf.decode: 'latin-1'; $str ~= $left-overs; - $!debug and "[server {DateTime.now}] {$str}".put; - (my $events, $left-overs) = IRC::Client::Grammar.parse( - $str, actions => IRC::Client::Grammar::Actions - ).made; - - for @$events -> $e { - say "[event] $e"; - CATCH { warn .backtrace } - } + + (my $events, $left-overs) = self!parse: $str; + # for @$events -> $e { + # say "[event] $e"; + # CATCH { warn .backtrace } + # } } CATCH { warn .backtrace } } - - say "Closing connection"; $!sock.close; - - # CATCH { warn .backtrace } }); } @@ -54,3 +48,13 @@ method !ssay (Str:D $msg) { $!sock.print("$msg\n"); self; } + +method !parse (Str:D $str) { + return IRC::Client::Grammar.parse( + $str, + actions => IRC::Client::Grammar::Actions.new( + irc => self, + server => 'dummy', + ), + ).made; +} diff --git a/lib/IRC/Client/Grammar.pm6 b/lib/IRC/Client/Grammar.pm6 index 255528a..a258e56 100644 --- a/lib/IRC/Client/Grammar.pm6 +++ b/lib/IRC/Client/Grammar.pm6 @@ -9,12 +9,12 @@ token message { [':' ]? \n } } token servername { } token nick { [ | | ]* } - token user { <-[\ \x0\r\n]>+? | '@']>} + token user { <-[\ \x[0]\r\n]>+? | '@']>} token host { <-[\s!@]>+ } token command { + | **3 } token params { * [ ':' | ]? } - token middle { <-[:\ \x0\r\n]> <-[\ \x0\r\n]>* } - token trailing { <-[\x0\r\n]>* } + token middle { <-[:\ \x[0]\r\n]> <-[\ \x[0]\r\n]>* } + token trailing { <-[\x[0]\r\n]>* } token letter { <[a..zA..Z]> } token number { <[0..9]> } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index 74ae4e8..3e190cd 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -1,22 +1,28 @@ unit class IRC::Client::Grammar::Actions; +use IRC::Client::Message::Numeric; + +has $.irc; +has $.server; + method TOP ($/) { $/.make: ($».made, $) } + method left-overs ($/) { $/.made: $/.defined ?? !$/ !! ''; } method message ($/) { + my %args; my $pref = $/; - my %args = command => ~$/; for qw/nick user host/ { $pref{$_}.defined or next; - %args{$_} = $pref{$_}.Str; + %args{$_} = ~$pref{$_}; } %args = ~$pref if $pref.defined; - my $p = $/; + my $p = $; - for ^100 { # bail out after 100 iterations; we're stuck + loop { if ( $p.defined ) { %args.append: ~$p; } @@ -27,5 +33,23 @@ method message ($/) { $p = $p; } - $/.make: %args; + my %msg-args = + irc => $!irc, + nick => %args, + username => %args, + host => %args, + usermask => "%args!%args@%args", + server => $!server; + + my $msg; + given ~$ { + when /^ ([0..9]**3) $/ { + $msg = IRC::Client::Message::Numeric.new: + :command( $ ), + :args( %args ), + |%msg-args; + } + } + + $/.make: $msg; } diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 new file mode 100644 index 0000000..6670baa --- /dev/null +++ b/lib/IRC/Client/Message.pm6 @@ -0,0 +1,9 @@ +unit role IRC::Client::Message; + +has $.irc; +has $.nick; +has $.username; +has $.host; +has $.usermask; +has $.server; +has $.command; diff --git a/lib/IRC/Client/Message/Numeric.pm6 b/lib/IRC/Client/Message/Numeric.pm6 new file mode 100644 index 0000000..c57c3c2 --- /dev/null +++ b/lib/IRC/Client/Message/Numeric.pm6 @@ -0,0 +1,4 @@ +use IRC::Client::Message; +unit role IRC::Client::Message::Numeric does IRC::Client::Message; + +has @.args; -- cgit v1.1 From 791d7981cff0cd3a85fdd504f410a7c9833272dc Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sat, 4 Jun 2016 15:16:43 -0400 Subject: More stuff --- lib/IRC/Client.pm6 | 28 ++++++++++++++++++++-------- lib/IRC/Client/Grammar/Actions.pm6 | 33 +++++++++++++++++---------------- lib/IRC/Client/Message.pm6 | 14 +++++++------- lib/IRC/Client/Message/Numeric.pm6 | 2 ++ 4 files changed, 46 insertions(+), 31 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 7d8369a..3fca5ae 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -19,9 +19,9 @@ has IO::Socket::Async $!sock; method run { await IO::Socket::Async.connect( $!host, $!port ).then({ $!sock = .result; - self!ssay: "PASS $!password\n" if $!password.defined; - self!ssay: "NICK $!nick\n"; - self!ssay: "USER $!username $!username $!host :$!userreal\n"; + self!ssay: "PASS $!password" if $!password.defined; + self!ssay: "NICK $!nick"; + self!ssay: "USER $!username $!username $!host :$!userreal"; my $left-overs = ''; react { @@ -31,10 +31,10 @@ method run { $str ~= $left-overs; (my $events, $left-overs) = self!parse: $str; - # for @$events -> $e { - # say "[event] $e"; - # CATCH { warn .backtrace } - # } + for $events.grep: *.defined -> $e { + $!debug and debug-print $e; + CATCH { warn .backtrace } + } } CATCH { warn .backtrace } @@ -44,7 +44,7 @@ method run { } method !ssay (Str:D $msg) { - $!debug and "$msg".put; + $!debug and debug-print $msg; $!sock.print("$msg\n"); self; } @@ -58,3 +58,15 @@ method !parse (Str:D $str) { ), ).made; } + +sub debug-print ($str, $dir where * eq 'in' | 'out') { + state $color = try { + require Terminal::ANSIColor; + $color = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&color>; + } // sub (Str $s) { '' }; + + put ( $dir eq 'in' + ?? $color('bold blue' ) ~ '▬▬▬▶ ' + !! $color('bold green') ~ '◀▬▬▬ ' + ) ~ $color('bold red') ~ join $color('reset'), $str.split: ' ', 2; +} diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index 3e190cd..54943bd 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -5,23 +5,23 @@ use IRC::Client::Message::Numeric; has $.irc; has $.server; -method TOP ($/) { $/.make: ($».made, $) } - -method left-overs ($/) { - $/.made: $/.defined ?? !$/ !! ''; +method TOP ($/) { + $/.make: ( + $».made, + ~( $ // '' ), + ); } -method message ($/) { +method message ($match) { my %args; - my $pref = $/; + my $pref = $match; for qw/nick user host/ { $pref{$_}.defined or next; %args{$_} = ~$pref{$_}; } %args = ~$pref if $pref.defined; - my $p = $; - + my $p = $match; loop { if ( $p.defined ) { %args.append: ~$p; @@ -30,26 +30,27 @@ method message ($/) { %args.append: ~$p; last; } + last unless $p.defined; $p = $p; } my %msg-args = irc => $!irc, - nick => %args, - username => %args, - host => %args, - usermask => "%args!%args@%args", + nick => %args//'', + username => %args//'', + host => %args//'', server => $!server; + . = . ~ '!' ~ . ~ '@' ~ . given %msg-args; my $msg; - given ~$ { - when /^ ([0..9]**3) $/ { + given ~$match { + when /^ $=(<[0..9]>**3) $/ { $msg = IRC::Client::Message::Numeric.new: - :command( $ ), + :command( ~$ ), :args( %args ), |%msg-args; } } - $/.make: $msg; + $match.make: $msg; } diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 6670baa..69e7c82 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -1,9 +1,9 @@ unit role IRC::Client::Message; -has $.irc; -has $.nick; -has $.username; -has $.host; -has $.usermask; -has $.server; -has $.command; +has $.irc is required; +has Str:D $.nick is required; +has Str:D $.username is required; +has Str:D $.host is required; +has Str:D $.usermask is required; +has Str:D $.command is required; +has Str:D $.server is required; diff --git a/lib/IRC/Client/Message/Numeric.pm6 b/lib/IRC/Client/Message/Numeric.pm6 index c57c3c2..38e9a26 100644 --- a/lib/IRC/Client/Message/Numeric.pm6 +++ b/lib/IRC/Client/Message/Numeric.pm6 @@ -2,3 +2,5 @@ use IRC::Client::Message; unit role IRC::Client::Message::Numeric does IRC::Client::Message; has @.args; + +method Str { "$.command @.args[]" } -- cgit v1.1 From 5a2196b2c8f2ac2eacb3ddaf40b3e75b9c38bb62 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sat, 4 Jun 2016 19:18:31 -0400 Subject: Stuff --- lib/IRC/Client.pm6 | 57 +++++++++++++++++++---- lib/IRC/Client/Grammar/Actions.pm6 | 74 +++++++++++++++++++++++++----- lib/IRC/Client/Message.pm6 | 42 +++++++++++++---- lib/IRC/Client/Message/Numeric.pm6 | 4 -- lib/IRC/Client/Message/Privmsg.pm6 | 4 ++ lib/IRC/Client/Message/Privmsg/Channel.pm6 | 5 ++ lib/IRC/Client/Message/Privmsg/Me.pm6 | 2 + lib/IRC/Client/Message/Unknown.pm6 | 4 ++ 8 files changed, 158 insertions(+), 34 deletions(-) create mode 100644 lib/IRC/Client/Message/Privmsg.pm6 create mode 100644 lib/IRC/Client/Message/Privmsg/Channel.pm6 create mode 100644 lib/IRC/Client/Message/Privmsg/Me.pm6 create mode 100644 lib/IRC/Client/Message/Unknown.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 3fca5ae..0c836a4 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -25,26 +25,46 @@ method run { my $left-overs = ''; react { + CATCH { warn .backtrace } + whenever $!sock.Supply :bin -> $buf is copy { my $str = try $buf.decode: 'utf8'; $str or $str = $buf.decode: 'latin-1'; $str ~= $left-overs; (my $events, $left-overs) = self!parse: $str; + $str ~~ /$=(\N*)$/; + dd $str; + say "#### SHOULD Left over: `$`"; + say "#### LEFT OVERS: `$left-overs`"; for $events.grep: *.defined -> $e { - $!debug and debug-print $e; CATCH { warn .backtrace } + $!debug and debug-print $e, 'in'; + self!handle-event: $e; } } - - CATCH { warn .backtrace } } $!sock.close; }); } +method send-cmd ($cmd, *@args) { + @args[*-1] = ':' ~ @args[*-1]; + self!ssay: join ' ', $cmd, @args; +} + +method !handle-event ($e) { + given $e.command { + when '001' { self!ssay: "JOIN @.channels[]"; } + when 'PING' { $e.reply } + when 'JOIN' { + say "Joined channel $e.channel()"; + } + } +} + method !ssay (Str:D $msg) { - $!debug and debug-print $msg; + $!debug and debug-print $msg, 'out'; $!sock.print("$msg\n"); self; } @@ -59,14 +79,31 @@ method !parse (Str:D $str) { ).made; } -sub debug-print ($str, $dir where * eq 'in' | 'out') { - state $color = try { +sub debug-print (Str(Any) $str, $dir where * eq 'in' | 'out') { + state $colored = try { require Terminal::ANSIColor; - $color = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&color>; + $colored = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; } // sub (Str $s) { '' }; + my @out; + if $str ~~ /^ '❚⚠❚'/ { + @out = $str.split: ' ', 3; + @out[0] = $colored(@out[0], 'bold white on_red'); + @out[1] = @out[1] ~~ /^ <[0..9]>**3 $/ + ?? $colored(@out[1], 'bold red') + !! $colored(@out[1], 'bold magenta'); + @out[2] = $colored(@out[2], 'bold cyan'); + } + else { + @out = $str.split: ' ', 2; + @out[0] = @out[0] ~~ /^ <[0..9]>**3 $/ + ?? $colored(@out[0], 'bold red') + !! $colored(@out[0], 'bold magenta'); + @out[1] = $colored(@out[1], 'bold cyan'); + } + put ( $dir eq 'in' - ?? $color('bold blue' ) ~ '▬▬▬▶ ' - !! $color('bold green') ~ '◀▬▬▬ ' - ) ~ $color('bold red') ~ join $color('reset'), $str.split: ' ', 2; + ?? $colored('▬▬▶ ', 'bold blue' ) + !! $colored('◀▬▬ ', 'bold green') + ) ~ @out.join: ' '; } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index 54943bd..6ebe33d 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -1,6 +1,6 @@ unit class IRC::Client::Grammar::Actions; -use IRC::Client::Message::Numeric; +use IRC::Client::Message; has $.irc; has $.server; @@ -23,9 +23,8 @@ method message ($match) { my $p = $match; loop { - if ( $p.defined ) { - %args.append: ~$p; - } + %args.append: ~$p if $p.defined; + if ( $p.defined ) { %args.append: ~$p; last; @@ -35,22 +34,75 @@ method message ($match) { } my %msg-args = + command => $match.uc, + args => %args, + host => %args//'', irc => $!irc, nick => %args//'', - username => %args//'', - host => %args//'', - server => $!server; + server => $!server, + username => %args//''; . = . ~ '!' ~ . ~ '@' ~ . given %msg-args; my $msg; - given ~$match { + given %msg-args { when /^ $=(<[0..9]>**3) $/ { - $msg = IRC::Client::Message::Numeric.new: - :command( ~$ ), - :args( %args ), + $msg = IRC::Client::Message::Numeric.new: |%msg-args; + } + when 'JOIN' { + $msg = IRC::Client::Message::Join.new: + :channel( %args[0] ), |%msg-args; } + when 'NOTICE' { $msg = msg-notice %args, %msg-args } + when 'MODE' { $msg = msg-mode %args, %msg-args } + when 'PING' { $msg = IRC::Client::Message::Ping.new: |%msg-args; } + when 'PRIVMSG' { $msg = msg-privmsg %args, %msg-args } + default { $msg = IRC::Client::Message::Unknown.new: |%msg-args } } $match.make: $msg; } + +sub msg-privmsg (%args, %msg-args) { + %args[0] ~~ /^<[#&]>/ + and return IRC::Client::Message::Privmsg::Channel.new: + :channel( %args[0] ), + :text( %args[1] ), + |%msg-args; + + return IRC::Client::Message::Privmsg::Me.new: + :text( %args[1] ), + |%msg-args; +} + +sub msg-notice (%args, %msg-args) { + %args[0] ~~ /^<[#&]>/ + and return IRC::Client::Message::Notice::Channel.new: + :channel( %args[0] ), + :text( %args[1] ), + |%msg-args; + + return IRC::Client::Message::Notice::Me.new: + :text( %args[1] ), + |%msg-args; +} + +sub msg-mode (%args, %msg-args) { + if %args[0] ~~ /^<[#&]>/ { + my @modes; + for %args[1..*-1].join.comb: /\S/ { + state $sign; + /<[+-]>/ and $sign = $_ and next; + @modes.push: $sign => $_; + }; + return IRC::Client::Message::Mode::Channel.new: + :channel( %args[0] ), + :modes( @modes ), + |%msg-args; + } + else { + return IRC::Client::Message::Mode::Me.new: + :modes( %args[1..*-1].join.comb: /<[a..zA..Z]>/ ), + |%msg-args; + } +} diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 69e7c82..4abb718 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -1,9 +1,33 @@ -unit role IRC::Client::Message; - -has $.irc is required; -has Str:D $.nick is required; -has Str:D $.username is required; -has Str:D $.host is required; -has Str:D $.usermask is required; -has Str:D $.command is required; -has Str:D $.server is required; +unit package IRC::Client::Message; + +role IRC::Client::Message { + has $.irc is required; + has Str:D $.nick is required; + has Str:D $.username is required; + has Str:D $.host is required; + has Str:D $.usermask is required; + has Str:D $.command is required; + has Str:D $.server is required; + has @.args is required; + + method Str { "$.command @.args[]" } +} + +constant M = IRC::Client::Message; + +role Join does M { has $.channel; } +role Notice does M { has $.text; } +role Notice::Channel does Notice { has $.channel; } +role Notice::Me does Notice { } +role Mode does M { has @.modes; } +role Mode::Channel does Mode { has $.channel; } +role Mode::Me does Mode { } +role Numeric does M { } +role Privmsg does M { has $.text; } +role Privmsg::Channel does Privmsg { has $.channel; } +role Privmsg::Me does Privmsg { } +role Unknown does M { method Str { "❚⚠❚ $.command @.args[]" } } + +role Ping does M { + method reply { $.irc.send-cmd: 'PONG', @.args; } +} diff --git a/lib/IRC/Client/Message/Numeric.pm6 b/lib/IRC/Client/Message/Numeric.pm6 index 38e9a26..c059eb4 100644 --- a/lib/IRC/Client/Message/Numeric.pm6 +++ b/lib/IRC/Client/Message/Numeric.pm6 @@ -1,6 +1,2 @@ use IRC::Client::Message; unit role IRC::Client::Message::Numeric does IRC::Client::Message; - -has @.args; - -method Str { "$.command @.args[]" } diff --git a/lib/IRC/Client/Message/Privmsg.pm6 b/lib/IRC/Client/Message/Privmsg.pm6 new file mode 100644 index 0000000..31efdea --- /dev/null +++ b/lib/IRC/Client/Message/Privmsg.pm6 @@ -0,0 +1,4 @@ +use IRC::Client::Message; +unit role IRC::Client::Message::Privmsg does IRC::Client::Message; + +has $.what; diff --git a/lib/IRC/Client/Message/Privmsg/Channel.pm6 b/lib/IRC/Client/Message/Privmsg/Channel.pm6 new file mode 100644 index 0000000..36cf3d6 --- /dev/null +++ b/lib/IRC/Client/Message/Privmsg/Channel.pm6 @@ -0,0 +1,5 @@ +use IRC::Client::Message::Privmsg; +unit role IRC::Client::Message::Privmsg::Channel + does IRC::Client::Message::Privmsg; + +has $.channel; diff --git a/lib/IRC/Client/Message/Privmsg/Me.pm6 b/lib/IRC/Client/Message/Privmsg/Me.pm6 new file mode 100644 index 0000000..1ff31ba --- /dev/null +++ b/lib/IRC/Client/Message/Privmsg/Me.pm6 @@ -0,0 +1,2 @@ +use IRC::Client::Message::Privmsg; +unit role IRC::Client::Message::Privmsg::Me does IRC::Client::Message::Privmsg; diff --git a/lib/IRC/Client/Message/Unknown.pm6 b/lib/IRC/Client/Message/Unknown.pm6 new file mode 100644 index 0000000..91baa79 --- /dev/null +++ b/lib/IRC/Client/Message/Unknown.pm6 @@ -0,0 +1,4 @@ +use IRC::Client::Message; +unit role IRC::Client::Message::Unknown does IRC::Client::Message; + +method Str { "❚⚠❚ $.command @.args[]" } -- cgit v1.1 From c56f8b4359f2730bb9e8bccd40bf2c9fa840f433 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sat, 4 Jun 2016 23:20:01 -0400 Subject: First working rewrite --- lib/IRC/Client.pm6 | 78 ++++++++++++++++++++++---------------- lib/IRC/Client/Grammar.pm6 | 4 +- lib/IRC/Client/Grammar/Actions.pm6 | 18 ++++++--- lib/IRC/Client/Message.pm6 | 25 +++++++++--- lib/IRC/Client/Plugin.pm6 | 4 ++ 5 files changed, 84 insertions(+), 45 deletions(-) create mode 100644 lib/IRC/Client/Plugin.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 0c836a4..afc4303 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -4,10 +4,10 @@ use IRC::Client::Grammar; use IRC::Client::Grammar::Actions; has Str:D $.host = 'localhost'; -has Bool $.debug = False; +has Int:D $.debug = 0; has Str $.password; has Int:D $.port where 0 <= $_ <= 65535 = 6667; -has Str:D $.nick = 'Perl6IRC'; +has Str:D $.nick is rw = 'Perl6IRC'; has Str:D $.username = 'Perl6IRC'; has Str:D $.userhost = 'localhost'; has Str:D $.userreal = 'Perl6 IRC Client'; @@ -23,23 +23,20 @@ method run { self!ssay: "NICK $!nick"; self!ssay: "USER $!username $!username $!host :$!userreal"; - my $left-overs = ''; react { CATCH { warn .backtrace } whenever $!sock.Supply :bin -> $buf is copy { + state $left-overs = ''; my $str = try $buf.decode: 'utf8'; $str or $str = $buf.decode: 'latin-1'; - $str ~= $left-overs; + $str = $left-overs ~ $str; (my $events, $left-overs) = self!parse: $str; $str ~~ /$=(\N*)$/; - dd $str; - say "#### SHOULD Left over: `$`"; - say "#### LEFT OVERS: `$left-overs`"; for $events.grep: *.defined -> $e { CATCH { warn .backtrace } - $!debug and debug-print $e, 'in'; + $!debug and debug-print $e, :in; self!handle-event: $e; } } @@ -58,19 +55,31 @@ method !handle-event ($e) { when '001' { self!ssay: "JOIN @.channels[]"; } when 'PING' { $e.reply } when 'JOIN' { - say "Joined channel $e.channel()"; + say "Joined channel $e.channel()" + if $e.nick eq $!nick; } } + + my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') + .lc.subst: '::', '-', :g; + $!debug >= 2 and debug-print "emitting `$method`", :sys; + for self!plugs-that-can: $method { + last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; + } +} + +method !plugs-that-can ($method) { + return @!plugins.grep(*.^can: $method); } method !ssay (Str:D $msg) { - $!debug and debug-print $msg, 'out'; + $!debug and debug-print $msg, :out; $!sock.print("$msg\n"); self; } method !parse (Str:D $str) { - return IRC::Client::Grammar.parse( + return |IRC::Client::Grammar.parse( $str, actions => IRC::Client::Grammar::Actions.new( irc => self, @@ -79,31 +88,36 @@ method !parse (Str:D $str) { ).made; } -sub debug-print (Str(Any) $str, $dir where * eq 'in' | 'out') { - state $colored = try { +sub debug-print (Str(Any) $str, :$in, :$out, :$sys) { + state &colored = try { require Terminal::ANSIColor; - $colored = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; + &colored + = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; } // sub (Str $s) { '' }; - my @out; - if $str ~~ /^ '❚⚠❚'/ { - @out = $str.split: ' ', 3; - @out[0] = $colored(@out[0], 'bold white on_red'); - @out[1] = @out[1] ~~ /^ <[0..9]>**3 $/ - ?? $colored(@out[1], 'bold red') - !! $colored(@out[1], 'bold magenta'); - @out[2] = $colored(@out[2], 'bold cyan'); + my @bits = $str.split: ' '; + if $in { + my ($pref, $cmd) = 0, 1; + if @bits[0] eq '❚⚠❚' { + @bits[0] = colored @bits[0], 'bold white on_red'; + $pref++; $cmd++; + } + @bits[$pref] = colored @bits[$pref], 'bold magenta'; + @bits[$cmd] = @bits[$cmd] ~~ /^ <[0..9]>**3 $/ + ?? colored(@bits[$cmd], 'bold red') + !! colored(@bits[$cmd], 'bold yellow'); + put colored('▬▬▶ ', 'bold blue' ) ~ @bits.join: ' '; + } + elsif $out { + @bits[0] = colored @bits[0], 'bold magenta'; + put colored('◀▬▬ ', 'bold green') ~ @bits.join: ' '; + } + elsif $sys { + put colored(' ' x 4 ~ '↳', 'bold white') ~ ' ' + ~ @bits.join(' ') + .subst: /(\`<-[`]>+\`)/, { colored(~$0, 'bold cyan') }; } else { - @out = $str.split: ' ', 2; - @out[0] = @out[0] ~~ /^ <[0..9]>**3 $/ - ?? $colored(@out[0], 'bold red') - !! $colored(@out[0], 'bold magenta'); - @out[1] = $colored(@out[1], 'bold cyan'); + die "Unknown debug print mode"; } - - put ( $dir eq 'in' - ?? $colored('▬▬▶ ', 'bold blue' ) - !! $colored('◀▬▬ ', 'bold green') - ) ~ @out.join: ' '; } diff --git a/lib/IRC/Client/Grammar.pm6 b/lib/IRC/Client/Grammar.pm6 index a258e56..feec9fd 100644 --- a/lib/IRC/Client/Grammar.pm6 +++ b/lib/IRC/Client/Grammar.pm6 @@ -1,6 +1,6 @@ unit grammar IRC::Client::Grammar; -token TOP { + } -token leftovers { \N* } +token TOP { + } +token left-overs { \N* } token SPACE { ' '+ } token message { [':' ]? \n } token prefix { diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index 6ebe33d..cf702f8 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -40,8 +40,8 @@ method message ($match) { irc => $!irc, nick => %args//'', server => $!server, + usermask => ~($match//''), username => %args//''; - . = . ~ '!' ~ . ~ '@' ~ . given %msg-args; my $msg; given %msg-args { @@ -53,11 +53,17 @@ method message ($match) { :channel( %args[0] ), |%msg-args; } - when 'NOTICE' { $msg = msg-notice %args, %msg-args } - when 'MODE' { $msg = msg-mode %args, %msg-args } - when 'PING' { $msg = IRC::Client::Message::Ping.new: |%msg-args; } - when 'PRIVMSG' { $msg = msg-privmsg %args, %msg-args } - default { $msg = IRC::Client::Message::Unknown.new: |%msg-args } + when 'PART' { + $msg = IRC::Client::Message::Part.new: + :channel( %args[0] ), + |%msg-args; + } + when 'NOTICE' { $msg = msg-notice %args, %msg-args } + when 'MODE' { $msg = msg-mode %args, %msg-args } + when 'PING' { $msg = IRC::Client::Message::Ping.new: |%msg-args } + when 'PRIVMSG' { $msg = msg-privmsg %args, %msg-args } + when 'QUIT' { $msg = IRC::Client::Message::Quit.new: |%msg-args } + default { $msg = IRC::Client::Message::Unknown.new: |%msg-args } } $match.make: $msg; diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 4abb718..1b38d23 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -10,7 +10,7 @@ role IRC::Client::Message { has Str:D $.server is required; has @.args is required; - method Str { "$.command @.args[]" } + method Str { ":$!usermask $!command @!args[]" } } constant M = IRC::Client::Message; @@ -23,11 +23,26 @@ role Mode does M { has @.modes; } role Mode::Channel does Mode { has $.channel; } role Mode::Me does Mode { } role Numeric does M { } -role Privmsg does M { has $.text; } -role Privmsg::Channel does Privmsg { has $.channel; } -role Privmsg::Me does Privmsg { } -role Unknown does M { method Str { "❚⚠❚ $.command @.args[]" } } +role Part does M { has $.channel; } +role Quit does M { } +role Unknown does M { + method Str { "❚⚠❚ :$.usermask $.command @.args[]" } +} role Ping does M { method reply { $.irc.send-cmd: 'PONG', @.args; } } + +role Privmsg does M { has $.text; } +role Privmsg::Channel does Privmsg { + has $.channel; + method reply ($text, :$where) { + $.irc.send-cmd: 'PRIVMSG', $where // $.channel, $text; + } +} +role Privmsg::Me does Privmsg { + method reply ($text, :$where) { + $where //= $.nick; + $.irc.send-cmd: 'PRIVMSG', $where, $text; + } +} diff --git a/lib/IRC/Client/Plugin.pm6 b/lib/IRC/Client/Plugin.pm6 new file mode 100644 index 0000000..2493c3f --- /dev/null +++ b/lib/IRC/Client/Plugin.pm6 @@ -0,0 +1,4 @@ +unit role IRC::Client::Plugin; + +has $.IRC_HANDLED = my class IRC_FLAG_HANDLED {}; +has $.IRC_NOT_HANDLED = my class IRC_FLAG_NOT_HANDLED {}; -- cgit v1.1 From fc59edef8c4a13cb894edad8f7ded39bff3f96d8 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 00:02:07 -0400 Subject: Promise --- lib/IRC/Client.pm6 | 75 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 28 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index afc4303..e1fffbf 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -13,36 +13,45 @@ has Str:D $.userhost = 'localhost'; has Str:D $.userreal = 'Perl6 IRC Client'; has Str:D @.channels = ['#perl6']; has @.plugins; -has @.servers; -has IO::Socket::Async $!sock; +has %.servers; method run { - await IO::Socket::Async.connect( $!host, $!port ).then({ - $!sock = .result; - self!ssay: "PASS $!password" if $!password.defined; - self!ssay: "NICK $!nick"; - self!ssay: "USER $!username $!username $!host :$!userreal"; - - react { - CATCH { warn .backtrace } - - whenever $!sock.Supply :bin -> $buf is copy { - state $left-overs = ''; - my $str = try $buf.decode: 'utf8'; - $str or $str = $buf.decode: 'latin-1'; - $str = $left-overs ~ $str; - - (my $events, $left-overs) = self!parse: $str; - $str ~~ /$=(\N*)$/; - for $events.grep: *.defined -> $e { - CATCH { warn .backtrace } - $!debug and debug-print $e, :in; - self!handle-event: $e; + self!prep-servers; + + for %!servers.kv -> $s-name, $s-conf { + %!servers{ $s-name } = + IO::Socket::Async.connect( $s-conf, $s-conf ).then({ + $s-conf = .result; + + self!ssay: "PASS $!password", :server($s-name) + if $!password.defined; + self!ssay: "NICK $!nick", :server($s-name); + self!ssay: + "USER $!username $!username $!host :$!userreal", + :server($s-name); + + react { + CATCH { warn .backtrace } + + whenever $s-conf.Supply :bin -> $buf is copy { + state $left-overs = ''; + my $str = try $buf.decode: 'utf8'; + $str or $str = $buf.decode: 'latin-1'; + $str = $left-overs ~ $str; + + (my $events, $left-overs) = self!parse: $str; + for $events.grep: *.defined -> $e { + CATCH { warn .backtrace } + $!debug and debug-print $e, :in; + self!handle-event: $e; + } } } - } - $!sock.close; - }); + $s-conf.close; + }) + } + say %!servers.values».; + await %!servers.values».; } method send-cmd ($cmd, *@args) { @@ -50,6 +59,16 @@ method send-cmd ($cmd, *@args) { self!ssay: join ' ', $cmd, @args; } +method !prep-servers { + %!servers = '*' => {} unless %!servers; + + for %!servers.values -> $s { + $s{$_} //= self."$_"() + for ; + $s = @.channels; + } +} + method !handle-event ($e) { given $e.command { when '001' { self!ssay: "JOIN @.channels[]"; } @@ -72,9 +91,9 @@ method !plugs-that-can ($method) { return @!plugins.grep(*.^can: $method); } -method !ssay (Str:D $msg) { +method !ssay (Str:D $msg, :$server = '*') { $!debug and debug-print $msg, :out; - $!sock.print("$msg\n"); + %!servers{ $server }.print("$msg\n"); self; } -- cgit v1.1 From c194b1d8b3b4e85d5ffd5b36c7deb63a494386fa Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 09:04:21 -0400 Subject: Z --- lib/IRC/Client.pm6 | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index e1fffbf..b591ff2 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -19,8 +19,8 @@ method run { self!prep-servers; for %!servers.kv -> $s-name, $s-conf { - %!servers{ $s-name } = - IO::Socket::Async.connect( $s-conf, $s-conf ).then({ + %!servers{ $s-name } + = IO::Socket::Async.connect( $s-conf, $s-conf ).then({ $s-conf = .result; self!ssay: "PASS $!password", :server($s-name) @@ -39,19 +39,21 @@ method run { $str or $str = $buf.decode: 'latin-1'; $str = $left-overs ~ $str; - (my $events, $left-overs) = self!parse: $str; + (my $events, $left-overs) + = self!parse: $str, :server($s-name); + # say $events, $left-overs; for $events.grep: *.defined -> $e { - CATCH { warn .backtrace } - $!debug and debug-print $e, :in; - self!handle-event: $e; + say $e; + # CATCH { warn .backtrace } + # $!debug and debug-print $e, :in; + # self!handle-event: $e, $s-name; } } } $s-conf.close; }) } - say %!servers.values».; - await %!servers.values».; + await Promise.allof: %!servers.values».; } method send-cmd ($cmd, *@args) { @@ -70,21 +72,21 @@ method !prep-servers { } method !handle-event ($e) { - given $e.command { - when '001' { self!ssay: "JOIN @.channels[]"; } - when 'PING' { $e.reply } - when 'JOIN' { - say "Joined channel $e.channel()" - if $e.nick eq $!nick; - } - } - - my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') - .lc.subst: '::', '-', :g; - $!debug >= 2 and debug-print "emitting `$method`", :sys; - for self!plugs-that-can: $method { - last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; - } + # given $e.command { + # when '001' { self!ssay: "JOIN @.channels[]", :server($e.server); } + # when 'PING' { $e.reply } + # when 'JOIN' { + # say "Joined channel $e.channel()" + # if $e.nick eq $!nick; + # } + # } + # + # my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') + # .lc.subst: '::', '-', :g; + # $!debug >= 2 and debug-print "emitting `$method`", :sys; + # for self!plugs-that-can: $method { + # last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; + # } } method !plugs-that-can ($method) { @@ -92,22 +94,24 @@ method !plugs-that-can ($method) { } method !ssay (Str:D $msg, :$server = '*') { + return; $!debug and debug-print $msg, :out; %!servers{ $server }.print("$msg\n"); self; } -method !parse (Str:D $str) { +method !parse (Str:D $str, :$server) { return |IRC::Client::Grammar.parse( $str, actions => IRC::Client::Grammar::Actions.new( irc => self, - server => 'dummy', + server => $server, ), ).made; } sub debug-print (Str(Any) $str, :$in, :$out, :$sys) { + return; state &colored = try { require Terminal::ANSIColor; &colored -- cgit v1.1 From 496d289d8b515ed57a1586c3a39826703c3923b2 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 09:07:46 -0400 Subject: Z --- lib/IRC/Client.pm6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index b591ff2..0c10f0c 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -44,8 +44,8 @@ method run { # say $events, $left-overs; for $events.grep: *.defined -> $e { say $e; - # CATCH { warn .backtrace } - # $!debug and debug-print $e, :in; + CATCH { warn .backtrace } + $!debug and debug-print $e, :in; # self!handle-event: $e, $s-name; } } -- cgit v1.1 From 6f3f00300a122e33ca1050fdb42cccda39fe9ba4 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 10:14:38 -0400 Subject: Z --- lib/IRC/Client.pm6 | 57 +++++++++++++++++++++++----------------------- lib/IRC/Client/Message.pm6 | 4 ++-- 2 files changed, 30 insertions(+), 31 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 0c10f0c..b546866 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -19,7 +19,8 @@ method run { self!prep-servers; for %!servers.kv -> $s-name, $s-conf { - %!servers{ $s-name } + say "LAUNCHING $s-name [$s-conf]"; + $s-conf = IO::Socket::Async.connect( $s-conf, $s-conf ).then({ $s-conf = .result; @@ -41,24 +42,21 @@ method run { (my $events, $left-overs) = self!parse: $str, :server($s-name); - # say $events, $left-overs; for $events.grep: *.defined -> $e { - say $e; - CATCH { warn .backtrace } $!debug and debug-print $e, :in; - # self!handle-event: $e, $s-name; + self!handle-event: $e; } } } $s-conf.close; - }) + }); } await Promise.allof: %!servers.values».; } -method send-cmd ($cmd, *@args) { +method send-cmd ($cmd, *@args, :$server) { @args[*-1] = ':' ~ @args[*-1]; - self!ssay: join ' ', $cmd, @args; + self!ssay: :$server, join ' ', $cmd, @args; } method !prep-servers { @@ -72,21 +70,21 @@ method !prep-servers { } method !handle-event ($e) { - # given $e.command { - # when '001' { self!ssay: "JOIN @.channels[]", :server($e.server); } - # when 'PING' { $e.reply } - # when 'JOIN' { - # say "Joined channel $e.channel()" - # if $e.nick eq $!nick; - # } - # } - # - # my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') - # .lc.subst: '::', '-', :g; - # $!debug >= 2 and debug-print "emitting `$method`", :sys; - # for self!plugs-that-can: $method { - # last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; - # } + given $e.command { + when '001' { self!ssay: "JOIN @.channels[]", :server($e.server); } + when 'PING' { $e.reply } + when 'JOIN' { + say "Joined channel $e.channel()" + if $e.nick eq $!nick; + } + } + + my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') + .lc.subst: '::', '-', :g; + $!debug >= 2 and debug-print "emitting `$method`", :sys; + for self!plugs-that-can: $method { + last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; + } } method !plugs-that-can ($method) { @@ -94,8 +92,7 @@ method !plugs-that-can ($method) { } method !ssay (Str:D $msg, :$server = '*') { - return; - $!debug and debug-print $msg, :out; + $!debug and debug-print $msg, :out, :$server; %!servers{ $server }.print("$msg\n"); self; } @@ -110,14 +107,16 @@ method !parse (Str:D $str, :$server) { ).made; } -sub debug-print (Str(Any) $str, :$in, :$out, :$sys) { - return; +sub debug-print (Str(Any) $str, :$in, :$out, :$sys, :$server) { state &colored = try { require Terminal::ANSIColor; &colored = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; } // sub (Str $s) { '' }; + my $server-str = $server + ?? colored($server, 'bold white on_green') ~ ' ' !! ''; + my @bits = $str.split: ' '; if $in { my ($pref, $cmd) = 0, 1; @@ -129,11 +128,11 @@ sub debug-print (Str(Any) $str, :$in, :$out, :$sys) { @bits[$cmd] = @bits[$cmd] ~~ /^ <[0..9]>**3 $/ ?? colored(@bits[$cmd], 'bold red') !! colored(@bits[$cmd], 'bold yellow'); - put colored('▬▬▶ ', 'bold blue' ) ~ @bits.join: ' '; + put colored('▬▬▶ ', 'bold blue' ) ~ $server-str ~ @bits.join: ' '; } elsif $out { @bits[0] = colored @bits[0], 'bold magenta'; - put colored('◀▬▬ ', 'bold green') ~ @bits.join: ' '; + put colored('◀▬▬ ', 'bold green') ~ $server-str ~ @bits.join: ' '; } elsif $sys { put colored(' ' x 4 ~ '↳', 'bold white') ~ ' ' diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 1b38d23..e7478de 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -37,12 +37,12 @@ role Privmsg does M { has $.text; } role Privmsg::Channel does Privmsg { has $.channel; method reply ($text, :$where) { - $.irc.send-cmd: 'PRIVMSG', $where // $.channel, $text; + $.irc.send-cmd: 'PRIVMSG', $where // $.channel, $text, :$.server; } } role Privmsg::Me does Privmsg { method reply ($text, :$where) { $where //= $.nick; - $.irc.send-cmd: 'PRIVMSG', $where, $text; + $.irc.send-cmd: 'PRIVMSG', $where, $text, :$.server; } } -- cgit v1.1 From a1ea399a2e4c36949959fa22ecfac5fe583f1775 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 10:34:38 -0400 Subject: Add lock --- lib/IRC/Client.pm6 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index b546866..cc18db2 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -18,11 +18,11 @@ has %.servers; method run { self!prep-servers; + my $lock = Lock.new; for %!servers.kv -> $s-name, $s-conf { - say "LAUNCHING $s-name [$s-conf]"; $s-conf - = IO::Socket::Async.connect( $s-conf, $s-conf ).then({ - $s-conf = .result; + = IO::Socket::Async.connect($s-conf, $s-conf).then: -> $v { + $lock.protect: { $s-conf = $v.result; }; self!ssay: "PASS $!password", :server($s-name) if $!password.defined; @@ -49,7 +49,7 @@ method run { } } $s-conf.close; - }); + }; } await Promise.allof: %!servers.values».; } @@ -92,7 +92,7 @@ method !plugs-that-can ($method) { } method !ssay (Str:D $msg, :$server = '*') { - $!debug and debug-print $msg, :out, :$server; + # $!debug and debug-print $msg, :out, :$server; %!servers{ $server }.print("$msg\n"); self; } @@ -112,7 +112,7 @@ sub debug-print (Str(Any) $str, :$in, :$out, :$sys, :$server) { require Terminal::ANSIColor; &colored = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; - } // sub (Str $s) { '' }; + } // sub (Str $s, $) { $s }; my $server-str = $server ?? colored($server, 'bold white on_green') ~ ' ' !! ''; -- cgit v1.1 From 16056e8af837a4d982d23728adf24b4cc406576c Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 11:17:15 -0400 Subject: Bug commit --- lib/IRC/Client.pm6 | 32 ++++++++++++++++++-------------- lib/IRC/Client/Message.pm6 | 8 ++++---- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index cc18db2..96580cf 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -15,14 +15,20 @@ has Str:D @.channels = ['#perl6']; has @.plugins; has %.servers; +my &colored = try { + require Terminal::ANSIColor; + &colored + = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; +} // sub (Str $s, $) { $s }; + method run { self!prep-servers; my $lock = Lock.new; for %!servers.kv -> $s-name, $s-conf { $s-conf - = IO::Socket::Async.connect($s-conf, $s-conf).then: -> $v { - $lock.protect: { $s-conf = $v.result; }; + = IO::Socket::Async.connect($s-conf, $s-conf).then: { + $lock.protect: { $s-conf = .result; }; self!ssay: "PASS $!password", :server($s-name) if $!password.defined; @@ -43,8 +49,8 @@ method run { (my $events, $left-overs) = self!parse: $str, :server($s-name); for $events.grep: *.defined -> $e { - $!debug and debug-print $e, :in; - self!handle-event: $e; + $!debug and debug-print $e, :in, :server($e.server); + $lock.protect: { self!handle-event: $e; }; } } } @@ -66,16 +72,20 @@ method !prep-servers { $s{$_} //= self."$_"() for ; $s = @.channels; + $s = Nil; } } method !handle-event ($e) { given $e.command { - when '001' { self!ssay: "JOIN @.channels[]", :server($e.server); } + when '001' { + %!servers{ $e.server } = $e.args[0]; + self!ssay: "JOIN @.channels[]", :server($e.server); + } when 'PING' { $e.reply } when 'JOIN' { say "Joined channel $e.channel()" - if $e.nick eq $!nick; + if $e.nick eq %!servers{ $e.server }; } } @@ -92,7 +102,7 @@ method !plugs-that-can ($method) { } method !ssay (Str:D $msg, :$server = '*') { - # $!debug and debug-print $msg, :out, :$server; + $!debug and debug-print $msg, :out, :$server; %!servers{ $server }.print("$msg\n"); self; } @@ -108,14 +118,8 @@ method !parse (Str:D $str, :$server) { } sub debug-print (Str(Any) $str, :$in, :$out, :$sys, :$server) { - state &colored = try { - require Terminal::ANSIColor; - &colored - = GLOBAL::Terminal::ANSIColor::EXPORT::DEFAULT::<&colored>; - } // sub (Str $s, $) { $s }; - my $server-str = $server - ?? colored($server, 'bold white on_green') ~ ' ' !! ''; + ?? colored($server, 'bold white on_cyan') ~ ' ' !! ''; my @bits = $str.split: ' '; if $in { diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index e7478de..9a51803 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -8,9 +8,9 @@ role IRC::Client::Message { has Str:D $.usermask is required; has Str:D $.command is required; has Str:D $.server is required; - has @.args is required; + has $.args is required; - method Str { ":$!usermask $!command @!args[]" } + method Str { ":$!usermask $!command $!args[]" } } constant M = IRC::Client::Message; @@ -26,11 +26,11 @@ role Numeric does M { } role Part does M { has $.channel; } role Quit does M { } role Unknown does M { - method Str { "❚⚠❚ :$.usermask $.command @.args[]" } + method Str { "❚⚠❚ :$.usermask $.command $.args[]" } } role Ping does M { - method reply { $.irc.send-cmd: 'PONG', @.args; } + method reply { $.irc.send-cmd: 'PONG', $.args, :$.server; } } role Privmsg does M { has $.text; } -- cgit v1.1 From 140959e4f170d732d990e69b9a0ca129b89e3ac4 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 5 Jun 2016 21:39:47 -0400 Subject: First working test --- lib/IRC/Client.pm6 | 8 ++++---- lib/IRC/Client/Grammar/Actions.pm6 | 5 +++++ lib/IRC/Client/Message.pm6 | 1 + lib/IRC/Client/Message/Numeric.pm6 | 2 -- lib/IRC/Client/Message/Privmsg.pm6 | 4 ---- lib/IRC/Client/Message/Privmsg/Channel.pm6 | 5 ----- lib/IRC/Client/Message/Privmsg/Me.pm6 | 2 -- lib/IRC/Client/Message/Unknown.pm6 | 4 ---- 8 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 lib/IRC/Client/Message/Numeric.pm6 delete mode 100644 lib/IRC/Client/Message/Privmsg.pm6 delete mode 100644 lib/IRC/Client/Message/Privmsg/Channel.pm6 delete mode 100644 lib/IRC/Client/Message/Privmsg/Me.pm6 delete mode 100644 lib/IRC/Client/Message/Unknown.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 96580cf..cacd7c1 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -37,14 +37,14 @@ method run { "USER $!username $!username $!host :$!userreal", :server($s-name); + my $left-overs = ''; react { CATCH { warn .backtrace } whenever $s-conf.Supply :bin -> $buf is copy { - state $left-overs = ''; my $str = try $buf.decode: 'utf8'; $str or $str = $buf.decode: 'latin-1'; - $str = $left-overs ~ $str; + $str = ($left-overs//'') ~ $str; (my $events, $left-overs) = self!parse: $str, :server($s-name); @@ -84,8 +84,8 @@ method !handle-event ($e) { } when 'PING' { $e.reply } when 'JOIN' { - say "Joined channel $e.channel()" - if $e.nick eq %!servers{ $e.server }; + # say "Joined channel $e.channel() on $e.server()" + # if $e.nick eq %!servers{ $e.server }; } } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index cf702f8..7c16227 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -58,6 +58,11 @@ method message ($match) { :channel( %args[0] ), |%msg-args; } + when 'NICK' { + $msg = IRC::Client::Message::Nick.new: + :new-nick( %args[0] ), + |%msg-args; + } when 'NOTICE' { $msg = msg-notice %args, %msg-args } when 'MODE' { $msg = msg-mode %args, %msg-args } when 'PING' { $msg = IRC::Client::Message::Ping.new: |%msg-args } diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 9a51803..74261c9 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -22,6 +22,7 @@ role Notice::Me does Notice { } role Mode does M { has @.modes; } role Mode::Channel does Mode { has $.channel; } role Mode::Me does Mode { } +role Nick does M { has $.new-nick; } role Numeric does M { } role Part does M { has $.channel; } role Quit does M { } diff --git a/lib/IRC/Client/Message/Numeric.pm6 b/lib/IRC/Client/Message/Numeric.pm6 deleted file mode 100644 index c059eb4..0000000 --- a/lib/IRC/Client/Message/Numeric.pm6 +++ /dev/null @@ -1,2 +0,0 @@ -use IRC::Client::Message; -unit role IRC::Client::Message::Numeric does IRC::Client::Message; diff --git a/lib/IRC/Client/Message/Privmsg.pm6 b/lib/IRC/Client/Message/Privmsg.pm6 deleted file mode 100644 index 31efdea..0000000 --- a/lib/IRC/Client/Message/Privmsg.pm6 +++ /dev/null @@ -1,4 +0,0 @@ -use IRC::Client::Message; -unit role IRC::Client::Message::Privmsg does IRC::Client::Message; - -has $.what; diff --git a/lib/IRC/Client/Message/Privmsg/Channel.pm6 b/lib/IRC/Client/Message/Privmsg/Channel.pm6 deleted file mode 100644 index 36cf3d6..0000000 --- a/lib/IRC/Client/Message/Privmsg/Channel.pm6 +++ /dev/null @@ -1,5 +0,0 @@ -use IRC::Client::Message::Privmsg; -unit role IRC::Client::Message::Privmsg::Channel - does IRC::Client::Message::Privmsg; - -has $.channel; diff --git a/lib/IRC/Client/Message/Privmsg/Me.pm6 b/lib/IRC/Client/Message/Privmsg/Me.pm6 deleted file mode 100644 index 1ff31ba..0000000 --- a/lib/IRC/Client/Message/Privmsg/Me.pm6 +++ /dev/null @@ -1,2 +0,0 @@ -use IRC::Client::Message::Privmsg; -unit role IRC::Client::Message::Privmsg::Me does IRC::Client::Message::Privmsg; diff --git a/lib/IRC/Client/Message/Unknown.pm6 b/lib/IRC/Client/Message/Unknown.pm6 deleted file mode 100644 index 91baa79..0000000 --- a/lib/IRC/Client/Message/Unknown.pm6 +++ /dev/null @@ -1,4 +0,0 @@ -use IRC::Client::Message; -unit role IRC::Client::Message::Unknown does IRC::Client::Message; - -method Str { "❚⚠❚ $.command @.args[]" } -- cgit v1.1 From 7a17edf5807b585698a219aaf551f1393139c001 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Thu, 9 Jun 2016 21:53:21 -0400 Subject: Fix multi-channel join for non-spec-conforming servers --- lib/IRC/Client.pm6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index cacd7c1..6803203 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -80,7 +80,7 @@ method !handle-event ($e) { given $e.command { when '001' { %!servers{ $e.server } = $e.args[0]; - self!ssay: "JOIN @.channels[]", :server($e.server); + self!ssay: "JOIN $_", :server($e.server) for @.channels; } when 'PING' { $e.reply } when 'JOIN' { -- cgit v1.1 From c341e8432ef33b5a598e6b9d3a75855f02104b6c Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Tue, 19 Jul 2016 13:16:16 -0400 Subject: Blahg --- lib/IRC/Client.pm6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 6803203..dc86287 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -93,7 +93,7 @@ method !handle-event ($e) { .lc.subst: '::', '-', :g; $!debug >= 2 and debug-print "emitting `$method`", :sys; for self!plugs-that-can: $method { - last if ."$method"($e).^name eq 'IRC_FLAG_HANDLED'; + last if ."$method"($e).?^name.&[eq]: 'IRC_FLAG_HANDLED'; } } -- cgit v1.1 From 18615cc9bb33801fbde2716513071e7b32af2ab2 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Sun, 24 Jul 2016 16:20:12 -0400 Subject: moar work --- lib/IRC/Client.pm6 | 119 ++++++++++++++++++++++++++++++------- lib/IRC/Client/Grammar/Actions.pm6 | 2 +- lib/IRC/Client/Message.pm6 | 35 ++++++++--- lib/IRC/Client/Plugin.pm6 | 4 -- 4 files changed, 128 insertions(+), 32 deletions(-) delete mode 100644 lib/IRC/Client/Plugin.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index dc86287..06c030f 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -3,6 +3,13 @@ unit class IRC::Client; use IRC::Client::Grammar; use IRC::Client::Grammar::Actions; +my class IRC_FLAG_NEXT {}; + +role IRC::Client::Plugin is export { + my IRC_FLAG_NEXT $.NEXT; + has $.irc is rw; +} + has Str:D $.host = 'localhost'; has Int:D $.debug = 0; has Str $.password; @@ -14,6 +21,9 @@ has Str:D $.userreal = 'Perl6 IRC Client'; has Str:D @.channels = ['#perl6']; has @.plugins; has %.servers; +has Bool $!is-connected = False; +has Lock $!lock = Lock.new; +has Channel $!event-pipe = Channel.new; my &colored = try { require Terminal::ANSIColor; @@ -23,12 +33,26 @@ my &colored = try { method run { self!prep-servers; + .irc = self for @.plugins.grep: { .DEFINITE and .^can: 'irc' }; + + start { + my $closed = $!event-pipe.closed; + loop { + if $!event-pipe.receive -> $e { + $!debug and debug-print $e, :in, :server($e.server); + $!lock.protect: { + self!handle-event: $e; + CATCH { default { warn $_; warn .backtrace } } + }; + } + elsif $closed { last } + } + } - my $lock = Lock.new; for %!servers.kv -> $s-name, $s-conf { $s-conf = IO::Socket::Async.connect($s-conf, $s-conf).then: { - $lock.protect: { $s-conf = .result; }; + $!lock.protect: { $s-conf = .result; }; self!ssay: "PASS $!password", :server($s-name) if $!password.defined; @@ -39,8 +63,6 @@ method run { my $left-overs = ''; react { - CATCH { warn .backtrace } - whenever $s-conf.Supply :bin -> $buf is copy { my $str = try $buf.decode: 'utf8'; $str or $str = $buf.decode: 'latin-1'; @@ -48,19 +70,29 @@ method run { (my $events, $left-overs) = self!parse: $str, :server($s-name); - for $events.grep: *.defined -> $e { - $!debug and debug-print $e, :in, :server($e.server); - $lock.protect: { self!handle-event: $e; }; - } + $!event-pipe.send: $_ for $events.grep: *.defined; } + CATCH { default { warn $_; warn .backtrace } } } $s-conf.close; + CATCH { default { warn $_; warn .backtrace } } }; } await Promise.allof: %!servers.values».; } -method send-cmd ($cmd, *@args, :$server) { +method emit-custom (|c) { + $!event-pipe.send: c; +} + +method send (:$where!, :$text!, :$server, :$notice) { + for $server || |%!servers.keys.sort { + self.send-cmd: $notice ?? 'NOTICE' !! 'PRIVMSG', $where, $text, + :server($_); + } +} + +method send-cmd ($cmd, *@args is copy, :$server) { @args[*-1] = ':' ~ @args[*-1]; self!ssay: :$server, join ' ', $cmd, @args; } @@ -82,23 +114,73 @@ method !handle-event ($e) { %!servers{ $e.server } = $e.args[0]; self!ssay: "JOIN $_", :server($e.server) for @.channels; } - when 'PING' { $e.reply } + when 'PING' { return $e.reply; } when 'JOIN' { # say "Joined channel $e.channel() on $e.server()" # if $e.nick eq %!servers{ $e.server }; } } - my $method = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') + my $event-name = 'irc-' ~ $e.^name.subst('IRC::Client::Message::', '') .lc.subst: '::', '-', :g; - $!debug >= 2 and debug-print "emitting `$method`", :sys; - for self!plugs-that-can: $method { - last if ."$method"($e).?^name.&[eq]: 'IRC_FLAG_HANDLED'; + + my @events = flat gather { + given $event-name { + when 'irc-privmsg-channel' | 'irc-notice-channel' { + my $nick = $!nick; + if $e.text.subst-mutate: /^ $nick <[,:\s]> \s* /, '' { + take 'irc-addressed', ('irc-to-me' if $!is-connected); + } + elsif $e ~~ / << $nick >> / and $!is-connected { + take 'irc-mentioned'; + } + take $event-name, $event-name eq 'irc-privmsg-channel' + ?? 'irc-privmsg' !! 'irc-notice'; + } + when 'irc-privmsg-me' { + take $event-name, ('irc-to-me' if $!is-connected), + 'irc-privmsg'; + } + when 'irc-notice-me' { + take $event-name, ('irc-to-me' if $!is-connected), + 'irc-notice'; + } + when 'irc-mode-channel' | 'irc-mode-me' { + take $event-name, 'irc-mode'; + } + when 'irc-numeric' { + if $e.command eq '001' { + $!is-connected = True ; + take 'irc-connected'; + } + take 'irc-' ~ $e.command, $event-name; + } + } + take 'irc-all'; + } + + EVENT: for @events -> $event { + debug-print "emitting `$event`", :sys + if $!debug >= 3 or ($!debug == 2 and not $event eq 'irc-all'); + + for self!plugs-that-can($event, $e) { + my $res = ."$event"($e); + next if $res ~~ IRC_FLAG_NEXT; + $e.reply: $res unless $res ~~ Nil; + last EVENT; + + CATCH { default { warn $_, .backtrace; } } + } } } -method !plugs-that-can ($method) { - return @!plugins.grep(*.^can: $method); +method !plugs-that-can ($method, $e) { + gather { + for @!plugins -> $plug { + take $plug if .cando: \($plug, $e) + for $plug.^can: $method; + } + } } method !ssay (Str:D $msg, :$server = '*') { @@ -110,10 +192,7 @@ method !ssay (Str:D $msg, :$server = '*') { method !parse (Str:D $str, :$server) { return |IRC::Client::Grammar.parse( $str, - actions => IRC::Client::Grammar::Actions.new( - irc => self, - server => $server, - ), + :actions( IRC::Client::Grammar::Actions.new: :irc(self), :$server ) ).made; } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 index 7c16227..b1fcc53 100644 --- a/lib/IRC/Client/Grammar/Actions.pm6 +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -45,7 +45,7 @@ method message ($match) { my $msg; given %msg-args { - when /^ $=(<[0..9]>**3) $/ { + when /^ <[0..9]>**3 $/ { $msg = IRC::Client::Message::Numeric.new: |%msg-args; } when 'JOIN' { diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 74261c9..84eba2c 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -16,9 +16,6 @@ role IRC::Client::Message { constant M = IRC::Client::Message; role Join does M { has $.channel; } -role Notice does M { has $.text; } -role Notice::Channel does Notice { has $.channel; } -role Notice::Me does Notice { } role Mode does M { has @.modes; } role Mode::Channel does Mode { has $.channel; } role Mode::Me does Mode { } @@ -34,16 +31,40 @@ role Ping does M { method reply { $.irc.send-cmd: 'PONG', $.args, :$.server; } } -role Privmsg does M { has $.text; } +role Privmsg does M { + has $.text is rw; + has Bool $.replied is rw = False; + method Str { $.text } +} role Privmsg::Channel does Privmsg { has $.channel; method reply ($text, :$where) { - $.irc.send-cmd: 'PRIVMSG', $where // $.channel, $text, :$.server; + $.irc.send-cmd: 'PRIVMSG', $where // $.channel, "$.nick, $text", + :$.server; } } role Privmsg::Me does Privmsg { method reply ($text, :$where) { - $where //= $.nick; - $.irc.send-cmd: 'PRIVMSG', $where, $text, :$.server; + $.irc.send-cmd: 'PRIVMSG', $where // $.nick, $text, :$.server; + } +} + +role Notice does M { + has $.text is rw; + has Bool $.replied is rw = False; + method Str { $.text } +} +role Notice::Channel does Notice { + has $.channel; + method reply ($text, :$where) { + $.irc.send-cmd: 'NOTICE', $where // $.channel, "$.nick, $text", + :$.server; + $.replied = True; + } +} +role Notice::Me does Notice { + method reply ($text, :$where) { + $.irc.send-cmd: 'NOTICE', $where // $.nick, $text, :$.server; + $.replied = True; } } diff --git a/lib/IRC/Client/Plugin.pm6 b/lib/IRC/Client/Plugin.pm6 deleted file mode 100644 index 2493c3f..0000000 --- a/lib/IRC/Client/Plugin.pm6 +++ /dev/null @@ -1,4 +0,0 @@ -unit role IRC::Client::Plugin; - -has $.IRC_HANDLED = my class IRC_FLAG_HANDLED {}; -has $.IRC_NOT_HANDLED = my class IRC_FLAG_NOT_HANDLED {}; -- cgit v1.1 From cc5b3c020f67a3cdf2da3d524c37eec743f1eba5 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Mon, 25 Jul 2016 02:27:19 -0400 Subject: Filter attempt --- lib/IRC/Client.pm6 | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 06c030f..e0cd731 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -19,6 +19,7 @@ has Str:D $.username = 'Perl6IRC'; has Str:D $.userhost = 'localhost'; has Str:D $.userreal = 'Perl6 IRC Client'; has Str:D @.channels = ['#perl6']; +has @.filters where .all ~~ Callable; has @.plugins; has %.servers; has Bool $!is-connected = False; @@ -93,8 +94,32 @@ method send (:$where!, :$text!, :$server, :$notice) { } method send-cmd ($cmd, *@args is copy, :$server) { - @args[*-1] = ':' ~ @args[*-1]; - self!ssay: :$server, join ' ', $cmd, @args; + CATCH { default { warn $_; warn .backtrace } } + + say "About to check filter stuff `{@!filters}`"; + if $cmd eq 'NOTICE'|'PRIVMSG' and @!filters + and my @f = @!filters.grep({ + .signature.ACCEPTS: \(@args[0], where => @args[1]) + }) + { + say "Starting filtering: `@args[]`"; + start { + CATCH { default { warn $_; warn .backtrace } } + + my ($where, $text) = @args; + for @f -> $f { + given $f.signature.params.elems { + when 1 { $text = $f($text); } + when 2 { ($text, $where) = $f($text, :$where) } + } + } + self!ssay: :$server, join ' ', $cmd, $where, ":$text"; + } + } + else { + @args[*-1] = ':' ~ @args[*-1]; + self!ssay: :$server, join ' ', $cmd, @args; + } } method !prep-servers { @@ -166,7 +191,11 @@ method !handle-event ($e) { for self!plugs-that-can($event, $e) { my $res = ."$event"($e); next if $res ~~ IRC_FLAG_NEXT; - $e.reply: $res unless $res ~~ Nil; + if $res ~~ Promise { + $res.then: { $e.reply: $^r unless $^r ~~ Nil or $e.replied; } + } else { + $e.reply: $res unless $res ~~ Nil or $e.replied; + } last EVENT; CATCH { default { warn $_, .backtrace; } } -- cgit v1.1 From ea2c4707a526cc9746ed929e7a38d932721db624 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Mon, 25 Jul 2016 21:05:42 -0400 Subject: Make filters sorta work --- lib/IRC/Client.pm6 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index e0cd731..5069d31 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -99,10 +99,11 @@ method send-cmd ($cmd, *@args is copy, :$server) { say "About to check filter stuff `{@!filters}`"; if $cmd eq 'NOTICE'|'PRIVMSG' and @!filters and my @f = @!filters.grep({ - .signature.ACCEPTS: \(@args[0], where => @args[1]) + .signature.ACCEPTS: \(@args[1]) + or .signature.ACCEPTS: \(@args[1], where => @args[0]) }) { - say "Starting filtering: `@args[]`"; + say "Starting filtering: `@f[]`"; start { CATCH { default { warn $_; warn .backtrace } } -- cgit v1.1 From 226a5ccd074b8840ca83d50376f8b26b9d9ffd97 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Tue, 26 Jul 2016 08:53:29 -0400 Subject: More stuff --- lib/IRC/Client.pm6 | 6 ++---- lib/IRC/Client/Message.pm6 | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index 5069d31..9e3bfbd 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -93,17 +93,15 @@ method send (:$where!, :$text!, :$server, :$notice) { } } -method send-cmd ($cmd, *@args is copy, :$server) { +method send-cmd ($cmd, *@args is copy, :$server, :$prefix = '') { CATCH { default { warn $_; warn .backtrace } } - say "About to check filter stuff `{@!filters}`"; if $cmd eq 'NOTICE'|'PRIVMSG' and @!filters and my @f = @!filters.grep({ .signature.ACCEPTS: \(@args[1]) or .signature.ACCEPTS: \(@args[1], where => @args[0]) }) { - say "Starting filtering: `@f[]`"; start { CATCH { default { warn $_; warn .backtrace } } @@ -114,7 +112,7 @@ method send-cmd ($cmd, *@args is copy, :$server) { when 2 { ($text, $where) = $f($text, :$where) } } } - self!ssay: :$server, join ' ', $cmd, $where, ":$text"; + self!ssay: :$server, join ' ', $cmd, $where, ":$prefix$text"; } } else { diff --git a/lib/IRC/Client/Message.pm6 b/lib/IRC/Client/Message.pm6 index 84eba2c..9559fd1 100644 --- a/lib/IRC/Client/Message.pm6 +++ b/lib/IRC/Client/Message.pm6 @@ -39,8 +39,8 @@ role Privmsg does M { role Privmsg::Channel does Privmsg { has $.channel; method reply ($text, :$where) { - $.irc.send-cmd: 'PRIVMSG', $where // $.channel, "$.nick, $text", - :$.server; + $.irc.send-cmd: 'PRIVMSG', $where // $.channel, $text, + :$.server, :prefix("$.nick, "); } } role Privmsg::Me does Privmsg { @@ -57,8 +57,8 @@ role Notice does M { role Notice::Channel does Notice { has $.channel; method reply ($text, :$where) { - $.irc.send-cmd: 'NOTICE', $where // $.channel, "$.nick, $text", - :$.server; + $.irc.send-cmd: 'NOTICE', $where // $.channel, $text, + :$.server, :prefix("$.nick, "); $.replied = True; } } -- cgit v1.1