1 #**************************************************************************
2 # Copyright (C) 2009 by Michael Andreen <harvATruinDOTnu> *
4 # This program is free software; you can redistribute it and/or modify *
5 # it under the terms of the GNU General Public License as published by *
6 # the Free Software Foundation; either version 2 of the License, or *
7 # (at your option) any later version. *
9 # This program is distributed in the hope that it will be useful, *
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 # GNU General Public License for more details. *
14 # You should have received a copy of the GNU General Public License *
15 # along with this program; if not, write to the *
16 # Free Software Foundation, Inc., *
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 #**************************************************************************/
20 package NDIRC::Commands::Usermgm;
27 use MooseX::MethodAttributes;
30 : Help(syntax: .+user username [pnick] | username must be alphanum characters, if no pnick is given then it will be set to the same as username)
34 my ($self,$c,$msg) = @_;
35 my ($nick,$pnick) = $msg =~ /^(\w+)(?: ([^.\s]+))?$/ or die 'ARGS';
40 my $host = "$pnick.users.netgamers.org";
41 my ($username,$hostname,$p_nick) = $dbh->selectrow_array(q{
42 SELECT username, hostmask,pnick
43 FROM users WHERE username ILIKE ? OR hostmask ILIKE ? OR pnick ILIKE ?
44 },undef,$nick,$host,$pnick);
46 if (defined $username){
47 $c->reply("<b>$username ($p_nick)</b> already exists with host: <b>$hostname</b>");
50 INSERT INTO users (username,hostmask,pnick,password) VALUES(?,?,?,'')
51 },undef,$nick,$host,$pnick);
52 $c->reply("Added <b>$nick(/$pnick)</b> with host: <b>$host</b>");
57 : Help(syntax: .-user nick | nick must be alphanum characters, if no pnick is given then it will be set to nick)
59 : ACL(irc_deactivateuser)
61 my ($self,$c,$msg) = @_;
63 my ($nick) = $msg =~ /^(\S+)$/ or die 'ARGS';
66 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
68 my ($uid,$username) = $f->fetchrow();
71 my $updated = $dbh->do(q{
72 UPDATE users SET hostmask = ?, password = '' WHERE uid = ?
73 },undef,$username,$uid);
75 my $groups = $dbh->do(q{DELETE FROM groupmembers WHERE uid = ?},undef,$uid);
77 $c->reply("<b>$username</b> has been deactivated. Removed from $groups groups.");
79 $c->reply("Something went wrong when trying to modify <b>$username</b>");
81 }elsif ($f->rows == 0){
82 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
84 $c->reply("More than 1 user matched, please refine the search");
90 : Help(syntax: .chattr username [-]flags | % can be used for wildcards \%arro% will match barrow, if a - is given then flags will be removed, otherwise added)
93 my ($self,$c,$msg) = @_;
95 my ($nick, $flags) = $msg =~ /^(\S+) ((\+|-)?\w+)$/ or die 'ARGS';
98 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
100 my $user = $f->fetchrow_hashref;
103 if ($flags =~ /^(-)/){
104 $update = $dbh->prepare(q{
105 DELETE FROM groupmembers WHERE uid = $1 AND gid = ANY($2)
108 $update = $dbh->prepare(q{
109 INSERT INTO groupmembers (uid,gid)
110 (SELECT $1,gid FROM unnest($2::text[]) gid WHERE
111 gid NOT IN (SELECT gid FROM groupmembers WHERE uid = $1)
112 AND gid IN (SELECT gid FROM groups))
115 my @flags = split /\W*/,$flags;
116 $update->execute($user->{uid},\@flags);
117 $update = $dbh->prepare(q{
118 SELECT array_to_string(array_agg(gid),'')
119 FROM (SELECT uid,gid FROM groupmembers ORDER BY uid,gid ) g
122 $flags = $dbh->selectrow_array($update,undef,$user->{uid});
123 $c->reply("Flags for <b>$user->{username}</b> are now: $flags");
124 }elsif ($f->rows == 0){
125 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
127 $c->reply("More than 1 user matched, please refine the search");
133 : Help(syntax: .whois [username] | % can be used for wildcards \%arro% will match barrow. If no username is given then all flags will be listed)
137 my ($self,$c,$msg) = @_;
138 my ($nick) = $msg =~ /^(\S+)?$/ or die 'ARGS';
142 my ($flags) = $dbh->selectrow_array(q{
143 SELECT array_to_string(array_agg(gid||':'||groupname),', ') FROM groups
145 $c->reply("Current flags: $flags");
149 my $f = $dbh->prepare(q{
150 SELECT username, pnick, hostmask, array_to_string(array_agg(gid),'') AS flags
152 LEFT OUTER JOIN (SELECT uid,gid FROM groupmembers ORDER BY uid,gid
154 WHERE username ILIKE ?
155 GROUP BY username,pnick,hostmask LIMIT 5
158 while (my $user = $f->fetchrow_hashref){
159 $c->reply("<b>$user->{username} (/$user->{pnick})</b> flags: ($user->{flags}) host: $user->{hostmask}");
162 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
167 : Help(syntax: .flag flag | Lists all users with the given flag.)
170 my ($self,$c,$msg) = @_;
171 my ($flag) = $msg =~ /^(\w)$/ or die 'ARGS';
173 my $f = $c->model->prepare(q{
174 SELECT array_to_string(array_agg(username),', '),count(username)
175 FROM (SELECT uid, username FROM users ORDER BY username) u
176 JOIN groupmembers gm USING (uid)
179 my ($users,$count) = $c->model->selectrow_array($f,undef,$flag);
180 $c->reply("<b>$count</b> Users with flag <b>$flag</b>: $users");
184 : Help(syntax: .laston flag [days] | lists users and the number of days since they were last seen (irc|forum|claim). If days is specified it will only list users with at least that amount of idle time. Days can also specify forum and claim with irc|forum|claim syntax)
187 my ($self,$c,$msg) = @_;
188 my ($flag,$min,$forum,$claim) = $msg =~ /^(\w)(?: (\d+)(?:\|(\d+)\|(\d+))?)?$/
192 my $f = $c->model->prepare(q{
193 SELECT username, COALESCE(last::text,'?') AS last
194 ,COALESCE(lastforum::text,'?') AS lastforum
195 ,COALESCE(lastclaim::text,'?') AS lastclaim
196 FROM (SELECT username
197 ,date_part('day',now() - laston)::int AS last
198 ,date_part('day',now() -
199 (SELECT max(time) FROM forum_thread_visits WHERE uid = u.uid)) AS lastforum
200 ,date_part('day',now() -
201 (SELECT max(timestamp) FROM raid_claims WHERE uid = u.uid)) AS lastclaim
203 NATURAL JOIN groupmembers
206 WHERE COALESCE(last >= $2,TRUE) AND COALESCE(lastforum >= $3,TRUE)
207 AND COALESCE(lastclaim >= $4,TRUE)
208 ORDER BY a.last DESC, a.lastforum DESC, a.lastclaim DESC
210 $f->execute($flag,$min,$forum,$claim);
214 while (my $user = $f->fetchrow_hashref){
215 $text .= "$user->{username}($user->{last}|$user->{lastforum}|$user->{lastclaim}) ";
218 $c->reply("<b>$i</b> Users(days) with flag <b>$flag</b>: $text");
223 : Help(syntax: .lastseen username | Shows the number of days since the user(s) last visited irc, forum and raids)
226 my ($self,$c,$msg) = @_;
227 my ($username) = $msg =~ /^(\S+)$/ or die 'ARGS';
229 my $f = $c->model->prepare(q{
230 SELECT username, COALESCE(date_part('day',now() - laston)::text,'?') AS last
231 ,COALESCE(date_part('day',now() - (SELECT max(time)
232 FROM forum_thread_visits WHERE uid = u.uid))::text,'?') AS lastforum
233 ,COALESCE(date_part('day',now() - (SELECT max(timestamp)
234 FROM raid_claims WHERE uid = u.uid))::text,'?') AS lastclaim
236 WHERE username ILIKE $1 ORDER BY username
238 $f->execute($username);
242 while (my $user = $f->fetchrow_hashref){
243 $text .= "$user->{username}($user->{last}|$user->{lastforum}|$user->{lastclaim}) ";
246 $c->reply("<b>$i</b> Users(days): $text");
250 : Help(Usage: .getships ship | % can be used as wildcard, e.g. beet%, shipshome shows the number of ships currently home)
254 my ($self,$c,$msg) = @_;
255 my ($ship) = $msg =~ /^(\S+)$/ or die 'ARGS';
258 my $f = $dbh->prepare(q{
259 SELECT username,SUM(fs.amount) AS amount
261 JOIN (SELECT DISTINCT ON (pid) pid,fid FROM fleets
262 WHERE mission = 'Full fleet' AND name <> 'Unit'
263 ORDER BY pid,tick DESC,fid DESC
265 JOIN fleet_ships fs USING (fid)
266 WHERE ship ILIKE $1 AND uid IN (SELECT uid FROM groupmembers WHERE gid = 'M')
267 GROUP BY username ORDER BY amount DESC
269 if ($self->name eq 'shipshome'){
270 $f = $dbh->prepare(q{
271 SELECT username,SUM(amount) AS amount
273 WHERE ship ILIKE ? AND uid IN (SELECT uid FROM groupmembers WHERE gid = 'M')
274 GROUP BY username ORDER BY amount DESC
281 while (my $user = $f->fetchrow_hashref){
282 $text .= "$user->{username}: $user->{amount} ";
284 $total += $user->{amount};
287 $c->reply("<b>$i</b> Users with <b>$total $ship</b>: $text");
289 $c->reply("Couldn't find any user with <b>$ship</b>");
294 : Help(Usage: .getfleet username | % can be used as wildcard, e.g. barr%)
297 my ($self,$c,$msg) = @_;
298 my ($nick) = $msg =~ /^(\S+)$/ or die 'ARGS';
301 my $f = $dbh->prepare(q{
302 SELECT fs.ship, fs.amount, username
304 JOIN (SELECT fid,username
306 JOIN users u USING (pid)
307 WHERE mission = 'Full fleet' AND name <> 'Unit'
308 AND username ILIKE $1
309 ORDER BY pid,tick DESC,fid DESC
317 while (my $ship = $f->fetchrow_hashref){
318 unless (defined $username) {
319 $username = $ship->{username};
320 $text = "<b>$username</b> has: "
322 $text .= "$ship->{ship} $ship->{amount} ";
327 $c->reply("Couldn't find any fleet for $nick");
332 : Help(Usage: .sethost username [host] | if host isn't given then it resets to netgamers host)
335 my ($self,$c,$msg) = @_;
336 my ($nick,$host) = $msg =~ /^(\S+)(?: (\S+))?$/ or die 'ARGS';
339 my $f = $dbh->prepare(q{
340 SELECT uid,username,pnick,hostmask FROM users WHERE username ILIKE ?
343 my $user = $f->fetchrow_hashref;
345 $host //= "$user->{pnick}.users.netgamers.org";
347 $dbh->do(q{UPDATE users SET hostmask = ? WHERE uid = ?}
348 ,undef,$host,$user->{uid});
349 $c->reply("Updated <b>$user->{username}</b>'s host to: <b>$host</b>");
352 if ($@ =~ /duplicate key value violates unique constraint/){
353 my ($username, $hostname) = $dbh->selectrow_array(q{
354 SELECT username,hostmask FROM users WHERE hostmask ILIKE $1
356 $c->reply("<c04>Problem</c>, <b>$username</b> already uses host <b>$hostname</b>.");
361 }elsif ($f->rows == 0){
362 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
364 $c->reply("More than 1 user matched, please refine the search");
370 : Help(Usage: .setpnick username pnick | Changes a user's pnick)
373 my ($self,$c,$msg) = @_;
374 my ($nick,$pnick) = $msg =~ /^(\S+) (\S+)$/ or die 'ARGS';
377 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
379 my $user = $f->fetchrow_hashref;
381 my $hostname = "$pnick.users.netgamers.org";
383 $dbh->do(q{UPDATE users SET pnick = ?, hostmask = ? WHERE uid = ?}
384 ,undef,$pnick,$hostname,$user->{uid});
385 $c->reply("Updated <b>$user->{username}</b>'s pnick to: <b>$pnick</b> and hostname to <b>$hostname</b>");
388 if ($@ =~ /duplicate key value violates unique constraint/){
389 my ($username, $hostname, $pnick) = $dbh->selectrow_array(q{
390 SELECT username,hostmask,pnick FROM users WHERE hostmask ILIKE $1 OR pnick ILIKE $2
391 },undef,$hostname, $pnick);
392 $c->reply("<c04>Problem</c>, <b>$username</b> already uses host <b>$hostname</b> and pnick <b>$pnick</b>.");
397 }elsif ($f->rows == 0){
398 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
400 $c->reply("More than 1 user matched, please refine the search");
406 : Help(Usage: .a username [points] | % can be used for wildcards %arro% will match barrow, if the number of points isn't specified, then 1 will be assumed.)
409 my ($self,$c,$msg) = @_;
410 my ($nick,$points) = $msg =~ /^(\S+)(?: (-?(:?\d+|\d*\.\d+)))?$/ or die 'ARGS';
413 my ($fleets) = $c->model->selectrow_array(q{
414 SELECT count(*) FROM raids r
415 JOIN raid_targets rt ON r.id = rt.raid
416 JOIN raid_claims rc ON rt.id = rc.target
417 WHERE not launched AND tick + 24 > tick()
418 AND uid = (SELECT uid FROM users WHERE username ILIKE $1);
421 if ($fleets > 0 && $points > 0){
422 $c->reply("$nick has $fleets claimed waves the last 24 ticks that aren't marked as launched, so no points.");
425 addPoints($c, 'attack', $nick, $points);
429 : Help(Usage: .d username [points] | % can be used for wildcards %arro% will match barrow, if the number of points isn't specified, then 1 will be assumed.)
433 my ($self,$c,$msg) = @_;
434 my ($nick,$points) = $msg =~ /^(\S+)(?: (-?(:?\d+|\d*\.\d+)))?$/ or die 'ARGS';
436 addPoints($c, 'defense', $nick, $points);
440 : Help(Usage: .s username [points] | % can be used for wildcards %arro% will match barrow, if the number of points isn't specified, then 1 will be assumed.)
443 my ($self,$c,$msg) = @_;
444 my ($nick,$points) = $msg =~ /^(\S+)(?: (-?(:?\d+|\d*\.\d+)))?$/ or die 'ARGS';
446 addPoints($c, 'scan', $nick, $points);
450 : Help(Usage: .h username [points] | % can be used for wildcards %arro% will match barrow, if the number of points isn't specified, then 1 will be assumed.)
453 my ($self,$c,$msg) = @_;
454 my ($nick,$points) = $msg =~ /^(\S+)(?: (-?(:?\d+|\d*\.\d+)))?$/ or die 'ARGS';
456 addPoints($c, 'humor', $nick, $points);
460 my ($c,$type, $nick, $points) = @_;
465 if ($points*$points > 400){
466 $c->reply("Values between -20 and 20 please");
470 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
472 my $user = $f->fetchrow_hashref;
475 $dbh->do(qq{UPDATE users SET $type = $type + ? WHERE uid = ?}
476 ,undef,$points,$user->{uid});
477 $c->reply("$user->{username} has been given $points $type");
478 }elsif ($f->rows == 0){
479 $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
481 $c->reply("More than 1 user matched, please refine the search");