]> ruin.nu Git - NDIRC.git/commitdiff
Merge branch 'discord'
authorMichael Andreen <harv@ruin.nu>
Fri, 22 Mar 2019 12:05:12 +0000 (13:05 +0100)
committerMichael Andreen <harv@ruin.nu>
Fri, 22 Mar 2019 12:05:12 +0000 (13:05 +0100)
13 files changed:
Bot.pm
Commands/Basic.pm
Commands/Channel.pm
Commands/Def.pm
Commands/Scans.pm
Commands/Usermgm.pm
Context.pm
Delling.pm
DiscordContext.pm [new file with mode: 0644]
Dispatcher.pm
IrcContext.pm [new file with mode: 0644]
database/roles.sql
ndbot.pl

diff --git a/Bot.pm b/Bot.pm
index 5693dd4d0b353c392d51a173736421262ba3f74d..363531217864018f1faf26ab54ec00a37cbeae9d 100644 (file)
--- a/Bot.pm
+++ b/Bot.pm
@@ -26,14 +26,18 @@ use Moose;
 
 use POE::Component::IRC::Common qw/irc_to_utf8/;
 use POE::Session;
+use POE::Kernel;
 use POE::Component::IRC::Plugin::Logger;
 use POE::Component::IRC::Plugin::BotTraffic;
 use POE::Component::IRC::Plugin::Connector;
 use POE::Component::IRC::Plugin::AutoJoin;
 use POE::Component::IRC::Plugin::NickReclaim;
 
+use Mojo::Discord;
+use Mojo::IOLoop;
+
 use NDIRC::Dispatcher;
-use NDIRC::Context;
+use NDIRC::IrcContext;
 
 use IO::File;
 
@@ -43,6 +47,33 @@ has disp => (
        lazy_build => 1
 );
 
