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