ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/commands.ext
Revision: 1.40
Committed: Fri Apr 13 05:32:12 2007 UTC (17 years, 1 month ago) by root
Branch: MAIN
Changes since 1.39: +23 -0 lines
Log Message:
move seen to commands.ext and fix it while doing so

File Contents

# User Rev Content
1 root 1.35 #! perl # MANDATORY
2 root 1.1
3     use POSIX ();
4    
5     # miscellaneous commands
6    
7     sub rename_to($$$) {
8     my ($ob, $from, $to) = @_;
9    
10 root 1.12 $to =~ /^[a-zA-Z0-9.,=#\/%$!^ ]*$/
11 root 1.1 or return $ob->message ("rename: name must consist only of letters, digits, spaces and a few other things.");
12    
13     127 >= length $to
14     or return $ob->message ("rename: new name must be <= 127 characters.");
15    
16     my $item;
17    
18     if (length $from) {
19     $item = $ob->find_best_object_match ($from)
20     or return $ob->message ("rename: could not find a matching item to rename.");
21     } else {
22 root 1.31 $item = $ob->find_marked_object
23 root 1.1 or return $ob->message ("rename: no from name and no marked item found to rename.");
24     }
25    
26     $item->custom_name (length $to ? $to : undef);
27    
28     if (length $to) {
29     $item->custom_name ($to);
30     $ob->message ("Your " . $item->base_name . " will now be called $to.");
31     } else {
32     $item->custom_name (undef);
33     $ob->message ("You stop calling your " . $item->base_name . " with weird names.");
34     }
35    
36     $ob->esrv_update_item (cf::UPD_NAME, $item);
37    
38     1
39     }
40    
41     sub ext::schmorp_irc::users; # HACK: TODO: replace by signal
42    
43     sub who_listing(;$) {
44     my ($privileged) = @_;
45    
46     my ($numwiz, $numafk) = (0, 0);
47     my @pl;
48    
49     foreach my $pl (cf::player::list) {
50 root 1.5 my $ns = $pl->ns or next;
51 root 1.1 my $ob = $pl->ob;
52    
53     next unless $ob->map
54     && ($privileged || !$pl->hidden);
55    
56     $numwiz++ if $ob->flag (cf::FLAG_WIZ);
57 root 1.5 $numafk++ if $ns->afk;
58 root 1.1
59     push @pl, $pl;
60     }
61    
62     (
63     "Total Players in The World. (" . (scalar @pl) . ") -- WIZ($numwiz) AFK($numafk) BOT(0)",
64     (
65     map {
66 root 1.5 my ($pl, $ob, $ns) = ($_, $_->ob, $_->ns);
67 root 1.1
68     "* " . $ob->name . "/" . $ob->level . " " . (length $pl->own_title ? $pl->own_title : "the " . $pl->title)
69     . ($pl->peaceful ? " [peaceful]" : " [HOSTILE]")
70 root 1.5 . ($ns->afk ? " [AFK]" : "")
71 root 1.1 . ($ob->flag (cf::FLAG_WIZ) ? " [WIZ]" : "")
72 root 1.4 . " [" . $pl->ns->version . "]"
73 root 1.18 . " [" . ($pl->peaceful || $privileged ? $ob->map->visible_name : $ob->region->name) . "]"
74 root 1.4 . (sprintf " [rtt %.3fs]", $pl->ns->rtt * 1e-6)
75     . ($privileged ? " " . $pl->ns->host : "")
76 root 1.1 } sort { (lc $a->ob->name) cmp (lc $b->ob->name) } @pl
77     ),
78     eval { "* IRC: " . join ", ", ext::schmorp_irc::users },
79     )
80     }
81    
82     cf::register_command who => sub {
83     my ($ob, $arg) = @_;
84    
85     $ob->speed_left ($ob->speed_left - 0.25);
86    
87     $ob->reply (undef, (join "\n", who_listing $ob->may ("extended_who")), cf::NDI_UNIQUE | cf::NDI_DK_ORANGE);
88    
89     1
90     };
91    
92 root 1.40 cf::register_command seen => sub {
93     my ($pl, $args) = @_;
94    
95     if (my ($login) = $args =~ /(\S+)/) {
96     if ($login eq $pl->name) {
97     $pl->message ("Very funny, $login. Ha. Ha.", cf::NDI_UNIQUE);
98     } elsif (cf::player::find_active $login) {
99     $pl->message ("$login is right here on this server!", cf::NDI_UNIQUE);
100     } elsif (cf::player::exists $login
101     and stat cf::player::path $login) {
102     my $time = (stat _)[9];
103    
104     $pl->message ("$login was last seen here "
105     . (POSIX::strftime "%Y-%m-%d %H:%M:%S +0000", gmtime $time)
106     . " which was " . (int +(time - $time) / 3600) . " hours ago.", cf::NDI_UNIQUE);
107     } else {
108     $pl->message ("No player named $login is known to me.", cf::NDI_UNIQUE);
109     }
110     } else {
111     $pl->message ("Usage: seen <player>", cf::NDI_UNIQUE);
112     }
113     };
114    
115 pippijn 1.27 cf::register_command body => sub {
116     my ($ob) = @_;
117    
118     my @body_locations = ("in your range slot", "on your arm", "on your body", "on your head",
119     "around your neck", "in your skill slot", "on your finger", "around your shoulders",
120     "on your feet", "on your hands", "around your wrists", "around your waist");
121    
122     # Too hard to try and make a header that lines everything up, so just
123     # give a description. (comment from C++)
124     $ob->reply (undef, "The first column is the name of the body location.");
125     $ob->reply (undef, "The second column is how many of those locations your body has.");
126     $ob->reply (undef, "The third column is how many slots in that location are available.");
127    
128     for (0 .. scalar @body_locations - 1) {
129     $ob->reply (undef, (sprintf "%-30s %5d %5d", $body_locations[$_], $ob->body_info($_), $ob->body_used($_)))
130     if $ob->body_info($_) or $ob->body_used($_);
131     }
132    
133     $ob->reply (undef, "You are not allowed to wear armor")
134     unless $ob->flag (cf::FLAG_USE_ARMOUR);
135     $ob->reply (undef, "You are not allowed to use weapons")
136     unless $ob->flag (cf::FLAG_USE_WEAPON);
137    
138     1
139     };
140    
141 pippijn 1.28 cf::register_command mark => sub {
142     my ($pl, $arg) = @_;
143    
144 pippijn 1.32 if (length $arg) {
145 pippijn 1.28 my $ob = $pl->find_best_object_match ($arg);
146    
147     return $pl->reply (undef, "Could not find an object that matches $arg")
148     unless $ob;
149    
150 pippijn 1.29 $pl->contr->mark ($ob);
151 pippijn 1.28 $pl->reply (undef, (sprintf "Marked item %s", $ob->name, $ob->title));
152 pippijn 1.32 } else {
153     my $ob = $pl->find_marked_object;
154    
155     $pl->reply (undef, $ob
156     ? (sprintf "%s %s * is marked.", $ob->name, $ob->title)
157     : "You have no marked object.");
158 pippijn 1.28 }
159    
160     1
161     };
162    
163     for my $cmd ("run", "fire") {
164     my $oncmd = "${cmd}_on";
165     cf::register_command $cmd => sub {
166     my ($ob, $arg) = @_;
167    
168 pippijn 1.34 $ob->reply (undef, "Can't $cmd into a non adjacent square.")
169 pippijn 1.28 if $arg < 0 or $arg >= 9;
170    
171 pippijn 1.34 $ob->contr->$oncmd (1);
172     $ob->move_player ($arg);
173 pippijn 1.28
174     1
175     };
176 pippijn 1.34
177 pippijn 1.28 cf::register_command "${cmd}_stop" => sub {
178     my ($ob) = @_;
179    
180     $ob->contr->$oncmd (0);
181    
182     1
183     };
184     }
185    
186 pippijn 1.26 cf::register_command mapinfo => sub {
187     my ($ob) = @_;
188    
189     my $map = $ob->map
190     or return;
191     $ob->reply (undef, (sprintf "%s (%s) %s", $map->name, $map->path, $ob->region->longname));
192     $ob->reply (undef, (sprintf "players: %d difficulty: %d size: %d start: %dx%d timeout: %d",
193     $map->players, $map->difficulty, $map->width, $map->height, $map->enter_x, $map->enter_y, $map->timeout))
194     if $ob->flag (cf::FLAG_WIZ);
195     $ob->reply (undef, $map->msg);
196    
197     1
198     };
199    
200 pippijn 1.25 cf::register_command whereami => sub {
201     my ($ob) = @_;
202    
203     my $reg = $ob->region;
204     $ob->reply (undef, (sprintf "You are %s.\n%s", $reg->longname, $reg->msg));
205    
206     1
207     };
208    
209 root 1.31 sub _set_mode($$$@) {
210     my ($name, $ob, $arg, $slot, @choices) = @_;
211 pippijn 1.23
212 root 1.31 my $oldmode = $ob->contr->$slot;
213 pippijn 1.23
214 root 1.31 return $ob->reply (undef, "$name is set to $choices[$oldmode]")
215 pippijn 1.23 unless $arg;
216    
217 root 1.31 my ($idx) = grep $choices[$_] eq $arg, 0 .. $#choices
218     or return $ob->reply (undef, "$name: Unknown options '$arg', valid options are @choices"), 1;
219 pippijn 1.23
220 root 1.31 $ob->contr->$slot ($idx);
221     $ob->reply (undef, "$name" . ($oldmode == $ob->contr->unapply ? "" : " now") . " set to " . $choices[$ob->contr->$slot]);
222     }
223    
224     cf::register_command applymode => sub {
225     my ($ob, $arg) = @_;
226    
227     _set_mode "applymode", $ob, $arg, unapply => qw(nochoice never always);
228 pippijn 1.23
229     1
230     };
231    
232     cf::register_command petmode => sub {
233     my ($ob, $arg) = @_;
234    
235 root 1.31 _set_mode "petmode", $ob, $arg, petmode => qw(normal sad defend arena);
236 pippijn 1.23
237     1
238     };
239    
240 pippijn 1.21 cf::register_command usekeys => sub {
241     my ($ob, $arg) = @_;
242    
243 root 1.31 _set_mode "usekeys", $ob, $arg, usekeys => qw(inventory keyrings containers);
244 pippijn 1.22
245     1
246 pippijn 1.21 };
247    
248 pippijn 1.19 cf::register_command afk => sub {
249     my ($ob, $arg) = @_;
250    
251     $ob->contr->ns->afk ($ob->contr->ns->afk ? 0 : 1);
252     $ob->reply (undef, $ob->contr->ns->afk ? "You are now AFK" : "You are no longer AFK");
253 pippijn 1.22
254     1
255 pippijn 1.19 };
256    
257 pippijn 1.21 cf::register_command sound => sub {
258     my ($ob, $arg) = @_;
259    
260     $ob->contr->ns->sound ($ob->contr->ns->sound ? 0 : 1);
261     $ob->reply (undef, $ob->contr->ns->sound ? "The sounds are enabled." : "Silence is golden...");
262 pippijn 1.22
263     1
264 pippijn 1.21 };
265    
266 pippijn 1.20 cf::register_command brace => sub {
267     my ($ob, $arg) = @_;
268    
269     $ob->contr->braced ($ob->contr->braced ? 0 : 1);
270     $ob->reply (undef, $ob->contr->braced ? "You are braced." : "Not braced.");
271 pippijn 1.22
272     1
273 pippijn 1.20 };
274    
275 root 1.35 cf::register_command 'output-rate' => sub {
276     my ($ob, $arg) = @_;
277    
278     return $ob->reply (undef, sprintf "Output rate is presently %dbps.", $ob->contr->ns->max_rate / $cf::TICK)
279     unless $arg > 0;
280    
281 root 1.39 # minimum is 2k/s
282     $ob->contr->ns->max_rate ((List::Util::max 2048, $arg) * $cf::TICK);
283 root 1.36 $ob->reply (undef, sprintf "Output rate now set to %dbps.", $ob->contr->ns->max_rate / $cf::TICK);
284 root 1.35
285     1
286     };
287    
288 pippijn 1.24 cf::register_command 'output-count' => sub {
289     my ($ob, $arg) = @_;
290    
291     return $ob->reply (undef, "Output count is presently " . $ob->contr->outputs_count)
292     unless $arg > 0;
293    
294     $ob->contr->outputs_count ($arg);
295     $ob->reply (undef, "Output count now set to " . $ob->contr->outputs_count);
296    
297     1
298     };
299    
300     cf::register_command 'output-sync' => sub {
301     my ($ob, $arg) = @_;
302    
303 root 1.38 return $ob->reply (undef, sprintf "Output sync time is presently %.1fs", $ob->contr->outputs_sync * $cf::TICK)
304     unless length $arg;
305 pippijn 1.24
306 root 1.38 $ob->contr->outputs_sync ($arg / $cf::TICK);
307     $ob->reply (undef, sprintf "Output sync time now set to %.1fs", $ob->contr->outputs_sync * $cf::TICK);
308 pippijn 1.24
309     1
310     };
311    
312 pippijn 1.20 # XXX: This has a bug. After one sets his wimpy level to 0 and resets it to
313     # some other level (which may also be 0), this does not get echoed,
314     # but it does get set.
315     cf::register_command wimpy => sub {
316     my ($ob, $arg) = @_;
317    
318     my $wimpy = $ob->run_away;
319     return $ob->reply (undef, "Your current wimpy level is $wimpy.")
320     if $arg eq "";
321    
322     return $ob->run_away ($arg) && $ob->reply (undef, "Your new wimpy level is $arg.")
323     if $arg =~ /^\d+$/ and $arg <= 100;
324    
325     $ob->reply (undef, "Incorrect parameters for wimpy: $arg");
326 pippijn 1.22
327     1
328 pippijn 1.20 };
329    
330     cf::register_command peaceful => sub {
331     my ($ob, $arg) = @_;
332    
333     $ob->reply (undef, "You cannot change your peaceful setting with this command."
334     ." Please speak to the priest in the temple of Gorokh"
335     ." if you want to become hostile or in temple of Valriel"
336     ." if you want to become peaceful again.");
337    
338     #$ob->contr->peaceful ($ob->contr->peaceful ? 0 : 1);
339     #$ob->reply (undef, $ob->contr->peaceful ? "You will attack other players." : "You will not attack other players.");
340 pippijn 1.22
341     1
342 pippijn 1.20 };
343    
344 root 1.1 cf::register_command rename => sub {
345     my ($ob, $arg) = @_;
346    
347     $ob->speed_left ($ob->speed_left - 0.25);
348    
349     if ($arg =~ /^\s* (?: <([^>]+)> \s+)? to \s+ <([^>]*)> \s*$/x) {
350     # compatibility syntax
351     rename_to $ob, $1, $2;
352     } elsif ($arg =~ /
353     ^\s*
354     (?:
355     (?: "((?:[^"]+|\\.)*)" | (\S+) )
356     \s+)?
357     to \s+
358     (?: "((?:[^"]+|\\.)*)" | (\S+) )
359     \s*$
360     /x) {
361     # does not unquote $1 or $3
362     rename_to $ob, $2||$1, $4||$3;
363     } else {
364     $ob->reply (undef, 'Syntax error. Rename usage: rename ["oldname"] to "newname"');
365     }
366    
367     1
368     };
369    
370     cf::register_command uptime => sub {
371     my ($ob, $arg) = @_;
372    
373     my $startup = POSIX::strftime "%Y-%m-%d %H:%M:%S %Z", localtime $cf::UPTIME;
374     my $runtime = sprintf "%.1f", (time - $cf::UPTIME) / 86400;
375     $ob->reply (undef, "server started $startup, uptime ${runtime}\d");
376    
377     1
378     };
379    
380 root 1.8 my %IN_MEMORY = (
381     cf::MAP_IN_MEMORY => "I",
382     cf::MAP_SWAPPED => "S",
383     cf::MAP_LOADING => "L",
384     );
385    
386 root 1.7 cf::register_command maps => sub {
387     my ($ob, $arg) = @_;
388    
389     no re 'eval'; $arg = qr<$arg>;
390    
391 root 1.13 my $format = "%2s %1s %3s %5s %.60s\n";
392 root 1.7
393 root 1.15 $ob->reply (undef, (sprintf $format, "Pl", "I", "Svd", "Reset", "Name"), cf::NDI_BLACK | cf::NDI_UNIQUE);
394 root 1.7
395     for (sort keys %cf::MAP) {
396     my $map = $cf::MAP{$_}
397     or next;
398    
399     next unless $map->path =~ $arg;
400 root 1.17 next if $map->{deny_list};
401 root 1.7
402 root 1.10 my $svd = int $cf::RUNTIME - $map->{last_save};
403     $svd = "++" if $svd > 99;
404    
405 root 1.14 $ob->reply (undef,
406     (sprintf $format,
407     (scalar $map->players),
408     $IN_MEMORY{$map->in_memory} || "?",
409     $svd,
410     (int $map->reset_at - $cf::RUNTIME),
411 root 1.17 $map->visible_name),
412 root 1.14 cf::NDI_BLACK | cf::NDI_UNIQUE);
413 root 1.7 }
414    
415     1
416     };
417