+has discord => (
+       is => 'rw',
+       isa => 'Object'
+);
+
+has discord_name => (
+       is => 'rw',
+       isa => 'Str'
+);
+
+has discord_id => (
+       is => 'rw',
+       isa => 'Str'
+);
+
+has discord_channels => (
+       is => 'rw',
+       isa => 'HashRef',
+       default => sub { {} }
+);
+
+has targets => (
+       is => 'ro',
+       isa => 'HashRef[ArrayRef[Str]]',
+       default => sub{ {} },
+);
+
 # We registered for all events, this will produce some debug info.
 sub _default {
        my ($event, $args) = @_[ARG0 .. $#_];
@@ -60,11 +91,16 @@ sub _default {
        return 0;
 }
 
+my $irc;
+sub irc {
+       return $irc;
+}
+
 sub _start {
-       my ($kernel,$heap,$session) = @_[KERNEL,HEAP,SESSION];
+       my ($self,$kernel,$heap,$session) = @_[OBJECT,KERNEL,HEAP,SESSION];
 
        # retrieve our component's object from the heap where we stashed it
-       my $irc = $heap->{irc};
+       $irc = $heap->{irc};
        $kernel->sig( DIE => 'sig_DIE' );
        $kernel->sig( USR1 => 'sig_usr1' );
        $kernel->sig( USR2 => 'sig_usr2' );
@@ -94,6 +130,29 @@ sub _start {
        $irc->yield( connect => { server => 'irc.netgamers.org' } );
 
        $kernel->delay( refresh => 60 );
+
+       if (my $f =  new IO::File 'discord'){
+               my $user = <$f>;
+               chomp $user;
+               my $token = <$f>;
+               chomp $token;
+
+               $self->discord(Mojo::Discord->new(
+                               'token'     => $token,
+                               'name'      => $user,
+                               'url'       => 'https://nd.ruin.nu',
+                               'version'   => '1.0',
+                               'callbacks' => {
+                                       'READY'          => sub { $self->discord_ready(@_) },
+                                       'MESSAGE_CREATE' => sub { $self->discord_message_create(@_) },
+                                       'GUILD_CREATE' => sub { $self->discord_guild_create(@_) },
+                                       'CHANNEL_CREATE' => sub { $self->discord_channel_create(@_) },
+                               },
+                               'reconnect' => 1,
+                               'verbose'   => 1,
+                       ));
+               $self->discord->init();
+       }
        return;
 }
 
@@ -188,13 +247,16 @@ sub _build_disp {
                $disp->load(@commands);
        }
 
+       %{$self->targets} = ();
        my $channels = new IO::File 'channels' or die $!;;
        while (<$channels>){
                my ($chan, @types) = split /\s+/;
                say "$chan - @types";
                if ($chan =~ /^(.*):(.*)$/){
                        $chan = $1;
-                       $disp->set_target($2,$chan);
+                       $self->targets->{$2} = [] unless exists $self->targets->{$2};
+                       push @{$self->targets->{$2}},$chan;
+                       say "$2 - @{$self->targets->{$2}}";
                }
                $disp->add_channel($chan,\@types);
        }
@@ -276,6 +338,58 @@ sub  refresh {
 sub irc_join {
 }
 
+sub discord_ready {
+       my $self = shift;
+       my $hash = shift;
+       $self->discord_id($hash->{user}{id});
+       $self->discord_name($hash->{user}{username});
+
+       say localtime(time) . " - Connected to Discord. $self->{discord_id}";
+}
+
+sub discord_message_create {
+}
+
+sub discord_guild_create {
+       my $self = shift;
+       my $hash = shift;
+
+       for my $chan (@{$hash->{channels}}) {
+               say localtime(time) . " - $chan->{id} - $chan->{name}";
+               $self->discord_channels->{$chan->{id}} = $chan;
+       }
+}
+
+sub discord_channel_create {
+       my $self = shift;
+       my $chan = shift;
+
+       for my $key (keys %{$chan}) {
+               say localtime(time) . " - $key - $chan->{$key}";
+       }
+       $self->discord_channels->{$chan->{id}} = $chan;
+}
+
+sub handleCommand {
+       my ($self, $c, $msg) = @_;
+
+       my ($p,$command,$args) = ($msg =~ /^([.])(\S+)(?: (.+))?/);
+
+       if ($msg =~ m{https?://[\w.]+/.+?scan(_id|_grp)?=(\w+)}){
+               if (!$command || $command =~ m{^https?://}){
+                       ($p,$command,$args) = ('.','addscan',$msg);
+               }elsif($command ne 'addscan'){
+                       $self->handleCommand ($c, ".addscan $msg")
+               }
+       }
+
+       return 0 unless $self->disp->has_command($command,$c->channel);
+
+       say localtime(time) . " - $msg";
+
+       return $self->disp->run_command($c,$command,$args);
+}
+
 sub parseCommand {
        my ($self, $msg, $server, $nick, $address, $channel, $model) = @_;
 
@@ -308,17 +422,58 @@ sub parseCommand {
        }
 
        $address =~ s/.*@(.*)/$1/;
-       my $c = NDIRC::Context->new({
+       my $c = NDIRC::IrcContext->new({
                        host => $address,
                        nick => $nick,
                        channel => $channel,
                        disp => $self->disp,
                        model => $model,
                        server => $server,
+                       bot => $self,
                        reply_string => $reply_string,
                });
 
        return $self->disp->run_command($c,$command,$args);
 }
 
+sub toTarget {
+       my ($self, $target, $msg) = @_;
+
+       return unless exists $self->targets->{$target};
+
+       $self->message($msg, @{$self->targets->{$target}});
+
+}
+
+sub message {
+       my ($self, $msg, @targets) = @_;
+
+       for (@targets) {
+               when (/^D-(\d+)$/) {
+                       $self->discordMessage($1, $msg);
+               }
+               default {
+                       $self->ircMessage(privmsg => $_, $msg);
+               }
+       }
+}
+
+sub ircMessage {
+       my ($self, $command, $target, $msg) = @_;
+
+       $msg =~ s`<b>(.*?)</b>`${\(chr(2))}$1${\(chr(15))}`gi;
+       $msg =~ s`<c(\d+)>(.*?)</c>`${\(chr(3))}$1$2${\(chr(15))}`gi;
+
+       $self->irc->yield($command, $target, $msg);
+}
+
+sub discordMessage {
+       my ($self, $target, $msg) = @_;
+
+       $msg =~ s`<b>(.*?)</b>`**$1**`gi;
+       $msg =~ s`<c(\d+)>(.*?)</c>`*$2*`gi;
+
+       $self->discord->send_message($target, $msg );
+}
+
 1;
index 672c7a9958c7a84940ca6bb420fb957260372f02..6517e384b94660353a53209b424a8ea1b41420ee 100644 (file)
@@ -25,6 +25,7 @@ use NDIRC::Dispatcher;
 
 command commands => {
        help => q(commands <command> | Gives help about all available commands or lists all commands available in the current channel),
+       type => 'help',
 }, class extends NDIRC::Command {
        method execute ($c,$command) {
                unless($command){
@@ -57,7 +58,7 @@ command help => {
 
 command say => {
        help => q(.say target message | sends message to target),
-       type => q(pm),
+       type => q(ircpm),
        acl => q(irc_say),
 }, class extends NDIRC::Command {
        method execute ($c,$msg) {
@@ -69,7 +70,7 @@ command say => {
 
 command cmd => {
        help => q(.cmd command args | run a given irc command),
-       type => q(pm),
+       type => q(ircpm),
        acl  => q(irc_cmd),
 }, class extends NDIRC::Command {
        method execute ($c,$msg) {
index 62eae4f9bebd59e6eb353ad7bff927217cfcabdd..1c3a76248a4d088ee89ffe3e00e0db79a5cdc8d8 100644 (file)
@@ -77,7 +77,7 @@ command devoice => {
 
 command invite => {
        help => q(Syntax: invite [channel] | If no channel is specified it invites you to all channel you have auto invite access on),
-       type => q(pm)
+       type => q(ircpm)
 }, class extends NDIRC::Command {
        method execute ($c,$msg) {
                my ($channel) = $msg =~ /^\s*(\S+)?\s*$/ or die 'ARGS';
@@ -114,45 +114,4 @@ command hostname => {
        }
 };
 
-command getpass => {
-       help => q(Gives new users a random password.),
-       type => q(pm)
-}, class extends NDIRC::Command {
-
-###########################################################
-# Written by Guy Malachi http://guymal.com
-# 18 August, 2002
-###########################################################
-       sub generate_random_string
-       {
-               my $length_of_randomstring=shift;# the length of
-               # the random string to generate
-
-               my @chars=('a'..'z','A'..'Z','0'..'9','_');
-               my $random_string;
-               foreach (1..$length_of_randomstring)
-               {
-                       # rand @chars will generate a random
-                       # number between 0 and scalar @chars
-                       $random_string .= $chars[rand @chars];
-               }
-               return $random_string;
-       }
-
-       method execute ($c,$msg) {
-               my $dbh = $c->model;
-
-               my $password = generate_random_string 16;
-               my $update = $dbh->do(q{
-UPDATE users SET password = $1
-WHERE uid = $2 AND password IS NULL
-                       },undef,$password,$c->uid);
-               if ($update > 0){
-                       $c->reply("Password set to: $password (you can change it on webbie)");
-               }else{
-                       $c->reply("Couldn't set password. Either it has already been set or you don't have an account");
-               }
-       }
-};
-
 1;
index 099d706ddc50b8ac80ee42aee2b26dd29ecef910..c50f864b1dda054eefed8293b97302fcef8dca5e 100644 (file)
@@ -58,9 +58,8 @@ ORDER BY c.landing_tick;
                                return;
                        }
                }
-               $c->message(notice => $c->disp->targets->{members}, "DEFENSE REQUIRED!! WAKE UP!!");
-               $c->message(privmsg => $c->disp->targets->{members}, "DEFENSE REQUIRED "
-                       ."$mess $callinfo MSG ".$c->nick." TO RESPOND");
+               $c->bot->toTarget(members => "DEFENSE REQUIRED "
+                       ."$mess $callinfo RESPOND TO ".$c->username);
        }
 };
 
index 8ea51ffc4b1fa89a775157f0ee775c8642db0f90..193e486c46b80b6c094988876338415e689040be 100644 (file)
@@ -83,14 +83,14 @@ WHERE uid = $1
 UPDATE scan_requests SET nick = $1, tick = tick(), time = NOW()
 WHERE id = $2
                                        });
-                               $req->execute($c->nick,$scan->{id});
+                               $req->execute($c->replyId,$scan->{id});
                                $id = $scan->{id};
                        }else{
                                $req = $c->model->prepare(q{
 INSERT INTO scan_requests (uid,nick,pid,type)
 VALUES($1,$2,$3,$4) RETURNING (id)
                                        });
-                               $req->execute($c->uid,$c->nick,$planet,$type);
+                               $req->execute($c->uid,$c->replyId,$planet,$type);
                                $id = $req->fetchrow;
                        }
 
@@ -100,9 +100,9 @@ VALUES($1,$2,$3,$4) RETURNING (id)
                                }else{
                                        $dists = "DISTS UNKNOWN, ADD DEVSCAN"
                                }
-                               $c->message(privmsg => $c->disp->targets->{scan}
-                                       ,"<b>$id</b> http://game.planetarion.com/waves.pl?id=$typeid&x=$x&y=$y&z=$z"
-                                       . " ($x:$y:$z $type - $dists) | <".$c->nick."> $msg"
+                               $c->bot->toTarget( scan =>
+                                       "<b>$id</b> http://game.planetarion.com/waves.pl?id=$typeid&x=$x&y=$y&z=$z"
+                                       . " ($x:$y:$z $type - $dists) | <".$c->username."> $msg"
                                );
                                $c->reply("sent request ($x:$y:$z $type)");
                        }else{
@@ -121,6 +121,7 @@ my %scantypes;
 command scanreqs => {
        help => q(syntax: .scanreqs [-pdunja] | Lists scan requests that haven't been handled. The argument can be used to omit types you don't have, like .scanreqs -ja to list all requests except jumpgates and advanced unit scans.),
        acl => q(irc_scanreqs),
+       type => q{scan},
 }, class extends NDIRC::Command {
        method execute($c,$msg) {
                my @notype;
@@ -200,6 +201,7 @@ SELECT ship,amount FROM fleet_ships WHERE fid = $1 ORDER BY num
 
 command addscan => {
        help => q(syntax: .addscan list of scans),
+       type => q(universal),
 }, class extends NDIRC::Command {
        method execute($c,$msg) {
                my $dbh = $c->model;
@@ -212,7 +214,7 @@ WHERE groupscan = $1 AND scan_id = LOWER($2) AND tick >= tick() - 168
 INSERT INTO scans (scan_id,tick,groupscan,uid) VALUES (LOWER($1),tick(),$2,COALESCE($3,-1))
                        });
                my $user = $dbh->selectrow_hashref(q{SELECT uid,username, scan_points, tick()
-                       FROM users WHERE uid = ? },undef,$c->uid);
+                       FROM users WHERE uid = ? AND uid > 0 },undef,$c->uid);
                my $groupscans = 0;
                my $scans = 0;
                eval {
index a5e3abf8a70ff478cc01e5ac9640b112e2760722..e530b84c8ac8049c8a35050d3670e25809ae9e30 100644 (file)
@@ -25,35 +25,42 @@ use MooseX::Declare;
 use NDIRC::Dispatcher;
 
 command '+user' => {
-       help => q(syntax: .+user username [pnick] | username must be alphanum characters, if no pnick is given then it will be set to the same as username),
+       help => q(syntax: .+user username id | username must be alphanum characters, assumes discord id if it ends with #XXXX otherwise pnick),
        type => q(usermgmt),
        acl => 'irc_adduser'
 }, class extends NDIRC::Command {
        method execute ($c,$msg) {
-               my ($nick,$pnick) = $msg =~ /^(\w+)(?: ([^.\s]+))?$/ or die 'ARGS';
-               $pnick //= $nick;
+               my ($nick,$id) = $msg =~ /^(\w+) (.+)$/ or die 'ARGS';
 
                my $dbh = $c->model;
-
-               my $host = "$pnick.users.netgamers.org";
-               my ($username,$hostname,$p_nick) = $dbh->selectrow_array(q{
-SELECT username, hostmask,pnick
-FROM users WHERE username = $1 OR hostmask = $2 OR pnick = $3
-                       },undef,$nick,$host,$pnick);
+               my $pnick = undef;
+               my $discordid = undef;
+               my $host = undef;
+
+               if ($id =~ /.+#\d+/) {
+                       $discordid = $id;
+               } else {
+                       $pnick = $id;
+                       $host = "$pnick.users.netgamers.org";
+               }
+               my ($username,$hostname,$p_nick,$discord_id) = $dbh->selectrow_array(q{
+SELECT username, hostmask,pnick,discord_id
+FROM users WHERE username = $1 OR hostmask = $2 OR pnick = $3 OR discord_id = $4
+                       },undef,$nick,$host,$pnick,$discordid);
 
                if (defined $username){
-                       $c->reply("<b>$username ($p_nick)</b> already exists with host: <b>$hostname</b>");
+                       $c->reply("<b>$username ($p_nick, $discord_id)</b> already exists with host: <b>$hostname</b>");
                }else{
                        $dbh->do(q{
-INSERT INTO users (username,hostmask,pnick) VALUES($1,$2,$3)
-                               },undef,$nick,$host,$pnick);
-                       $c->reply("Added <b>$nick(/$pnick)</b> with host: <b>$host</b>");
+INSERT INTO users (username,hostmask,pnick,discord_id) VALUES($1,$2,$3,$4)
+                               },undef,$nick,$host,$pnick,$discordid);
+                       $c->reply("Added <b>$nick(/$id)</b>");
                }
        }
 };
 
 command '-user' => {
-       help => q(syntax: .-user nick | nick must be alphanum characters, if no pnick is given then it will be set to nick),
+       help => q(syntax: .-user nick | Deactivates a user),
        type => q(usermgmt),
        acl => 'irc_deactivateuser'
 }, class extends NDIRC::Command {
@@ -67,8 +74,8 @@ command '-user' => {
 
                if ($f->rows == 1){
                        my $updated = $dbh->do(q{
-UPDATE users SET hostmask = $1, password = NULL WHERE uid = $2
-                               },undef,$username,$uid);
+UPDATE users SET hostmask = NULL, discord_id = discord_id || '_', password = NULL WHERE uid = $1
+                               },undef,$uid);
                        if ($updated > 0){
                                my $groups = $dbh->do(q{DELETE FROM groupmembers WHERE uid = ?},undef,$uid);
                                $groups += 0;
@@ -152,16 +159,16 @@ command whois => {
 
 
                my $f = $dbh->prepare(q{
-SELECT username, pnick, hostmask, array_to_string(array_agg(gid),'') AS flags
+SELECT username, pnick, hostmask, discord_id, array_to_string(array_agg(gid),'') AS flags
 FROM users u
        LEFT OUTER JOIN (SELECT uid,gid FROM groupmembers ORDER BY uid,gid
        ) g USING (uid)
 WHERE username ILIKE ?
-GROUP BY username,pnick,hostmask LIMIT 5
+GROUP BY username,pnick,hostmask,discord_id LIMIT 5
                        });
                $f->execute($nick);
                while (my $user = $f->fetchrow_hashref){
-                       $c->reply("<b>$user->{username} (/$user->{pnick})</b> flags: ($user->{flags}) host: $user->{hostmask}");
+                       $c->reply("<b>$user->{username}</b> (<b>$user->{pnick},$user->{discord_id}</b>) flags: ($user->{flags}) host: $user->{hostmask}");
                }
                if ($f->rows == 0){
                        $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
@@ -417,6 +424,42 @@ SELECT username,hostmask,pnick FROM users WHERE hostmask = $1 OR pnick = $2
        }
 };
 
+command setdiscordid => {
+       help => q(Usage: .setdiscordid username discordid | Changes a user's discord id/tag Nick#id),
+       acl => q(bot_setdiscordid)
+}, class extends NDIRC::Command {
+       method execute ($c,$msg) {
+               my ($nick,$discordid) = $msg =~ /^(\S+) (\S+)$/ or die 'ARGS';
+               my $dbh = $c->model;
+
+               my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
+               $f->execute($nick);
+               my $user = $f->fetchrow_hashref;
+               if ($f->rows == 1){
+                       eval{
+                               $dbh->do(q{UPDATE users SET discord_id = NULLIF($1, 'NULL') WHERE uid = $2}
+                                       ,undef,$discordid,$user->{uid});
+                               $c->reply("Updated <b>$user->{username}</b>'s discord id to: <b>$discordid</b>");
+                       };
+                       if($@){
+                               if ($@ =~ /duplicate key value violates unique constraint/){
+                                       my ($username, $discordid) = $dbh->selectrow_array(q{
+SELECT username,discord_id FROM users WHERE discord_id = $1
+                                               },undef,$discordid);
+                                       $c->reply("<c04>Problem</c>, <b>$username</b> already uses discord id <b>$discordid</b>.");
+                               }else{
+                                       die $@;
+                               }
+                       }
+               }elsif ($f->rows == 0){
+                       $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
+               }else{
+                       $c->reply("More than 1 user matched, please refine the search");
+               }
+               $f->finish;
+       }
+};
+
 my $points = class extends NDIRC::Command {
        has point => (
                is => 'ro',
@@ -549,4 +592,45 @@ ORDER BY amount*(metal+crystal+eonium)*CASE WHEN $1 = t1 THEN 1.0 ELSE 0.6 END D
        }
 };
 
+command getpass => {
+       help => q(Gives new users a random password.),
+       type => q(pm)
+}, class extends NDIRC::Command {
+
+###########################################################
+# Written by Guy Malachi http://guymal.com
+# 18 August, 2002
+###########################################################
+       sub generate_random_string
+       {
+               my $length_of_randomstring=shift;# the length of
+               # the random string to generate
+
+               my @chars=('a'..'z','A'..'Z','0'..'9','_');
+               my $random_string;
+               foreach (1..$length_of_randomstring)
+               {
+                       # rand @chars will generate a random
+                       # number between 0 and scalar @chars
+                       $random_string .= $chars[rand @chars];
+               }
+               return $random_string;
+       }
+
+       method execute ($c,$msg) {
+               my $dbh = $c->model;
+
+               my $password = generate_random_string 16;
+               my $update = $dbh->do(q{
+UPDATE users SET password = $1
+WHERE uid = $2 AND password IS NULL
+                       },undef,$password,$c->uid);
+               if ($update > 0){
+                       $c->reply("Password set to: $password (you can change it on webbie)");
+               }else{
+                       $c->reply("Couldn't set password. Either it has already been set or you don't have an account");
+               }
+       }
+};
+
 1;
index 5810ca4e97dc9cc369b2d6327e716d50ea67fd02..7f1d2cc58e9654c71c3208c527486bd91615a737 100644 (file)
@@ -23,21 +23,10 @@ use warnings;
 use feature ':5.10';
 
 use Moose;
+use namespace::autoclean;
 
 use Set::Object ();
 
-has host => (
-       is => 'ro',
-       isa => 'Str',
-       required => 1
-);
-
-has nick => (
-       is => 'ro',
-       isa => 'Str',
-       required => 1
-);
-
 has channel => (
        is => 'ro',
        isa => 'Str',
@@ -56,6 +45,12 @@ has uid => (
        lazy_build => 1
 );
 
+has username => (
+       is => 'ro',
+       isa => 'Str',
+       lazy_build => 1
+);
+
 has disp => (
        is => 'ro',
        isa => 'Object',
@@ -68,18 +63,12 @@ has model => (
        required => 1
 );
 
-has server => (
+has bot => (
        is => 'ro',
        isa => 'Object',
        required => 1
 );
 
-has reply_string => (
-       is => 'ro',
-       isa => 'Str',
-       required => 1,
-);
-
 sub assert_user_roles {
        my ($self,@roles) = @_;
        return 1 unless @roles;
@@ -101,48 +90,12 @@ sub check_user_roles {
 }
 
 sub reply {
-       my ($self,$msg) = @_;
-
-       my @command = split / /, $self->reply_string;
-       $self->message(@command, $msg);
 }
 
 sub message {
-       my ($self,$command, $target, $msg) = @_;
-
-       $msg =~ s`<b>(.*?)</b>`${\(chr(2))}$1${\(chr(15))}`gi;
-       $msg =~ s`<c(\d+)>(.*?)</c>`${\(chr(3))}$1$2${\(chr(15))}`gi;
-
-       #Split the message, using the, slightly modified, algorithm from splitlong.pl in the irssi distribution.
-       if ($command eq 'privmsg'){
-               my $lend = ' ...';
-               my $lstart = '... ';
-               my $maxlength = $self->server->{msg_length} - bytes::length("privmsg $target :" . $self->server->nick_name());
-               my $maxlength2 = $maxlength - bytes::length($lend);
-
-               if (bytes::length($msg) > ($maxlength)) {
-                       my @spltarr;
-
-                       while (bytes::length($msg) > ($maxlength)) {
-                               my $pos = rindex($msg, " ", $maxlength2);
-                               push @spltarr, substr($msg, 0, ($pos < ($maxlength/10 + 4)) ? $maxlength2  : $pos)  . $lend;
-                               $msg = $lstart . substr($msg, ($pos < ($maxlength/10 + 4)) ? $maxlength2 : $pos+1);
-                       }
-
-                       push @spltarr, $msg;
-                       for (@spltarr) {
-                               $self->command($command, $target, $_);
-                       }
-                       return;
-               }
-       }
-       $self->command($command, $target, $msg);
 }
 
-sub command {
-       my ($self,@command) = @_;
-
-       $self->server->yield(@command);
+sub replyId {
 }
 
 sub intel_log {
@@ -169,9 +122,9 @@ sub _build_roles {
        my $query = $self->model->prepare(q{
 SELECT role FROM group_roles
 WHERE gid IN (SELECT gid FROM groupmembers JOIN users USING (uid)
-       WHERE hostmask = $1)
+       WHERE uid = $1)
                });
-       $query->execute($self->host);
+       $query->execute($self->uid);
 
        my @roles;
        while (my $group = $query->fetchrow_hashref){
@@ -183,29 +136,30 @@ WHERE gid IN (SELECT gid FROM groupmembers JOIN users USING (uid)
 sub _build_uid {
        my ($self) = @_;
 
+       return -4;
+}
+
+sub _build_username {
+       my ($self) = @_;
+
        my $query = $self->model->prepare(q{
-SELECT uid FROM users
-WHERE hostmask = $1
+SELECT username FROM users
+WHERE uid = $1
                });
-       $query->execute($self->host);
+       $query->execute($self->uid);
 
-       if (my ($uid) = $query->fetchrow_array){
+       if (my ($username) = $query->fetchrow_array){
                $query->finish;
-               return $uid;
+               return $username;
        }
-       return -4;
+       return "Anonymous";
 }
 
 sub valuecolor {
        shift @_;
        my $s = $_;
-       $s = $_[1] if $#_ >= 1;
-       $s = "" unless defined $s;
-       return "<c05>$s</c>" if $s eq 'Hostile';
-       return "<c03>$s</c>" if $s eq 'Friendly';
-       return "<c12>$s</c>" if $s eq 'Nap' or $s eq 'NAP';
-       return "<b>$s</b>" if $_[0];
        return $s;
 }
 
+__PACKAGE__->meta->make_immutable;
 1;
index bf9bb9d665d8e17cb0a5ca44710a308e0c767de4..e04619015f4fdb8e8a5fafc39dfb79c75a5f7580 100644 (file)
@@ -28,6 +28,8 @@ extends 'NDIRC::Bot';
 use POE::Session;
 use ND::DB;
 
+use NDIRC::DiscordContext;
+
 my ($tick,$stattick) = (0,0);
 my $last_announcement = 0;
 
@@ -101,7 +103,7 @@ WHERE u.hostmask = $1 AND channel = $2 AND flag IN ('o','v');
                $irc->yield(mode => $channel, $mode, @who) if $mode;
        }
 
-       if (lc $channel ~~ lc $disp->targets->{members}){
+       if (lc $channel ~~ lc $self->targets->{members}){
                if (time - $last_announcement < 1){
                        $last_announcement = time;
                        return;
@@ -113,14 +115,14 @@ FROM users u WHERE hostmask = ?
                }, undef, $address);
                if ($user){
                        unless ($user->{password}) {
-                               $irc->yield(privmsg => $disp->targets->{members}, "$nick: Get a new random password with /msg delling !getpass . If you don't know your username, then you can get it with .points");
+                               $irc->yield(privmsg => $self->targets->{members}, "$nick: Get a new random password with /msg delling !getpass . If you don't know your username, then you can get it with .points");
                        }
                        if ($tick > 12 && not defined $user->{pid}){
-                               $irc->yield(privmsg => $disp->targets->{members}, "$nick: go to https://nd.ruin.nu/ and enter your coords.");
+                               $irc->yield(privmsg => $self->targets->{members}, "$nick: go to https://nd.ruin.nu/ and enter your coords.");
                        }
 
                        if (not defined $user->{last_forum_visit}){
-                               $irc->yield(privmsg => $disp->targets->{members}, "$nick: Go read the forum! https://nd.ruin.nu/forum");
+                               $irc->yield(privmsg => $self->targets->{members}, "$nick: Go read the forum! https://nd.ruin.nu/forum");
                        }else {
                                my $unread = $dbh->selectrow_hashref(q{SELECT * FROM unread_posts($1)},undef,$user->{uid});
                                if ($unread && $unread->{new}){
@@ -160,29 +162,30 @@ sub refresh {
                });
        $scans->execute;
        while (my $scan = $scans->fetchrow_hashref){
-               $heap->{irc}->yield(notice => $scan->{nick}, "($scan->{coords} $scan->{type})"
-                       ." http://game.planetarion.com/showscan.pl?scan_id=$scan->{scan_id}");
+               $self->message("($scan->{coords} $scan->{type})"
+                       ." http://game.planetarion.com/showscan.pl?scan_id=$scan->{scan_id}"
+                       , @{$scan->{nick}});
                $sentscan->execute($scan->{id});
        }
 
        my @row = $dbh->selectrow_array(q{SELECT tick(), max(tick) FROM planet_stats});
        if ($tick != $row[0]){
                $tick = $row[0];
-               $irc->yield(privmsg => $disp->targets->{def}, "New tick: $tick");
+               $self->toTarget(def => "New tick: $tick");
        }
        if (defined $row[1] && $stattick != $row[1]){
                $stattick = $row[1];
-               $irc->yield(privmsg => $disp->targets->{members}, "New tick: $stattick");
+               $self->toTarget(members => "New tick: $stattick");
        }
        my $ircreqs = $dbh->prepare(q{SELECT id,username,message,channel FROM irc_requests NATURAL JOIN users WHERE not sent});
        my $upircreq = $dbh->prepare(q{UPDATE irc_requests SET sent = TRUE WHERE id = ?});
        $ircreqs->execute;
        while (my $req = $ircreqs->fetchrow_hashref){
                if ($req->{channel} eq 'def'){
-                       $irc->yield(privmsg => $disp->targets->{def}, chr(3)."04 ## $req->{username} via webbie ## >> $req->{message}");
-                       $self->parseCommand("~report_incs $req->{message}",$irc,$req->{username},' BATCH ',$disp->targets->{def},$dbh);
-               }elsif(exists $disp->targets->{$req->{channel}}){
-                       $irc->yield(privmsg => $disp->targets->{$req->{channel}}, "<$req->{username} via webbie> $req->{message}");
+                       $self->toTarget(def => "<c04>## $req->{username} via webbie ## >></c> $req->{message}");
+                       #$self->parseCommand("~report_incs $req->{message}",$irc,$req->{username},' BATCH ',$disp->targets->{def},$dbh);
+               }else{
+                       $self->toTarget($req->{channel} => "<$req->{username} via webbie> $req->{message}");
                }
                $upircreq->execute($req->{id});
        }
@@ -202,7 +205,7 @@ GROUP BY username,call,tick,dm.fleet,p.value
        my $updefmis = $dbh->prepare(q{UPDATE defense_missions SET announced = TRUE WHERE fleet = ?});
        $defmissions->execute();
        while (my $mission = $defmissions->fetchrow_hashref){
-               $irc->yield(privmsg => $disp->targets->{def}, chr(3)."06 $mission->{username} sent def to call $mission->{call}, $mission->{value}% of value (tick $mission->{tick}) https://nd.ruin.nu/calls/edit/$mission->{call}");
+               $self->toTarget(def => "<c06>$mission->{username} sent def</c> to call $mission->{call}, $mission->{value}% of value (tick $mission->{tick}) https://nd.ruin.nu/calls/edit/$mission->{call}");
                $updefmis->execute($mission->{fleet});
        }
 
@@ -216,4 +219,36 @@ after _start => sub {
  ($tick,$stattick) = DB()->selectrow_array(q{SELECT tick(),max(tick) FROM planet_stats});
 };
 
+after discord_message_create => sub {
+       my $self = shift;
+       my $hash = shift;
+
+       my $author = $hash->{author};
+       my $msg = $hash->{content};
+       my $channel_id = $hash->{channel_id};
+       my $author_name = $author->{username}.'#'.$author->{discriminator};
+       my $author_id = $author->{id};
+       return if $author->{'id'} eq $self->discord_id; # Ignore my own messages
+
+       my $channel = "D-".$channel_id;
+       if (exists $self->discord_channels->{$channel_id}) {
+               $channel = 'dm' if ($self->discord_channels->{$channel_id}->{type} == 1);
+       }
+
+       say localtime(time) . " - $channel_id $channel $author_name $author_id";
+
+       my $c = NDIRC::DiscordContext->new({
+                       discord_id => $author_name,
+                       channel_id => $channel_id,
+                       channel => $channel,
+                       disp => $self->disp,
+                       model => DB(),
+                       bot => $self,
+                       discord => $self->discord,
+               });
+
+       return $self->handleCommand($c,$msg);
+
+};
+
 1;
diff --git a/DiscordContext.pm b/DiscordContext.pm
new file mode 100644 (file)
index 0000000..c6e4959
--- /dev/null
@@ -0,0 +1,95 @@
+#**************************************************************************
+#   Copyright (C) 2019 by Michael Andreen <harvATruinDOTnu>               *
+#                                                                         *
+#   This program is free software; you can redistribute it and/or modify  *
+#   it under the terms of the GNU General Public License as published by  *
+#   the Free Software Foundation; either version 2 of the License, or     *
+#   (at your option) any later version.                                   *
+#                                                                         *
+#   This program is distributed in the hope that it will be useful,       *
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+#   GNU General Public License for more details.                          *
+#                                                                         *
+#   You should have received a copy of the GNU General Public License     *
+#   along with this program; if not, write to the                         *
+#   Free Software Foundation, Inc.,                                       *
+#   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
+#**************************************************************************/
+
+package NDIRC::DiscordContext;
+use strict;
+use warnings;
+use feature ':5.10';
+
+use Moose;
+use namespace::autoclean;
+extends "NDIRC::Context";
+
+has discord_id => (
+       is => 'ro',
+       isa => 'Str',
+       required => 1
+);
+
+has channel_id => (
+       is => 'ro',
+       isa => 'Str',
+       required => 1
+);
+
+has discord => (
+       is => 'ro',
+       isa => 'Object',
+       required => 1
+);
+
+
+sub reply {
+       my ($self,$msg) = @_;
+
+       $self->message($self->channel_id, $msg);
+}
+
+sub message {
+       my ($self, $target, $msg) = @_;
+
+       $self->bot->discordMessage($target, $msg ); # Send the response.
+}
+
+sub replyId {
+       my $self = shift;
+       return "D-".$self->channel_id;
+}
+
+sub _build_uid {
+       my ($self) = @_;
+
+       my $query = $self->model->prepare(q{
+SELECT uid FROM users
+WHERE discord_id = $1
+               });
+       $query->execute($self->discord_id);
+
+       if (my ($uid) = $query->fetchrow_array){
+               $query->finish;
+               return $uid;
+       }
+       return -4;
+}
+
+sub valuecolor {
+       shift @_;
+       my $s = $_;
+       $s = $_[1] if $#_ >= 1;
+       $s = "" unless defined $s;
+       return "~~$s~~" if $s eq 'Hostile';
+       return "***$s***" if $s eq 'Friendly';
+       return "*$s*" if $s eq 'Nap' or $s eq 'NAP';
+       return "<b>$s</b>" if $_[0] && $s;
+       return $s;
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
index 6705349b8081b4da430edc43ee3e48d12adf0217..a11ae53cda91800f387dcd4fae40c874a2a9b045 100644 (file)
@@ -46,11 +46,6 @@ has channels => (
        default => sub{ {} },
 );
 
-has targets => (
-       is => 'ro',
-       isa => 'HashRef[Str]',
-       default => sub{ {} },
-);
 
 my $DISP;
 
@@ -92,6 +87,7 @@ sub add_channel {
        my ($self,$channel,$types) = @_;
 
        $types = Set::Object->new(@{$types});
+       $types->insert('universal');
        $self->channels->{lc $channel} = $types;
 }
 
@@ -101,17 +97,13 @@ sub has_command {
 
        return 0 unless defined $command && defined $channel;
        return 0 unless exists $self->commands->{$command};
+       $command = $self->commands->{$command};
+       return 1 if $command->type eq 'universal';
        return 0 unless exists $self->channels->{$channel};
 
-       $command = $self->commands->{$command};
        return $self->channels->{$channel}->has($command->type);
 }
 
-sub set_target {
-       my ($self,$label,$target) = @_;
-       $self->targets->{$label} = $target;
-}
-
 sub run_command {
        my ($self,$c,$command,$args) = @_;
 
diff --git a/IrcContext.pm b/IrcContext.pm
new file mode 100644 (file)
index 0000000..b8eae0d
--- /dev/null
@@ -0,0 +1,134 @@
+#**************************************************************************
+#   Copyright (C) 2009 by Michael Andreen <harvATruinDOTnu>               *
+#                                                                         *
+#   This program is free software; you can redistribute it and/or modify  *
+#   it under the terms of the GNU General Public License as published by  *
+#   the Free Software Foundation; either version 2 of the License, or     *
+#   (at your option) any later version.                                   *
+#                                                                         *
+#   This program is distributed in the hope that it will be useful,       *
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+#   GNU General Public License for more details.                          *
+#                                                                         *
+#   You should have received a copy of the GNU General Public License     *
+#   along with this program; if not, write to the                         *
+#   Free Software Foundation, Inc.,                                       *
+#   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
+#**************************************************************************/
+
+package NDIRC::IrcContext;
+use strict;
+use warnings;
+use feature ':5.10';
+
+use Moose;
+use namespace::autoclean;
+extends "NDIRC::Context";
+
+use Set::Object ();
+
+has host => (
+       is => 'ro',
+       isa => 'Str',
+       required => 1
+);
+
+has nick => (
+       is => 'ro',
+       isa => 'Str',
+       required => 1
+);
+
+has server => (
+       is => 'ro',
+       isa => 'Object',
+       required => 1
+);
+
+has reply_string => (
+       is => 'ro',
+       isa => 'Str',
+       required => 1,
+);
+
+sub reply {
+       my ($self,$msg) = @_;
+
+       my @command = split / /, $self->reply_string;
+       $self->message(@command, $msg);
+}
+
+sub message {
+       my ($self,$command, $target, $msg) = @_;
+
+       $msg =~ s`<b>(.*?)</b>`${\(chr(2))}$1${\(chr(15))}`gi;
+       $msg =~ s`<c(\d+)>(.*?)</c>`${\(chr(3))}$1$2${\(chr(15))}`gi;
+
+       #Split the message, using the, slightly modified, algorithm from splitlong.pl in the irssi distribution.
+       if ($command eq 'privmsg'){
+               my $lend = ' ...';
+               my $lstart = '... ';
+               my $maxlength = $self->server->{msg_length} - bytes::length("privmsg $target :" . $self->server->nick_name());
+               my $maxlength2 = $maxlength - bytes::length($lend);
+
+               if (bytes::length($msg) > ($maxlength)) {
+                       my @spltarr;
+
+                       while (bytes::length($msg) > ($maxlength)) {
+                               my $pos = rindex($msg, " ", $maxlength2);
+                               push @spltarr, substr($msg, 0, ($pos < ($maxlength/10 + 4)) ? $maxlength2  : $pos)  . $lend;
+                               $msg = $lstart . substr($msg, ($pos < ($maxlength/10 + 4)) ? $maxlength2 : $pos+1);
+                       }
+
+                       push @spltarr, $msg;
+                       for (@spltarr) {
+                               $self->command($command, $target, $_);
+                       }
+                       return;
+               }
+       }
+       $self->command($command, $target, $msg);
+}
+
+sub replyId {
+       my $self = shift;
+       return $self->nick;
+}
+
+sub command {
+       my ($self,@command) = @_;
+
+       $self->server->yield(@command);
+}
+
+sub _build_uid {
+       my ($self) = @_;
+
+       my $query = $self->model->prepare(q{
+SELECT uid FROM users
+WHERE hostmask = $1
+               });
+       $query->execute($self->host);
+
+       if (my ($uid) = $query->fetchrow_array){
+               $query->finish;
+               return $uid;
+       }
+       return -4;
+}
+
+sub valuecolor {
+       shift @_;
+       my $s = $_;
+       $s = $_[1] if $#_ >= 1;
+       $s = "" unless defined $s;
+       return "<c05>$s</c>" if $s eq 'Hostile';
+       return "<c03>$s</c>" if $s eq 'Friendly';
+       return "<c12>$s</c>" if $s eq 'Nap' or $s eq 'NAP';
+       return "<b>$s</b>" if $_[0];
+       return $s;
+}
+
+__PACKAGE__->meta->make_immutable;
+1;
index 657c9696515c1091fbe3ca5ce31bd41106784fed..0e5e6ded3f8ab1ed85d4ec2b30c21693942868a0 100644 (file)
@@ -44,6 +44,7 @@ INSERT INTO roles VALUES('irc_allycoords');
 INSERT INTO roles VALUES('irc_allygals');
 INSERT INTO roles VALUES('irc_g_intel');
 INSERT INTO roles VALUES('irc_anon');
+INSERT INTO roles VALUES('bot_setdiscordid');
 
 INSERT INTO group_roles (gid,role) VALUES('T','irc_p_nick');
 INSERT INTO group_roles (gid,role) VALUES('T','irc_p_intel');
@@ -86,6 +87,7 @@ INSERT INTO group_roles (gid,role) VALUES('T','irc_cmd');
 INSERT INTO group_roles (gid,role) VALUES('T','irc_allycoords');
 INSERT INTO group_roles (gid,role) VALUES('T','irc_allygals');
 INSERT INTO group_roles (gid,role) VALUES('T','irc_g_intel');
+INSERT INTO group_roles (gid,role) VALUES('T','bot_setdiscordid');
 
 INSERT INTO group_roles (gid,role) VALUES('M','irc_gs');
 INSERT INTO group_roles (gid,role) VALUES('M','irc_scan');
@@ -131,6 +133,7 @@ INSERT INTO group_roles (gid,role) VALUES('H','irc_forum_others');
 INSERT INTO group_roles (gid,role) VALUES('H','irc_allycoords');
 INSERT INTO group_roles (gid,role) VALUES('H','irc_allygals');
 INSERT INTO group_roles (gid,role) VALUES('H','irc_g_intel');
+INSERT INTO group_roles (gid,role) VALUES('H','bot_setdiscordid');
 
 INSERT INTO group_roles (gid,role) VALUES('B','irc_points_others');
 INSERT INTO group_roles (gid,role) VALUES('B','irc_a');
index 54e2fcc9b56a6d8a9826aa426052a45a6afea012..afc8722741732a41c22f280ad83dc13bd8e9e0d2 100755 (executable)
--- a/ndbot.pl
+++ b/ndbot.pl
@@ -29,7 +29,7 @@ use lib dirname (__FILE__) . "/..";
 
 
 #use Devel::Leak::Object qw{ GLOBAL_bless };
-use POE qw(Component::IRC::Qnet::State);
+use POE qw(Component::IRC::Qnet::State Loop::Mojo_IOLoop);
 
 use Moose;
 use MooseX::Declare;
@@ -64,3 +64,5 @@ POE::Session->create(
 );
 
 $poe_kernel->run();
+
+1;