blob: caf82eb2371038b4c61746652ac5113771ac58c6 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// ----------------------------------------------------------------------
2// Builtinkommandos der Teller.
3// ----------------------------------------------------------------------
4#include "teller.h"
5inherit T_BASE;
6
Zesstra703da222017-01-31 10:47:36 +01007#include <config.h>
MG Mud User88f12472016-06-24 23:31:02 +02008#include <moving.h>
9#include <attributes.h>
10#include <terminal.h>
11#include <wizlevels.h>
12
13static void do_rinv( object env, int depth );
14static scan_obj( object player, object obj );
15static void mk_waitfor( mixed waitfor );
16static void mk_autoload( mixed autoload );
17static int do_roomupdate( int destflag, int noitems );
18static int do_cleanof( int strong );
19
20// from teller.c
21static int do_cmd( string str );
22
23static int cmd_clear()
24{
25 stack = ({});
26 return TRUE;
27}
28
29static int cmd_pop()
30{
31 if( !sizeof(stack) )
32 return error( "pop: Der Stack ist leer" );
33 pop();
34 return TRUE;
35}
36
37static int cmd_top()
38{
39 if( !sizeof(stack) )
40 return error( "top: Der Stack ist leer" );
41 write( "TOS= " );
42 dump_obj( top(), 5 );
43 return TRUE;
44}
45
46static int cmd_swap()
47{
48 mixed tmp;
49
50 if( sizeof(stack)<2 )
51 return error( "swap: Keine 2 Elemente auf dem Stack" );
52 tmp = stack[0];
53 stack[0] = stack[1];
54 stack[1] = tmp;
55 return TRUE;
56}
57
58static int cmd_dup()
59{
60 if( !sizeof(stack) )
61 return error( "dup: Der Stack ist leer" );
62 push(top());
63 return TRUE;
64}
65
66static int cmd_here()
67{
68 push(environment(PL));
69 return TRUE;
70}
71
72static int cmd_stack()
73{
74 int i;
75 if( !sizeof(stack) )
76 return memo( "Der Stack ist leer" );
77
78 for( i=0; i<sizeof(stack); i++ )
79 {
80 printf( "%2d: ", i );
81 dump_obj( stack[i], 4 );
82 }
83 return TRUE;
84}
85
86static int cmd_inv()
87{
88 int i;
89 object ob;
90
91 if( !becomes_obj() )
92 return error( "inv: TOS ist kein Objekt" );
93 write( "Inventar von " );
94 dump_obj( top(), 13 );
95 for( i=0, ob=first_inventory(top()); ob; ob=next_inventory(ob), i++ )
96 {
97 printf( "%2d. ", i );
98 dump_obj( ob, 4 );
99 }
100 return TRUE;
101}
102
103static int cmd_rekinv()
104{
105 if( !becomes_obj() )
106 return error( "rekinv: TOS ist kein Objekt" );
107 write( "Inventar von " );
108 dump_obj( top(), 13 );
109
110 do_rinv( top(), 2 );
111 return TRUE;
112}
113
114static void do_rinv( object env, int depth )
115{
116 int i;
117 object ob;
118
119 for( i=0, ob=first_inventory(env); ob; ob=next_inventory(ob), i++ )
120 {
121 printf( "%*d. ", depth, i );
122 dump_obj( ob, 2+depth );
123 do_rinv( ob, depth+2 );
124 }
125}
126
127static int cmd_me()
128{
129 push( PL );
130 return TRUE;
131}
132
133// Uebernommen aus dem Teddy (mit freundlicher Genehmigung von Sir).
134static int cmd_scan()
135{
136 object obj;
137
138 if( !becomes_pl() && ( !objectp(top()) || !living(top()) ) )
139 {
Zesstra85576452017-01-30 15:43:21 +0100140 if( stringp(top()) && master()->find_userinfo(top()))
MG Mud User88f12472016-06-24 23:31:02 +0200141 {
142 obj = clone_object( T_PLAYER );
143 obj->Load( top() );
144 obj->SetProp( P_NAME, capitalize( pop() ) );
145 scan_obj( TRUE, obj );
146 destruct( obj );
147 return TRUE;
148 }
149 return error( "scan: TOS ist kein Lebewesen" );
150 }
151
152 scan_obj( query_once_interactive( top() ), pop() );
153 return TRUE;
154}
155
156static int WizLevel( object obj )
157{
158 if( obj->Notlogged() )
159 return query_wiz_level( lower_case(obj->playername()) );
160 else
161 return query_wiz_level( obj );
162}
163
164static string IpName( object obj )
165{
166 string ip_name, ip_num, nm;
167
168 if( obj->Notlogged() )
169 {
170 // Aus Umstellungsgruenden werden CALLED_FROM_IP und IP_NAME
171 // abgefragt. IP_NAME ist neuer.
172
173 nm = lower_case(obj->playername());
174 ip_name = obj->QueryProp(P_CALLED_FROM_IP);
175 if( !ip_name ) ip_name = obj->Query(P_IP_NAME);
176 return ip_name + " ("
Zesstra703da222017-01-31 10:47:36 +0100177 + dtime(get_dir(SAVEPATH+nm[0..0]+"/"+nm+".o",4)[0]) +")";
MG Mud User88f12472016-06-24 23:31:02 +0200178 }
179 else
180 {
181 nm = lower_case( obj->name(RAW) );
182 ip_name = query_ip_name( obj );
183 if( ip_name == "" || !ip_name )
184 {
185 ip_name = obj->QueryProp(P_CALLED_FROM_IP);
186 if( !ip_name ) ip_name = obj->Query(P_IP_NAME);
187 return ip_name + " ("
Zesstra703da222017-01-31 10:47:36 +0100188 + dtime(get_dir(SAVEPATH+nm[0..0]+"/"+nm+".o",4)[0]) +")";
MG Mud User88f12472016-06-24 23:31:02 +0200189 }
190 return ip_name + " [" + query_ip_number(obj) + "]";
191 }
192}
193
194string IdleTime( object obj )
195{
196 if( obj->Notlogged() ) return "-nicht da-";
197 if( query_ip_number(obj) ) return ""+query_idle(obj);
198 return "-netztot-";
199}
200
201static scan_obj( object player, object obj )
202{
203 string title, level, gender, room, testpl,
204 weapon, armour, quest, stat_str, *arr;
205 int i,ac;
Zesstra38121982021-05-07 09:36:14 +0200206 object weaponobj, *list;
207 object** enemies;
208 object* gegner;
MG Mud User88f12472016-06-24 23:31:02 +0200209 mixed *hands, *quests, *stats;
210
211 // 1.Zeile : Name Titel - Rasse - [ Wizlevel ]
212 title = obj->QueryProp(P_TITLE);
213
214 if( !player )
215 level = "Monster" ;
216 else if( WizLevel( obj ) < WIZARD_LVL )
217 {
218 if( testpl=obj->QueryProp( P_TESTPLAYER ) )
219 {
220 if( stringp(testpl) )
221 level = "("+testpl+")";
222 else
223 level = "Testspieler";
224 }
225 else if( WizLevel( obj ) >= SEER_LVL )
226 level = "Seher";
227 else
228 level = "Spieler" ;
229 }
230 else if( WizLevel( obj ) >= GOD_LVL )
231 level = "MudGott" ;
232 else if( WizLevel( obj ) >= ARCH_LVL )
233 level = "Erzmagier" ;
234 else if( WizLevel( obj ) >= LORD_LVL )
235 level = "Regionsmagier" ;
236 else
237 level = "Magier" ;
238
239 if( !obj->short() )
240 level += ", unsichtbar" ;
241 if( obj -> QueryProp( P_FROG ) )
242 level += ", Frosch" ;
243 if( obj->QueryProp( P_GHOST ) )
244 level += ", tot";
245 if( obj->Notlogged() )
246 level += ", ausgeloggt";
247 if(obj->QueryProp(P_SECOND) )
248 level +=", Zweitie";
249
250 if( environment(obj) )
251 room = object_name(environment( obj ));
252 else
253 room = "-nirgends-";
254
255 printf( "%s %s %s[ %s ].\nBefindet sich in %s.\n",
256 obj->name(RAW), title? title : "",
257 stringp(obj->QueryProp(P_RACE)) ? "- "+obj->QueryProp(P_RACE)+" - " : "",
258 level, room ) ;
259
260 // 1 abc Zeile : Host,Email,Snooper
261 if( player )
262 {
263 printf( "Host.......: %s\n", IpName(obj) );
264 printf( "E-Mail.....: %s.\n", obj->QueryProp(P_MAILADDR) );
265 if( !obj->Notlogged() && query_snoop(obj) )
266 printf( "Snooper....: %s.\n", capitalize(getuid(query_snoop(obj))) );
267
268 printf( "Vorsicht...: %11d Kurzmodus.: %11s Magierblick....: %11s.\n",
269 obj->QueryProp(P_WIMPY), obj->QueryProp(P_BRIEF) ? "-an-" : "-aus-",
270 obj->QueryProp(P_WANTS_TO_LEARN) ? "-an-" : "-aus-" );
271 printf( "Idlezeit...: %11s Alter.....: %11s Verheiratet mit: %-11s.\n",
272 IdleTime(obj), time2string("%5d:%02h:%02m",obj->QueryProp(P_AGE)*2),
273 (stringp(obj->QueryProp(P_MARRIED)) ? obj->QueryProp(P_MARRIED) : "-" )
274 );
275 }
276
277 // 2.Zeile : HP, SP und XP
278 printf( "Lebenspkt..: [%4d/%4d] Magiepkt..: [%4d/%4d].\n" +
279 "Questpunkte: [%4d/%4d] Erfahrung.: %11d.\n",
280 obj->QueryProp(P_HP), obj->QueryProp(P_MAX_HP),
281 obj->QueryProp(P_SP), obj->QueryProp(P_MAX_SP),
282 obj->QueryProp(P_QP), "/secure/questmaster"->QueryMaxQP(),
283 obj->QueryProp(P_XP) );
284
285 // 3.Zeile : FOOD, DRINK, ALCOHOL
286 printf( "Nahrung....: [%4d/%4d] Fluessigk.: [%4d/%4d] " +
287 "Alkohol........: [%4d/%4d].\n",
288 obj->QueryProp(P_FOOD), obj->QueryProp(P_MAX_FOOD),
289 obj->QueryProp(P_DRINK), obj->QueryProp(P_MAX_DRINK),
290 obj->QueryProp(P_ALCOHOL), obj->QueryProp(P_MAX_ALCOHOL) ) ;
291
292 // 4.Zeile : Geschlecht, Alignment, Level
293 switch( obj->QueryProp(P_GENDER) )
294 {
295 case FEMALE : gender = "weiblich " ; break ;
296 case MALE : gender = "maennlich " ; break ;
297 default : gender = "neutrum " ; break ;
298 }
299 printf(
300 "Geschlecht.: %s Charakter.: %11d (Magier)Stufe..: [%4s/%4d].\n",
301 gender, obj->QueryProp(P_ALIGN),
302 player ? WizLevel(obj)+"" : "-", obj->QueryProp(P_LEVEL) );
303
304 // 5.Zeile : Geld, Gewicht, Playerkills
305 printf( "Geld.......: %11d Traegt....: %11d Playerkills....: %11d.\n",
306 obj->QueryMoney(), obj->query_weight_contents(),
307 obj->QueryProp(P_KILLS) );
308
309 // 6.Zeile : stati
310 stats = obj->QueryProp(P_ATTRIBUTES) ;
311 arr = m_indices( stats );
312 stat_str = "" ;
313 for( i = 0; i < sizeof( arr ); i++ ) {
314 stat_str += capitalize(arr[ i ]) + "[" + stats[arr[ i ]];
315 if( ac = obj->QueryAttributeOffset(arr[i]) ) {
316 stat_str += "+" + ac;
317 }
318 stat_str += "], ";
319 }
320
321 if( stat_str == "" )
322 stat_str = "Keine" ;
323 else
324 stat_str = stat_str[0..sizeof( stat_str ) - 3] ;
325 printf( "Attribute..: %s.\n", stat_str ) ;
326
327 // 7.Zeile : Waffe( Dateiname )[ AC ]
328 // 8.Zeile : Ruestung(en)[ WC ]
329 weaponobj=obj->QueryProp(P_WEAPON);
330 if( weaponobj )
331 weapon = weaponobj->name(RAW) + " (" +
332 object_name( weaponobj ) + ") [" +
333 weaponobj->QueryProp(P_WC) + "]" ;
334 else
335 {
336 hands = obj->QueryProp(P_HANDS);
337 weapon = sprintf( "kaempft%s [%d]", hands[0], hands[1] );
338 }
339 ac = 0;
340 list = obj->QueryProp(P_ARMOURS);
341 armour = "";
342 for( i = 0; i < sizeof( list ); i++ )
343 {
344 armour += ( list[i]->name(RAW) + "[" +
345 list[i]->QueryProp(P_AC) + "]" + ", ") ;
346 ac += list[i]->QueryProp(P_AC);
347 }
348
349 if( armour == "" )
350 armour = "Keine " ;
351
352 arr = old_explode( break_string( armour[0..<3]+sprintf(" =>[%d]",
353 ac+obj->QueryProp(P_BODY) ), 65 ), "\n" ) ;
354 armour = arr[ 0 ] ;
355 for( i = 1; i < sizeof( arr ); i++ )
356 armour += "\n " + arr[ i ] ;
357 printf( "Waffe......: %s.\nRuestung...: %s.\n", weapon, armour ) ;
358
Zesstra38121982021-05-07 09:36:14 +0200359 enemies = obj->QueryEnemies();
360 if( pointerp(enemies) )
MG Mud User88f12472016-06-24 23:31:02 +0200361 {
Zesstra38121982021-05-07 09:36:14 +0200362 gegner = enemies[0];
MG Mud User88f12472016-06-24 23:31:02 +0200363 for( i=0; i<sizeof(gegner); i++ )
364 {
365 if( i==0 ) printf( "Gegner.....: "); else printf( " " );
366 if( !objectp(gegner[i]) )
367 printf( "<%O>\n", gegner[i] );
368 else
369 printf( "%s (%s)\n", gegner[i]->name(WER,0), object_name(gegner[i]) );
370 }
371 }
372
373 mk_waitfor( obj->QueryProp(P_WAITFOR) );
374
375 mk_autoload( obj->QueryProp(P_AUTOLOAD) );
376
377 return TRUE;
378}
379
380static void mk_waitfor( mixed waitfor )
381{
382 string str;
383 int i;
384
385 if( !pointerp(waitfor) || sizeof(waitfor)==0 )
386 return;
387 str = "Waiting for: ";
388 for( i=sizeof(waitfor)-1; i>0; i-- )
389 str += waitfor[i] + ", ";
390 str += waitfor[0];
391 write( str+"\n" );
392}
393
394static void mk_autoload( mixed autoload )
395{
396 string str, *objlist;
397 int i;
398
399 if( !mappingp(autoload) )
400 return;
401 str = "Autoload...: ";
402 objlist = m_indices(autoload);
403 for( i=sizeof(objlist)-1; i>=0; i-- )
404 {
405 str += "\"" + objlist[i] + "\"\n";
406 if( i>0 )
407 str += " ";
408 }
409 write( str );
410}
411
412static void print_memory_line( string key, object data, int flag )
413{
414 printf( " %-10s%s ", key, (flag ? ">" : "=") );
415 dump_obj( data, 13 );
416}
417
418static int cmd_memory()
419{
420 int i;
421 if( !sizeof(memory) )
422 return memo( "Keine Variablen definiert" );
423
424 walk_mapping( memory, #'print_memory_line );
425 return TRUE;
426}
427
428static int cmd_array()
429{
430 mixed *array;
431 mixed ob;
432
433 if( !sizeof(stack) )
434 return error( "array: Der Stack ist leer" );
435 array = ({});
436 while( sizeof(stack) && (ob=pop()) && ob!=";" )
437 array = ({ob}) + array;
438 push( array );
439 return TRUE;
440}
441
442static int cmd_split()
443{
444 mixed *array;
445 int i;
446
447 if( !pointerp(top()) )
448 return error( "split: TOS ist kein Array" );
449 array=pop();
450 if( sizeof(stack) )
451 push( ";" );
452 for( i=0; i<sizeof(array); i++ )
453 push(array[i]);
454 return TRUE;
455}
456
457static int cmd_player()
458{
459 object ob;
460 string str;
461
462 str = top();
463 if( !stringp(str) )
464 return error( "player: TOS ist kein String" );
465 ob = becomes_pl();
466 if( !ob )
467 return error( "player: Keinen Spieler namens \""+str+"\" gefunden" );
468 //pop();
469 //push(ob);
470 return TRUE;
471}
472
473static int cmd_object()
474{
475 object ob;
476 string err,fnam;
477
478 if( !stringp(top()) )
479 return error( "object: TOS ist kein String" );
480 ob = find_object(top());
481 if( !ob )
482 {
483 if( !(fnam=this_player()->find_file(top(),".c")) )
484 return error( "object: Kein Objekt namens \""+top()+"\" gefunden" );
485 if( err=(catch(call_other(fnam,"?"))) )
486 return error( "object: Fehler beim Laden: "+err[1..<3] );
487 ob = find_object(fnam);
488 }
489 pop();
490 push(ob);
491 return TRUE;
492}
493
494static int cmd_living()
495{
496 object ob;
497 if( !stringp(top()) )
498 return error( "object: TOS ist kein String" );
499 ob = find_living(top());
500 if( !ob )
501 return error( "object: Kein Objekt namens \""+top()+"\" gefunden" );
502 pop();
503 push(ob);
504 return TRUE;
505}
506
507static int cmd_say()
508{
509 mit_say = !mit_say;
510 if( mit_say )
511 memo( "Meldungen an Mitspieler an" );
512 else
513 memo( "Meldungen an Mitspieler aus" );
514 return TRUE;
515}
516
517static int cmd_names()
518{
519 mit_namen = !mit_namen;
520 if( mit_namen )
521 memo( "Namen werden angezeigt" );
522 else
523 memo( "Namen werden nicht angezeigt" );
524 return TRUE;
525}
526
527static int cmd_secureinv()
528{
529 secureinv = !secureinv;
530 if( secureinv )
531 memo( "Inventory wird ueberwacht" );
532 else
533 memo( "Inventory wird nicht ueberwacht" );
534 set_heart_beat(secureinv);
535 return TRUE;
536}
537
538static int cmd_logaccess()
539{
540 dologaccess = !dologaccess;
541 if( dologaccess )
542 memo( "Zugriffe werden gemeldet" );
543 else
544 memo( "Zugriffe werden nicht gemeldet" );
545 return TRUE;
546}
547
548static int cmd_destruct_bang()
549{
550 if( !becomes_obj() )
551 return error( "destruct: TOS ist kein Objekt" );
552 destruct(pop());
553 return TRUE;
554}
555
556static int cmd_destruct()
557{
558 if( !becomes_obj() )
559 return error( "remove: TOS ist kein Objekt" );
560 memo( "destruct: TOS wird 'removed'!" );
561 top()->remove();
562 if( top() )
563 memo( "destruct: TOS lebt noch." );
564 else
565 pop();
566 return TRUE;
567}
568
569static int cmd_remove()
570{
571 if( !becomes_obj() )
572 return error( "remove: TOS ist kein Objekt" );
573 top()->remove();
574 if( top() )
575 memo( "destruct: TOS lebt noch." );
576 else
577 pop();
578 return TRUE;
579}
580
581static int cmd_update()
582{
583 object blue;
584
585 if( !becomes_obj() )
586 return error( "update: TOS ist kein Objekt" );
587 blue = find_object(old_explode(object_name(top()),"#")[0]);
588 blue->remove();
589 if( blue )
590 memo( "update: TOS lebt noch" );
591 else
592 pop();
593 return TRUE;
594}
595
596static int cmd_update_bang()
597{
598 if( !becomes_obj() )
599 return error( "update: TOS ist kein Objekt" );
600 destruct(find_object(old_explode(object_name(pop()),"#")[0]));
601 return TRUE;
602}
603
604static int cmd_roomupdate()
605{
606 return do_roomupdate( FALSE, FALSE );
607}
608
609static int cmd_roomupdate_bang()
610{
611 return do_roomupdate( TRUE, FALSE );
612}
613
614static int cmd_extroomupdate()
615{
616 return do_roomupdate( FALSE, TRUE );
617}
618
619static int cmd_extroomupdate_bang()
620{
621 return do_roomupdate( TRUE, TRUE );
622}
623
624// Hilfsfunktionen zum Filtern von Items
625static object *collect_items;
626static void collect( object* data ) { collect_items += ({ data[0] }); }
627
628static int do_roomupdate( int destflag, int noitems )
629{
630 object tmproom,newroom;
631 object *inv;
632 string errmsg;
633 string *file;
634 object *items;
635 int i;
636
637 if( !becomes_obj() )
638 return error( "roomupdate: TOS ist kein Objekt" );
639 file = old_explode( object_name( top() ), "#" );
640 if( sizeof(file) > 1 )
641 return error( "roomupdate: TOS ist keine Blueprint" );
642 if( file[0] == "/room/void" )
643 return error( "roomupdate: Die `void' darf nicht geupdatet werden" );
644
645 // ----- Rettung
646 tell_room( top(),
647 "Der Raum verschwimmt vor Deinen Augen, um sich zu erneuern.\n"
648 );
649 tmproom = clone_object( "/room/void" );
650
651 if( noitems )
652 // Nur Spieler kommen raus.
653 inv = filter( all_inventory(top()), #'query_once_interactive );
654 else
655 { // Dinge, die P_ITEMS sind, bleiben da!
656 collect_items = ({});
657 map( top()->QueryProp(P_ITEMS), #'collect );
658 inv = all_inventory(top()) - collect_items;
659 }
660
661 for( i=sizeof(inv)-1; i>=0; i-- )
662 inv[i]->move( tmproom, M_NOCHECK | M_SILENT | M_NO_SHOW );
663
664 // ----- Vernichtung
665 if( destflag )
666 destruct( pop() );
667 else
668 {
669 top()->remove();
670 if( top() )
671 memo( "roomupdate : TOS ist nicht verschwunden." );
672 else
673 pop();
674 }
675
676 // ----- Neuerschaffung
677 errmsg = catch( call_other( file[0], "?" ) );
678 if( errmsg )
679 {
680 tell_room( tmproom, "Der Raum verbleicht in ein Nichts.\n" );
681 push( file[0] );
682 return error( "updateroom: " + errmsg[1..<2] );
683 }
684
685 // ----- Restaurierung
686 newroom = find_object( file[0] );
687 for( i=sizeof(inv)-1; i>=0; i-- )
688 if( objectp(inv[i]) ) // Objekte koennten sich beim ersten move zerstoeren.
689 inv[i]->move( newroom, M_NOCHECK | M_SILENT | M_NO_SHOW );
690 tell_room( newroom, "Die Konturen werden wieder scharf.\n" );
691 destruct( tmproom );
692 return TRUE;
693}
694
695static int cmd_clone()
696{
697 if( !stringp(top()) )
698 return error( "clone: TOS ist kein String" );
699 if( file_size(top()+".c")<=0 )
700 return error( "clone: Kein solches File" );
701 push(clone_object(pop()));
702 //do_move( top(), environment(PL) );
703 //top()->move(PL,M_GET|M_SILENT);
704 return TRUE;
705}
706
707static int cmd_move()
708{
709 object ob;
710
711 if( !becomes_obj() )
712 return error( "move: Ziel ist kein Objekt" );
713 ob = pop();
714 if( !becomes_obj() )
715 return error( "move: Kein solcher Gegenstand" );
716 do_move( pop(), ob );
717 return TRUE;
718}
719
720static int cmd_cleanof_bang()
721{
722 return do_cleanof( TRUE );
723}
724
725static int cmd_cleanof()
726{
727 return do_cleanof( FALSE );
728}
729
730static int do_cleanof( int strong )
731{
732 object *inv;
733 int i;
734 string clean_id;
735
736 if( !stringp(top()) )
737 return error( "cleanof: TOS ist kein String" );
738 clean_id = pop();
739 if( !becomes_obj() )
740 {
741 push( clean_id );
742 return error( "cleanof: Kein Objekt zum Leeren" );
743 }
744 for( i=0, inv=all_inventory(pop()); i<sizeof(inv); i++ )
745 if( inv[i]->id(clean_id) )
746 {
747 if( strong )
748 destruct( inv[i] );
749 else
750 inv[i]->remove();
751 }
752 return TRUE;
753}
754
755static int cmd_snoopers()
756{
757 object* u, snooper;
758 int i, flag;
759
760 flag = 0;
761 u = users();
762 for( i=0; i<sizeof(u); i++ )
763 {
764 if( snooper = query_snoop(u[i]) )
765 {
766 flag = 1;
767 printf( "%s wird gesnooped von: %s.\n",
768 capitalize(getuid(u[i])), capitalize(getuid(snooper)) );
769 }
770 }
771 if( !flag )
772 memo( "Momentan wird niemand gesnooped" );
773 return TRUE;
774}
775
776static int cmd_ping()
777{
778 object pl;
779
780 if( !becomes_pl() )
781 return error( "ping: TOS ist kein Spieler" );
782
783 pl=pop();
784 call_out( "ping", 0, ({ pl, 5 }) );
785 return TRUE;
786}
787
788static void ping( mixed* argv )
789{
790 if( !argv[0] || --argv[1] < 0 ) return;
791 tell_object( argv[0], BEEP+PL->name(WER)+" pingt Dich an.\n" );
792 call_out( "ping", 1, argv );
793}
794
795static void do_calloutinfo( mixed* call )
796{
797 int l,i;
798
799 if( pointerp(call) )
800 {
801 printf( "%5d:%O->%O(", call[2], call[0], call[1]);
802 if( (l=sizeof(call))>3 ) {
803 for( ; l>=3 && !call[--l]; ) ;
804 for( i=3; i<=l; i++ ) printf( "%O%s", call[i], (i==l)?"":"," );
805 }
806 write(")\n");
807 }
808}
809
810static int cmd_callouts_bang()
811{
812 mixed *calls;
813 object obj;
814 string name;
815 int i,j;
816
817 calls = call_out_info();
818 if( !pointerp(calls) || !sizeof(calls) )
819 {
820 memo( "Keine Callouts vorhanden" );
821 return TRUE;
822 }
823 map( calls, #'do_calloutinfo );
824 return TRUE;
825}
826
827static void do_calloutinfo2( mixed* call, string str )
828{
829 string s;
830 int i,l;
831
832 if( pointerp(call) )
833 {
834 s = sprintf( "%5d:%O->%O(", call[2], call[0], call[1]);
835 if( sizeof(explode(s,str)) > 1 )
836 {
837 write( s );
838 if( (l=sizeof(call))>3 ) {
839 for( ; l>=3 && !call[--l]; ) ;
840 for( i=3; i<=l; i++ ) printf( "%O%s", call[i], (i==l)?"":"," );
841 }
842 write(")\n");
843 }
844 }
845}
846
847static int cmd_callouts()
848{
849 mixed *calls;
850 object obj;
851 string str;
852 int i,j;
853
854 if( !stringp(top()) )
855 return error( "TOS ist kein String" );
856 str = pop();
857 calls = call_out_info();
858 if( !pointerp(calls) || !sizeof(calls) )
859 {
860 memo( "Keine Callouts vorhanden" );
861 return TRUE;
862 }
863 map( calls, #'do_calloutinfo2, str );
864 return TRUE;
865}
866
867static int cmd_heartbeats()
868{
869 mixed *beats;
870 int i;
871 object env;
872 string enam;
873
874 beats = heart_beat_info();
875 if( !pointerp(beats) || !sizeof(beats) )
876 {
877 memo( "Keine Heartbeats vorhanden" );
878 return TRUE;
879 }
880 for( i=0; i<sizeof(beats); i++ )
881 {
882 env = environment(beats[i]);
883 enam = env ? object_name(env) : "-- nirgends --";
884 printf( "%-35s %-35s\n", object_name(beats[i]), enam );
885 }
886 return TRUE;
887}
888
889static int cmd_wer()
890{
891 object* ppl;
892 string* pl;
893 int i;
894
895 ppl = sort_array( users(), lambda( ({ 'x, 'y }),
896 ({ #'<, ({ #'query_ip_number, 'x }), ({ #'query_ip_number, 'y }) })
897 ));
898 pl = ({});
899 for( i=0; i<sizeof(ppl); i++ )
900 {
901 pl += ({ sprintf( "%'.'-14s %-15s %3d %s \n",
902 capitalize(geteuid(ppl[i])),
903 query_ip_number(ppl[i]),
904 query_wiz_level(ppl[i])>0 ? query_wiz_level(ppl[i])
905 : ppl[i]->QueryProp(P_LEVEL),
906 query_wiz_level(ppl[i])>0 ? "W" : "P"
907 ) });
908 }
909 write( implode(pl,"") );
910 return TRUE;
911}
912
913static int cmd_debuginfo()
914{
915 if( !becomes_obj() )
916 return error( "dinfo: TOS ist kein Objekt" );
917 debug_info( 0, pop() );
918 return TRUE;
919}
920
921static int cmd_pretty()
922{
923 pretty = !pretty;
924 if( pretty )
925 memo( "Schoenmodus an" );
926 else
927 memo( "Schoenmodus aus" );
928 return TRUE;
929}
930
931static int cmd_doprofile()
932{
933 do_profile=!do_profile;
934 if( do_profile )
935 memo( "Profile wird geladen" );
936 else
937 memo( "Profile wird nicht geladen" );
938 return TRUE;
939}
940
941static int cmd_evaluate()
942{
943 string str;
944 if( !sizeof(stack) ) return error( "evaluate: Stack ist leer" );
945 if( !stringp(top()) ) return error( "evaluate: TOS ist kein String" );
946 str = pop();
947 return do_cmd( str );
948}
949
950static void write_memory( string nam, string str, int flag, string file )
951{
952 if( flag ) write_file( file, nam + " = " + str + "\n" );
953}
954
955static int cmd_dump()
956{
957 string file;
958
959 if( !sizeof(stack) || !stringp(top()) )
960 file = "/players/"+getuid(PL)+"/.memory.o";
961 else
962 file = pop();
963 rm( file );
964 write_file( file, "# Dump des Tellerstapels vom " + dtime(time()) + "\n" );
965 write_file( file, "# Owner = "+capitalize(getuid(PL))+"\n" );
966 walk_mapping( memory, #'write_memory, file );
967 return TRUE;
968}
969
970static int restore_line( string line )
971{
972 string nam,str;
973 if( sscanf( line, "%s = %s", nam, str ) != 2 )
974 return error( "restore: Fehler im file" );
975 memory += ([ nam: str; 1 ]);
976 return 1;
977}
978
979static int cmd_restore()
980{
981 string str, *lines;
982
983 if( !sizeof(stack) || !stringp(top()) )
984 str = "/players/"+getuid(PL)+"/.memory.o";
985 else
986 str = pop();
987
988 if(file_size(str)<=0)
989 return error( "restore: kann '"+str+"' nicht laden" );
990 lines = regexp( old_explode( read_file(str), "\n" ), "^[^#]" );
991 map( lines, #'restore_line );
992 return TRUE;
993}
994
995static int cmd_if()
996{
997 if( sizeof(stack) < 3 )
998 return error( "if: zuwenig Argumente" );
999 if( !pop() )
1000 cmd_swap();
1001 pop();
1002 return TRUE;
1003}