]> ruin.nu Git - NDIRC.git/blob - Commands/Usermgm.pm
Updated .whois to show discord_id
[NDIRC.git] / Commands / Usermgm.pm
1 #**************************************************************************
2 #   Copyright (C) 2009 by Michael Andreen <harvATruinDOTnu>               *
3 #                                                                         *
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.                                   *
8 #                                                                         *
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.                          *
13 #                                                                         *
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 #**************************************************************************/
19
20 use strict;
21 use warnings;
22 use feature ':5.10';
23
24 use MooseX::Declare;
25 use NDIRC::Dispatcher;
26
27 command '+user' => {
28         help => q(syntax: .+user username id | username must be alphanum characters, assumes discord id if it ends with #XXXX otherwise pnick),
29         type => q(usermgmt),
30         acl => 'irc_adduser'
31 }, class extends NDIRC::Command {
32         method execute ($c,$msg) {
33                 my ($nick,$id) = $msg =~ /^(\w+) (.+)$/ or die 'ARGS';
34
35                 my $dbh = $c->model;
36                 my $pnick = undef;
37                 my $discordid = undef;
38                 my $host = undef;
39
40                 if ($id =~ /.+#\d+/) {
41                         $discordid = $id;
42                 } else {
43                         $pnick = $id;
44                         $host = "$pnick.users.netgamers.org";
45                 }
46                 my ($username,$hostname,$p_nick,$discord_id) = $dbh->selectrow_array(q{
47 SELECT username, hostmask,pnick,discord_id
48 FROM users WHERE username = $1 OR hostmask = $2 OR pnick = $3 OR discord_id = $4
49                         },undef,$nick,$host,$pnick,$discordid);
50
51                 if (defined $username){
52                         $c->reply("<b>$username ($p_nick, $discord_id)</b> already exists with host: <b>$hostname</b>");
53                 }else{
54                         $dbh->do(q{
55 INSERT INTO users (username,hostmask,pnick,discord_id) VALUES($1,$2,$3,$4)
56                                 },undef,$nick,$host,$pnick,$discordid);
57                         $c->reply("Added <b>$nick(/$id)</b>");
58                 }
59         }
60 };
61
62 command '-user' => {
63         help => q(syntax: .-user nick | nick must be alphanum characters, if no pnick is given then it will be set to nick),
64         type => q(usermgmt),
65         acl => 'irc_deactivateuser'
66 }, class extends NDIRC::Command {
67         method execute ($c,$msg) {
68                 my ($nick) = $msg =~ /^(\S+)$/ or die 'ARGS';
69
70                 my $dbh = $c->model;
71                 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
72                 $f->execute($nick);
73                 my ($uid,$username) = $f->fetchrow();
74
75                 if ($f->rows == 1){
76                         my $updated = $dbh->do(q{
77 UPDATE users SET hostmask = $1, password = NULL WHERE uid = $2
78                                 },undef,$username,$uid);
79                         if ($updated > 0){
80                                 my $groups = $dbh->do(q{DELETE FROM groupmembers WHERE uid = ?},undef,$uid);
81                                 $groups += 0;
82                                 $c->reply("<b>$username</b> has been deactivated. Removed from $groups groups.");
83                         }else{
84                                 $c->reply("Something went wrong when trying to modify <b>$username</b>");
85                         }
86                 }elsif ($f->rows == 0){
87                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
88                 }else{
89                         $c->reply("More than 1 user matched, please refine the search");
90                 }
91                 $f->finish;
92         }
93 };
94
95 command chattr => {
96         help => q(syntax: .chattr username [-]flags | % can be used for wildcards \%arro% will match barrow, if a - is given then flags will be removed, otherwise added),
97         type => q(usermgmt),
98         acl => 'irc_chattr'
99 }, class extends NDIRC::Command {
100         method execute ($c,$msg) {
101                 my ($nick, $mode, $flags) = $msg =~ /^(\S+) (\+|-)?(\w+)$/ or die 'ARGS';
102                 my $dbh = $c->model;
103
104                 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
105                 $f->execute($nick);
106                 my $user = $f->fetchrow_hashref;
107                 if ($f->rows == 1){
108                         my $update;
109                         if ($mode ~~ '-'){
110                                 $update = $dbh->prepare(q{
111 DELETE FROM groupmembers WHERE uid = $1 AND gid = ANY($2)
112                                         });
113                         }else{
114                                 $update = $dbh->prepare(q{
115 INSERT INTO groupmembers (uid,gid)
116         (SELECT $1,gid FROM unnest($2::text[]) gid WHERE
117                 gid NOT IN (SELECT gid FROM groupmembers WHERE uid = $1)
118                 AND gid IN (SELECT gid FROM groups))
119                                 });
120                         }
121                         my @flags = split /\W*/,$flags;
122                         $update->execute($user->{uid},\@flags);
123                         $update = $dbh->prepare(q{
124 SELECT array_to_string(array_agg(gid),'')
125 FROM (SELECT uid,gid FROM groupmembers ORDER BY uid,gid ) g
126 WHERE uid = ?
127                                 });
128                         $flags = $dbh->selectrow_array($update,undef,$user->{uid});
129                         $c->reply("Flags for <b>$user->{username}</b> are now: $flags");
130                 }elsif ($f->rows == 0){
131                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
132                 }else{
133                         $c->reply("More than 1 user matched, please refine the search");
134                 }
135                 $f->finish;
136         }
137 };
138
139 command flags => {
140         help => q(Lists all the available flags),
141         acl => 'irc_whois'
142 }, class extends NDIRC::Command {
143         method execute ($c,$msg) {
144                 my $dbh = $c->model;
145                 my ($flags) = $dbh->selectrow_array(q{
146 SELECT array_to_string(array_agg(gid||':'||groupname),', ') FROM groups
147                         });
148                 $c->reply("Current flags: $flags");
149         }
150 };
151
152 command whois => {
153         help => q(syntax: .whois username | % can be used for wildcards \%arro% will match barrow.),
154         acl => 'irc_whois'
155 }, class extends NDIRC::Command {
156         method execute ($c,$msg) {
157                 my ($nick) = $msg =~ /^(\S+)$/ or die 'ARGS';
158                 my $dbh = $c->model;
159
160
161                 my $f = $dbh->prepare(q{
162 SELECT username, pnick, hostmask, discord_id, array_to_string(array_agg(gid),'') AS flags
163 FROM users u
164         LEFT OUTER JOIN (SELECT uid,gid FROM groupmembers ORDER BY uid,gid
165         ) g USING (uid)
166 WHERE username ILIKE ?
167 GROUP BY username,pnick,hostmask,discord_id LIMIT 5
168                         });
169                 $f->execute($nick);
170                 while (my $user = $f->fetchrow_hashref){
171                         $c->reply("<b>$user->{username}</b> (<b>$user->{pnick},$user->{discord_id}</b>) flags: ($user->{flags}) host: $user->{hostmask}");
172                 }
173                 if ($f->rows == 0){
174                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
175                 }
176         }
177 };
178
179 command flag => {
180         help => q(syntax: .flag flag [-noflags] | Lists all users with the given flag. Can specify a second argument to remove members that has any of those flags. .flag M -C lists all members that doesn't have community flag),
181         acl => 'irc_flag'
182 }, class extends NDIRC::Command {
183         method execute ($c,$msg) {
184                 my ($flag,$noflag) = $msg =~ /^(\w)(?: -(\w+))?$/ or die 'ARGS';
185                 $noflag //= '';
186
187                 my $f = $c->model->prepare(q{
188 SELECT array_to_string(array_agg(username),', '),count(username)
189 FROM (SELECT uid, username FROM users ORDER BY username) u
190         JOIN groupmembers gm USING (uid)
191 WHERE gid = $1 AND uid NOT IN (SELECT uid FROM groupmembers WHERE gid =  ANY($2))
192                         });
193                 my @noflag = split //, $noflag;
194                 my ($users,$count) = $c->model->selectrow_array($f,undef,$flag,\@noflag);
195                 $c->reply("<b>$count</b> Users with flag <b>$flag</b>: $users");
196         }
197 };
198
199 command laston => {
200         help => q(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),
201         acl => 'irc_laston'
202 }, class extends NDIRC::Command {
203         method execute ($c,$msg) {
204                 my ($flag,$min,$forum,$claim) = $msg =~ /^(\w)(?: (\d+)(?:\|(\d+)\|(\d+))?)?$/
205                         or die 'ARGS';
206                 $min //= 0;
207
208                 my $f = $c->model->prepare(q{
209 SELECT username, COALESCE(last::text,'?') AS last
210         ,COALESCE(lastforum::text,'?') AS lastforum
211         ,COALESCE(lastclaim::text,'?') AS lastclaim
212 FROM (SELECT username
213                 ,date_part('day',now() - laston)::int AS last
214                 ,date_part('day',now() -
215                         (SELECT max(time) FROM forum_thread_visits WHERE uid = u.uid)) AS lastforum
216                 ,date_part('day',now() -
217                         (SELECT max(timestamp) FROM raid_claims WHERE uid = u.uid)) AS lastclaim
218         FROM users u
219                 NATURAL JOIN groupmembers
220         WHERE gid = $1
221         ) a
222 WHERE COALESCE(last >= $2,TRUE) AND COALESCE(lastforum >= $3,TRUE)
223         AND COALESCE(lastclaim >= $4,TRUE)
224 ORDER BY a.last DESC, a.lastforum DESC, a.lastclaim DESC
225                         });
226                 $f->execute($flag,$min,$forum,$claim);
227
228                 my $text;
229                 my $i = 0;
230                 while (my $user = $f->fetchrow_hashref){
231                         $text .= "$user->{username}($user->{last}|$user->{lastforum}|$user->{lastclaim}) ";
232                         $i++;
233                 }
234                 $c->reply("<b>$i</b> Users(days) with flag <b>$flag</b>: $text");
235         }
236 };
237
238
239 command lastseen => {
240         help => q(syntax: .lastseen username | Shows the number of days since the user(s) last visited irc, forum and raids),
241         acl => 'irc_lastseen'
242 }, class extends NDIRC::Command {
243         method execute ($c,$msg) {
244                 my ($username) = $msg =~ /^(\S+)$/ or die 'ARGS';
245
246                 my $f = $c->model->prepare(q{
247 SELECT username, COALESCE(date_part('day',now() - laston)::text,'?') AS last
248         ,COALESCE(date_part('day',now() - (SELECT max(time)
249                 FROM forum_thread_visits WHERE uid = u.uid))::text,'?') AS lastforum
250         ,COALESCE(date_part('day',now() - (SELECT max(timestamp)
251                 FROM raid_claims WHERE uid = u.uid))::text,'?') AS lastclaim
252 FROM users u
253 WHERE username ILIKE $1 ORDER BY username
254                         });
255                 $f->execute($username);
256
257                 my $text;
258                 my $i = 0;
259                 while (my $user = $f->fetchrow_hashref){
260                         $text .= "$user->{username}($user->{last}|$user->{lastforum}|$user->{lastclaim}) ";
261                         $i++;
262                 }
263                 $c->reply("<b>$i</b> Users(days): $text");
264         }
265 }
266
267 command getships => {
268         help => q(Usage: .getships ship | % can be used as wildcard, e.g. beet%, shipshome shows the number of ships currently home),
269         alias => 'shipshome',
270         acl => 'irc_getships'
271 }, class extends NDIRC::Command {
272         method execute ($c,$msg) {
273                 my ($ship) = $msg =~ /^(\S+)$/ or die 'ARGS';
274                 my $dbh = $c->model;
275
276                 my $f = $dbh->prepare(q{
277 SELECT username,SUM(fs.amount) AS amount
278 FROM users u
279         JOIN (SELECT DISTINCT ON (pid) pid,fid FROM fleets
280                 WHERE mission = 'Full fleet' AND name <> 'Unit'
281                 ORDER BY pid,tick DESC,fid DESC
282         ) f  USING (pid)
283         JOIN fleet_ships fs USING (fid)
284 WHERE ship ILIKE $1 AND uid IN (SELECT uid FROM groupmembers WHERE gid = 'M')
285 GROUP BY username ORDER BY amount DESC
286                         });
287                 if ($self->name eq 'shipshome'){
288                         $f = $dbh->prepare(q{
289 SELECT username,SUM(amount) AS amount
290 FROM available_ships
291 WHERE ship ILIKE ? AND uid IN (SELECT uid FROM groupmembers WHERE gid = 'M')
292 GROUP BY username ORDER BY amount DESC
293                                 });
294                 }
295                 $f->execute($ship);
296                 my $text;
297                 my $i = 0;
298                 my $total = 0;
299                 while (my $user = $f->fetchrow_hashref){
300                         $text .= "$user->{username}: $user->{amount} ";
301                         $i++;
302                         $total += $user->{amount};
303                 }
304                 if ($text){
305                         $c->reply("<b>$i</b> Users with <b>$total $ship</b>: $text");
306                 }else{
307                         $c->reply("Couldn't find any user with <b>$ship</b>");
308                 }
309         }
310 };
311
312 command getfleet => {
313         help => q(Usage: .getfleet username | % can be used as wildcard, e.g. barr%),
314         acl => q(irc_getfleet)
315 }, class extends NDIRC::Command {
316         method execute ($c,$msg) {
317                 my ($nick) = $msg =~ /^(\S+)$/ or die 'ARGS';
318                 my $dbh = $c->model;
319
320                 my $f = $dbh->prepare(q{
321 SELECT fs.ship, fs.amount, username
322 FROM fleet_ships fs
323         JOIN (SELECT fid,username
324                 FROM fleets f
325                         JOIN users u USING (pid)
326                 WHERE mission = 'Full fleet' AND name <> 'Unit'
327                         AND username ILIKE $1
328                 ORDER BY pid,tick DESC,fid DESC
329                 LIMIT 1
330         ) f  USING (fid)
331 ORDER BY num
332                         });
333                 $f->execute($nick);
334                 my $text;
335                 my $username;
336                 while (my $ship = $f->fetchrow_hashref){
337                         unless (defined $username) {
338                                 $username = $ship->{username};
339                                 $text = "<b>$username</b> has: "
340                         }
341                         $text .= "$ship->{ship} $ship->{amount} ";
342                 }
343                 if ($text){
344                         $c->reply($text);
345                 }else{
346                         $c->reply("Couldn't find any fleet for $nick");
347                 }
348         }
349 };
350
351 command sethost => {
352         help => q(Usage: .sethost username [host] | if host isn't given then it resets to netgamers host),
353         acl => q(irc_sethost)
354 }, class extends NDIRC::Command {
355         method execute ($c,$msg) {
356                 my ($nick,$host) = $msg =~ /^(\S+)(?: (\S+))?$/ or die 'ARGS';
357                 my $dbh = $c->model;
358
359                 my $f = $dbh->prepare(q{
360 SELECT uid,username,pnick,hostmask FROM users WHERE username ILIKE ?
361                         });
362                 $f->execute($nick);
363                 my $user = $f->fetchrow_hashref;
364                 if ($f->rows == 1){
365                         $host //= "$user->{pnick}.users.netgamers.org";
366                         eval{
367                                 $dbh->do(q{UPDATE users SET hostmask = ? WHERE uid = ?}
368                                         ,undef,$host,$user->{uid});
369                                 $c->reply("Updated <b>$user->{username}</b>'s host to: <b>$host</b>");
370                         };
371                         if($@){
372                                 if ($@ =~ /duplicate key value violates unique constraint/){
373                                         my ($username, $hostname) = $dbh->selectrow_array(q{
374 SELECT username,hostmask FROM users WHERE hostmask = $1
375                                                 },undef,$host);
376                                         $c->reply("<c04>Problem</c>, <b>$username</b> already uses host <b>$hostname</b>.");
377                                 }else{
378                                         die $@;
379                                 }
380                         }
381                 }elsif ($f->rows == 0){
382                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
383                 }else{
384                         $c->reply("More than 1 user matched, please refine the search");
385                 }
386                 $f->finish;
387         }
388 };
389
390 command setpnick => {
391         help => q(Usage: .setpnick username pnick | Changes a user's pnick),
392         acl => q(irc_setpnick)
393 }, class extends NDIRC::Command {
394         method execute ($c,$msg) {
395                 my ($nick,$pnick) = $msg =~ /^(\S+) (\S+)$/ or die 'ARGS';
396                 my $dbh = $c->model;
397
398                 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
399                 $f->execute($nick);
400                 my $user = $f->fetchrow_hashref;
401                 if ($f->rows == 1){
402                         my $hostname = "$pnick.users.netgamers.org";
403                         eval{
404                                 $dbh->do(q{UPDATE users SET pnick = ?, hostmask = ? WHERE uid = ?}
405                                         ,undef,$pnick,$hostname,$user->{uid});
406                                 $c->reply("Updated <b>$user->{username}</b>'s pnick to: <b>$pnick</b> and hostname to <b>$hostname</b>");
407                         };
408                         if($@){
409                                 if ($@ =~ /duplicate key value violates unique constraint/){
410                                         my ($username, $hostname, $pnick) = $dbh->selectrow_array(q{
411 SELECT username,hostmask,pnick FROM users WHERE hostmask = $1 OR pnick = $2
412                                                 },undef,$hostname, $pnick);
413                                         $c->reply("<c04>Problem</c>, <b>$username</b> already uses host <b>$hostname</b> and pnick <b>$pnick</b>.");
414                                 }else{
415                                         die $@;
416                                 }
417                         }
418                 }elsif ($f->rows == 0){
419                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
420                 }else{
421                         $c->reply("More than 1 user matched, please refine the search");
422                 }
423                 $f->finish;
424         }
425 };
426
427 command setdiscordid => {
428         help => q(Usage: .setdiscordid username discordid | Changes a user's discord id/tag Nick#id),
429         acl => q(bot_setdiscordid)
430 }, class extends NDIRC::Command {
431         method execute ($c,$msg) {
432                 my ($nick,$discordid) = $msg =~ /^(\S+) (\S+)$/ or die 'ARGS';
433                 my $dbh = $c->model;
434
435                 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
436                 $f->execute($nick);
437                 my $user = $f->fetchrow_hashref;
438                 if ($f->rows == 1){
439                         eval{
440                                 $dbh->do(q{UPDATE users SET discord_id = NULLIF($1, 'NULL') WHERE uid = $2}
441                                         ,undef,$discordid,$user->{uid});
442                                 $c->reply("Updated <b>$user->{username}</b>'s discord id to: <b>$discordid</b>");
443                         };
444                         if($@){
445                                 if ($@ =~ /duplicate key value violates unique constraint/){
446                                         my ($username, $discordid) = $dbh->selectrow_array(q{
447 SELECT username,discord_id FROM users WHERE discord_id = $1
448                                                 },undef,$discordid);
449                                         $c->reply("<c04>Problem</c>, <b>$username</b> already uses discord id <b>$discordid</b>.");
450                                 }else{
451                                         die $@;
452                                 }
453                         }
454                 }elsif ($f->rows == 0){
455                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
456                 }else{
457                         $c->reply("More than 1 user matched, please refine the search");
458                 }
459                 $f->finish;
460         }
461 };
462
463 my $points = class extends NDIRC::Command {
464         has point => (
465                 is => 'ro',
466                 isa => 'Str',
467                 required => 1
468         );
469         method execute ($c,$msg) {
470                 my ($nick,$points) = $msg =~ /^(\S+)(?: (-?(:?\d+|\d*\.\d+)))?$/ or die 'ARGS';
471
472                 $points //= 1;
473
474                 return unless $self->check($c,$nick,$points);
475
476                 my $dbh = $c->model;
477
478                 if ($points*$points > 400){
479                         $c->reply("Values between -20 and 20 please");
480                         return;
481                 }
482
483                 my $f = $dbh->prepare(q{SELECT uid,username FROM users WHERE username ILIKE ?});
484                 $f->execute($nick);
485                 my $user = $f->fetchrow_hashref;
486                 if ($f->rows == 1){
487                         my $type .= $self->point . "_points";
488                         $dbh->do(qq{UPDATE users SET $type = $type + ? WHERE uid = ?}
489                                 ,undef,$points,$user->{uid});
490                         $c->reply("$user->{username} has been given $points $type");
491                 }elsif ($f->rows == 0){
492                         $c->reply("No hit, maybe spelling mistake, or add % as wildcard");
493                 }else{
494                         $c->reply("More than 1 user matched, please refine the search");
495                 }
496                 $f->finish;
497         }
498         method check ($c,$nick,$points) {
499                 return 1;
500         }
501 };
502
503 command a => {
504         help => q(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.),
505         point => 'attack',
506         acl => q(irc_a)
507 }, class {
508         extends $points->name;
509         method check ($c,$nick,$points) {
510                 my ($fleets) = $c->model->selectrow_array(q{
511 SELECT count(*) FROM raids r
512         JOIN raid_targets rt ON r.id = rt.raid
513         JOIN raid_claims rc ON rt.id = rc.target
514 WHERE not launched  AND tick + 24 > tick()
515         AND uid = (SELECT uid FROM users WHERE username ILIKE $1);
516                         },undef,$nick);
517
518                 if ($fleets > 0 && $points > 0){
519                         $c->reply("$nick has $fleets claimed waves the last 24 ticks that aren't marked as launched, so no points.");
520                         return 0;
521                 }
522                 return 1;
523         }
524 };
525
526 command d => {
527         help => q(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.),
528         acl => q(irc_d),
529         point => 'defense',
530         type => q(def)
531 }, $points;
532
533 command s => {
534         help => q(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.),
535         point => 'scan',
536         acl => q(irc_s),
537 }, $points;
538
539 command h => {
540         help => q(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.),
541         point => 'humor',
542         acl => q(irc_h),
543 }, $points;
544
545 command getanti => {
546         help => q(Usage: .getanti class [eta] | class is the target class, like fi or bs, eta is optional max eta for the ships.),
547         acl => q(irc_getships),
548 }, class extends NDIRC::Command {
549         method execute ($c,$msg) {
550                 my ($class,$eta) = $msg =~ /^(\S+)(?: (\d+))?$/ or die 'ARGS';
551                 my $dbh = $c->model;
552
553                 $eta //= 9;
554
555                 my @classes = qw/Fi Co Fr De Cr Bs/;
556                 for (@classes){
557                         if (lc $class eq lc $_){
558                                 $class = $_;
559                                 last;
560                         }
561                 }
562
563                 while ($eta < 9){
564                         pop @classes;
565                         pop @classes;
566                         $eta++;
567                 }
568
569                 my $f = $dbh->prepare(q{
570 SELECT username, ship, amount, CASE WHEN $1 = t1 THEN 't1' ELSE 't2' END AS t
571 FROM available_ships a
572         JOIN ship_stats s USING (ship)
573 WHERE uid IN (SELECT uid FROM groupmembers WHERE gid = 'M')
574         AND class = ANY($2)
575         AND $1 IN (t1,t2)
576 ORDER BY amount*(metal+crystal+eonium)*CASE WHEN $1 = t1 THEN 1.0 ELSE 0.6 END DESC
577                         });
578                 $f->execute($class,\@classes);
579                 my $text;
580                 my $i = 0;
581                 my $total = 0;
582                 while (my $user = $f->fetchrow_hashref){
583                         $text .= "($user->{username}: $user->{ship} $user->{amount} $user->{t}) ";
584                         $i++;
585                         $total += $user->{amount};
586                 }
587                 if ($text){
588                         $c->reply("<b>$i</b> fleets with anti-<b>$class</b>: $text");
589                 }else{
590                         $c->reply("Couldn't find any user with anti-<b>$class</b>");
591                 }
592         }
593 };
594
595 command getpass => {
596         help => q(Gives new users a random password.),
597         type => q(pm)
598 }, class extends NDIRC::Command {
599
600 ###########################################################
601 # Written by Guy Malachi http://guymal.com
602 # 18 August, 2002
603 ###########################################################
604         sub generate_random_string
605         {
606                 my $length_of_randomstring=shift;# the length of
607                 # the random string to generate
608
609                 my @chars=('a'..'z','A'..'Z','0'..'9','_');
610                 my $random_string;
611                 foreach (1..$length_of_randomstring)
612                 {
613                         # rand @chars will generate a random
614                         # number between 0 and scalar @chars
615                         $random_string .= $chars[rand @chars];
616                 }
617                 return $random_string;
618         }
619
620         method execute ($c,$msg) {
621                 my $dbh = $c->model;
622
623                 my $password = generate_random_string 16;
624                 my $update = $dbh->do(q{
625 UPDATE users SET password = $1
626 WHERE uid = $2 AND password IS NULL
627                         },undef,$password,$c->uid);
628                 if ($update > 0){
629                         $c->reply("Password set to: $password (you can change it on webbie)");
630                 }else{
631                         $c->reply("Couldn't set password. Either it has already been set or you don't have an account");
632                 }
633         }
634 };
635
636 1;