X-Git-Url: https://ruin.nu/git/?p=NDIRC.git;a=blobdiff_plain;f=Commands%2FDef.pm;h=099d706ddc50b8ac80ee42aee2b26dd29ecef910;hp=7931033e2f6ddd1ba1cf1b04372dff5bb5fbaef0;hb=f36fb98300ab9b6e395b0f859eb537b2fc301b8e;hpb=565ece6e27fa54253934518cc8c69ecfac9487e4 diff --git a/Commands/Def.pm b/Commands/Def.pm index 7931033..099d706 100644 --- a/Commands/Def.pm +++ b/Commands/Def.pm @@ -17,27 +17,304 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * #**************************************************************************/ -package NDIRC::Commands::Def; - use strict; use warnings; use feature ':5.10'; -use Moose; -use MooseX::MethodAttributes; -sub anon - : Help(syntax: .anon nick message) - : Type(def) - : ACL(irc_anondef) -{ - my ($self,$c,$msg) = @_; +use MooseX::Declare; +use NDIRC::Dispatcher; + +command defcall => { + help => q(syntax: .defcall [callid] | if a call id is given, then shiptypes and eta will be fetched from the database and added to the message), + type => q(def), + acl => q(irc_defcall), +}, class extends NDIRC::Command { + method execute($c,$msg) { + my ($callnr,$mess) = $msg =~ /^(\d+)?(.*)$/ or die 'ARGS'; + my $dbh = $c->model; + + my $callinfo = ""; + if ($callnr){ + my $st = $dbh->prepare(q{ +SELECT status + ,c.landing_tick - (SELECT value::integer FROM misc WHERE id = 'TICK') AS eta + ,array_to_string(array_agg(i.shiptype),'/') AS shiptype +FROM calls c + JOIN incomings i USING (call) + LEFT OUTER JOIN users dc ON dc.uid = c.dc +WHERE c.call = ? +GROUP BY c.call,c.landing_tick,c.status +ORDER BY c.landing_tick; + }); + my $call = $dbh->selectrow_hashref($st,undef,$callnr); + unless (defined $call->{status}){ + $c->reply("No call with id: $callnr"); + return; + } + $callinfo = "(Anti $call->{shiptype} ETA: $call->{eta})"; + if($call->{status} eq 'Covered'){ + $c->reply("Call $callnr $callinfo is covered."); + 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"); + } +}; + +command settype => { + help => q(Usage: .settype incId type | or: .settyp callId X:Y:Z type | or: .settypeall callId type), + type => q(def), + acl => q(irc_settype), + alias => q(settypeall), +}, class extends NDIRC::Command { + use CGI; + method execute($c,$msg) { + my $dbh = $c->model; + + my $query = q{ +SELECT inc,call,shiptype, coords(x,y,z),c.landing_tick - tick() AS eta +FROM incomings i + JOIN current_planet_stats p USING (pid) + JOIN calls c USING (call) + }; + my $fleets; + my $type; + my $call; + + if ($self->name eq 'settypeall'){ + ($call,$type) = $msg =~ /^(\d+) (.*)$/ or die 'ARGS'; + + $fleets = $dbh->prepare($query . q{ +WHERE call = ? + }); + $fleets->execute($call); + }else{ + my ($id,$x,$y,$z,$t) = $msg =~ /^(\d+) (\d+):(\d+):(\d+) (.*)$/; + if (defined $id){ + $fleets = $dbh->prepare($query . q{ +WHERE call = ? AND pid = planetid(?,?,?,tick()) + }); + $fleets->execute($id,$x,$y,$z); + }else{ + ($id,$t) = $msg =~ /^(\d+) (.*)$/ or die 'ARGS'; + $fleets = $dbh->prepare($query . q{ +WHERE inc = ? + }); + $fleets->execute($id); + } + $type = $t; + } + + $type = CGI::escapeHTML($type); + $dbh->begin_work; + my $deflog = ''; + my $settype = $dbh->prepare(q{UPDATE incomings SET shiptype = ? WHERE inc = ?}); + while (my $inc = $fleets->fetchrow_hashref){ + $call //= $inc->{call}; + if ($inc->{eta} < 0){ + $c->reply("This call is old. Did you use the call id instead of inc id by" + ." accident? You can use .settypeall callid to set the type on all incs" + ." in a call. Or use webbie if you really want to update this old call."); + $dbh->rollback; + return; + } + $settype->execute($type,$inc->{inc}); + $deflog .= "Set fleet: [B]$inc->{inc} [/B] to: [B]$type [/B]\n"; + $c->reply("Set fleet $inc->{inc} from $inc->{coords} on call $call to $type (previously $inc->{shiptype})"); + } + if ($fleets->rows == 0){ + $c->reply("No matching fleets"); + $dbh->rollback; + }else{ + $c->def_log($call,$deflog); + $dbh->commit; + } + } +}; + +command calltake => { + help => q(Usage: .calltake callid | sets the dc. also markes as covered/ignored with .callcov and .callignore), + type => q(def), + acl => q(irc_calltake), + alias => [qw/callcov callignore/], +}, class extends NDIRC::Command { + method execute($c,$msg) { + my ($id) = $msg =~ /^(\d+)$/ or die 'ARGS'; + my $dbh = $c->model; + + my $status = 'Open'; + + given ($self->{name}){ + when('callignore'){ + $status = 'Ignored'; + } + when('callcov'){ + $status = 'Covered'; + } + } + + $dbh->begin_work; + my $rows = $dbh->do(q{ +UPDATE calls SET dc = $1 + ,status = $3 +WHERE call = $2 + },undef,$c->uid,$id,$status); + if ($rows == 1){ + $c->reply("Setting status on call $id to $status"); + $c->def_log($id , "Changed status: [B]$status [/B]"); + $dbh->commit; + }else{ + $c->reply("$id is not a valid call"); + $dbh->rollback; + } + } +}; + +command setcalc => { + help => q(Usage: .setcalc callId calc | sets the calc for the given call.), + type => q(def), + acl => q(irc_setcalc), +}, class extends NDIRC::Command { + use CGI; + method execute($c,$msg) { + my ($id,$calc) = $msg =~ /^(\d+) (.+)$/ or die 'ARGS'; + my $dbh = $c->model; + + $dbh->begin_work; + my $rows = $dbh->do(q{UPDATE calls SET calc = $2 WHERE call = $1} + ,undef,$id, $calc); + if ($rows == 1){ + $c->reply("Updated calc call $id"); + $calc = CGI::escapeHTML($calc); + $c->def_log($id , 'Updated calc to: [URL]'.$calc.'[/URL]'); + $dbh->commit; + }else{ + $c->reply("$id is not a valid call"); + $dbh->rollback; + } + } +}; + +command getcalc => { + help => q(Usage: .getcalc callId | receives the calc for the given call), + type => q(def), + acl => q(irc_getcalc), +}, class extends NDIRC::Command { + method execute($c,$msg) { + my ($id) = $msg =~ /^(\d+)$/ or die 'ARGS'; + my $dbh = $c->model; + + my $calc = $dbh->selectrow_array(q{ +SELECT calc FROM calls WHERE call = $1} + ,undef,$id); + $calc //= "Bad call id, there is no such call."; + $c->reply("Calc for call $id: $calc"); + } +}; + +command report_incs => { + help => q(Used to report incs, same as pasting in pm. Use ~ prefix to send output to channel), + type => q(def), +}, class extends NDIRC::Command { + use Try::Tiny; + method execute($c,$msg) { + + $msg =~ /(\d+):(\d+):(\d+)\*?\s+(\d+):(\d+):(\d+)\s+([^:]*\S+)\s+(?:Ter|Cat|Xan|Zik|Etd)\s+([\d,]+)\s+(?:Attack\s+)?(\d+)/ + || $msg =~ /(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)\s+\((?:Ter|Cat|Xan|Zik|Etd)\)\s+([^,]*\S+)\s+([\d,]+)\s+(\d+)\s+\(\d+\)/ + or return; + my $dbh = $c->model; + my $amount = $8; + { + $amount =~ s/,//g; + } + + my $st = $dbh->prepare(q{ +SELECT username, uid, pid, defprio +FROM users_defprio u +WHERE pid = planetid($1,$2,$3,tick()) + AND uid IN (SELECT uid FROM groupmembers WHERE gid = 'M') + }); + if (my $user = $dbh->selectrow_hashref($st,undef,$1,$2,$3)){ - my ($target,$mess) = $msg =~ /^(\S+) (.*)$/ or die 'ARGS'; + $st = $dbh->prepare(q{ +SELECT nick,alliance,pid,planet_status,relationship +FROM current_planet_stats WHERE x = ? AND y = ? AND z = ? + }); + if (my @attacker = $dbh->selectrow_array($st,undef,$4,$5,$6)){ + try { + $dbh->begin_work; + my $landing_tick = $dbh->selectrow_array(q{SELECT tick() + ?},undef,$9); + my @call = $dbh->selectrow_array(q{ +SELECT call,status,calc +FROM calls WHERE uid = ? AND landing_tick = ? + },undef,$user->{uid},$landing_tick); + my $threefleeter = $dbh->selectrow_array(q{ +SELECT COALESCE(gid = 'X',false) +FROM groupmembers WHERE uid = ? AND gid = 'X' + },undef,$user->{uid}); + unless (@call){ #call doesn't exists, create a new one + @call = $dbh->selectrow_array(q{ +INSERT INTO calls (uid,landing_tick,info) VALUES(?,?,'') RETURNING call,status,calc + },undef,$user->{uid},$landing_tick); + if ($threefleeter){ + $dbh->do(q{UPDATE calls SET status = 'Ignored' WHERE call = $1},undef,$call[0]); + $c->def_log($call[0], 'This member has been marked as [B]NoDef[/B], do [B]not cover[/B] unless you have a good reaon.'); + $call[1] = 'Ignored'; + } + } + my $pointlimits = $dbh->prepare(q{SELECT value :: float FROM misc WHERE id = ?}); + my ($minpoints) = $dbh->selectrow_array($pointlimits,undef,'DEFMINPRIO'); + my ($maxpoints) = $dbh->selectrow_array($pointlimits,undef,'DEFMAXPRIO'); + my $color = 3; + if ($user->{defprio} < $minpoints){ + $color = 5; + }elsif ($user->{defprio} < $maxpoints){ + $color = 8; + } + $user->{defprio} = "$user->{defprio}"; + $st = $dbh->prepare(q{SELECT pid FROM incomings WHERE pid = ? AND amount = ? and fleet = ? AND call = ?}); + unless (my @inc = $dbh->selectrow_array($st,undef,$attacker[2],$amount,$7,$call[0])){ + my $incid = $dbh->selectrow_array(q{ +INSERT INTO incomings (call,pid,eta,amount,fleet) VALUES(?,?,?,?,?) RETURNING inc + },undef,$call[0],$attacker[2],$9,$amount,$7); + @attacker = map ($c->valuecolor(0),@attacker); + if (! $threefleeter || $call[1] ne 'Ignored'){ + $c->reply("New incoming: CallId: $call[0], IncId: $incid $1:$2:$3 ($user->{defprio}) is under Attack by $4:$5:$6, ($attacker[3]), $attacker[1]($attacker[4]) https://nd.ruin.nu/calls/edit/$call[0]"); + }else{ + $c->reply("Do not cover, NoDef member is under attack by $4:$5:$6, ($attacker[3]), $attacker[1]($attacker[4]) https://nd.ruin.nu/calls/edit/$call[0]"); + } + $dbh->do(q{UPDATE planets SET hit_us = hit_us + 1 WHERE pid = ?},undef,$attacker[2]); + if ($call[1] eq 'Covered'){ + $dbh->do(q{UPDATE calls SET status = 'Open' WHERE call = ?},undef,$call[0]); + $c->reply("Call is likely not covered anymore, please recalc! calc: $call[2]"); + } + }else{ + @attacker = map ($c->valuecolor(0),@attacker); + $c->reply("Duplicate call: Callid: $call[0], Status: $call[1] $1:$2:$3 ($user->{defprio}) is under Attack by $4:$5:$6, ($attacker[3]), $attacker[1]($attacker[4]), landing tick: $landing_tick"); + } - $c->message("msg $target", "$mess"); - $c->message("msg ".$c->channel, "$target << $mess"); -} + my ($fleetcatch) = $dbh->selectrow_array(q{ +SELECT count(*) FROM launch_confirmations WHERE uid = ? AND back = ? + },undef,$user->{uid},$landing_tick); + if ($fleetcatch > 0){ + $c->reply("THIS IS A POSSIBLE FLEETCATCH!"); + } + $dbh->commit; + } catch { + $dbh->rollback; + die $_; + }; + }else{ + $c->reply("Didn't find any planet with coordinates $4:$5:$6 at this tick"); + } + }else{ + $c->reply("No member registered with coordinates $1:$2:$3"); + } + } +}; 1;