blob: 389a2a0dad9734142c5a934f709d9941c5d60128 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// $Id: magier_ext.c 9555 2016-05-03 20:42:46Z Zesstra $
2#pragma strict_types
3#pragma save_types
4//#pragma range_check
5#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +02006
Zesstra876b0d62018-11-08 20:52:22 +01007protected functions virtual inherit "/std/util/path";
Zesstra5ad01e12025-06-20 11:06:56 +02008inherit "/std/shells/magier/parsing";
9inherit "/std/shells/magier/upd";
10inherit "/std/shells/magier/fileview";
11inherit "/std/shells/magier/objects";
12inherit "/std/shells/magier/fileedit";
13//inherit "/std/shells/magier/todo";
14inherit "/std/shells/magier/players";
15inherit "/std/shells/magier/admin";
16inherit "/std/shells/magier/moving";
17inherit "/std/shells/magier/comm";
Zesstra876b0d62018-11-08 20:52:22 +010018
MG Mud User88f12472016-06-24 23:31:02 +020019#include <wizlevels.h>
20#include <logging.h>
21#include <magier.h>
22#include <snooping.h>
23#include <driver_info.h>
24#define NEED_PROTOTYPES
25#include <player/telnetneg.h>
26#include <player/base.h>
bugfix1b04afb2020-04-15 14:52:24 +020027#include <player/comm.h>
MG Mud User88f12472016-06-24 23:31:02 +020028#undef NEED_PROTOTYPES
29#include <properties.h>
30#include <files.h>
31#include <events.h>
MG Mud User88f12472016-06-24 23:31:02 +020032
MG Mud User88f12472016-06-24 23:31:02 +020033// #######
34//############################### SET #################################
35// #######
36
37
38//
39// _set(): Shell-Befehl 'set'
40// args: Kommandozeilenargumente
41//
42
43static int _set(mixed args)
44{
45 int pos;
46 string var;
47 mixed val;
48 mapping vars;
49
50 if(!args=_unparsed_args())
51 {
52 if(!sizeof(vars=QueryProp(P_VARIABLES)))
53 printf("Du hast noch keine Variablen definiert!\n");
54 else
55 {
56 printf("Du hast die folgenden Variablen definiert:\n");
57 walk_mapping(vars,((: printf(" %-20s = %s\n",$1,
58 pointerp($2)?implode($2,":"):$2) :)));
59
60 }
61 return 1;
62 }
63 pos = member(args,' ');
64 if(pos == -1)
65 if(sizeof(args))
66 {
67 m_delete(QueryProp(P_VARIABLES), args);
68 printf("Variable %s wurde geloescht.\n",args);
69 return 1;
70 }
71 else return USAGE("set <variable> <wert>");
72 var = args[0..pos-1];
73 val = (member(args[pos+1..],':')>-1?
74 explode(args[pos+1..], ":") :
75 args[pos+1..]);
76 vars=QueryProp(P_VARIABLES);
77 vars+= ([var : val]);
78 printf("Variable gesetzt: %s = %s\n",var,args[pos+1..]);
79 return 1;
80}
81
82// ############
83//############################# CD + PWD ###################################
84// ############
85
86static int _pwd()
87{
88 printf("Aktuelles Verzeichnis: %s\n",QueryProp(P_CURRENTDIR));
89 return 1;
90}
91
92static int _cd2(string cmdline)
93{
94 string dest,tmp;
95 int flags;
96 mixed *args;
97
98 args=parseargs(cmdline,&flags,CD_OPTS,1);
99 if (flags==-1) return 0;
100 if(flags&CD_B)
101 {
102 dest=QueryProp(P_LASTDIR);
103 }
104 if (sizeof(args)>1)
105 return notify_fail("Man kann sich (leider) nur in einem "
106 "Verzeichnis gleichzeitig befinden.\n"),0;
107 if(!dest)
108 {
109 if (!sizeof(args))
110 {
111 if (IS_WIZARD(this_object()))
112 dest="/players/"+getuid(this_object());
113 else
114 dest="/doc";
115 }
116 else
117 {
118 dest=args[0];
119 }
120 }
121
122 if (dest!="/")
123 {
124 args=file_list(({dest}),MODE_CD,0,"/");
125 args = filter(args, function int (mixed arr)
126 { return arr[FILESIZE] == FSIZE_DIR; } );
127
128 if (!sizeof(args))
129 return notify_fail("cd: "+dest+
130 ": Kein solches Verzeichnis gefunden.\n"),0;
131 if (sizeof(args)>1)
132 return notify_fail("cd: "+dest+": Maske ist nicht eindeutig.\n"),0;
133 dest=args[0][FULLNAME];
134 }
135 if (!IS_WIZARD(this_object())&&dest[0..3]!="/doc") dest="/doc";
136 SetProp(P_LASTDIR,QueryProp(P_CURRENTDIR));
137 printf("Aktuelles Verzeichnis ist jetzt: %s\n",SetProp(P_CURRENTDIR,dest));
138 tmp="";
139 if (((flags&CD_L)||
140 ((!m_contains(&tmp,QueryProp(P_VARIABLES),"CD_SHORT")||
141 tmp!="1")&&(!(flags&CD_S)))))
142 tell_object(this_object(),
143 read_file(dest+(dest[<1]=='/'?".readme":"/.readme"))||"");
144 return 1;
145}
146
147static int _cd(string cmdline)
148{
149 return _cd2(_unparsed_args());
150}
151
152static string _set_currentdir(string path)
153{
154 Set(P_CURRENTDIR, path);
Zesstra95ca5c32025-06-20 11:04:48 +0200155 if (interactive())
156 modify_prompt(); // Prompt mit neuem Pfad setzen, telnetneg
MG Mud User88f12472016-06-24 23:31:02 +0200157 return path;
158}
159
160private string _query_currentdir()
161{
162 string c;
163 if(!c=Query(P_CURRENTDIR))
164 return Set(P_CURRENTDIR, "/players/"+getuid(this_object()),F_VALUE);
165 return c;
166}
167
168// ##########
169//############################ PROMPT #################################
170// ##########
171
172//
173// _prompt_subst: Mudnamen, Usernamen, Zeilenvorschub in Eingabeauf-
174// forderung einbauen
175// str: Uebergebener Kommandozeilenabschnitt
176//
177
178private string _prompt_subst(string str)
179{
180 switch(str)
181 {
182 case "\\h": return sizeof(MUDNAME)?MUDNAME:"Mud ohne Namen";
183 case "\\u": return capitalize(getuid(this_object()));
184 case "\\n": return "\n";
185 case "\\t": return "\t";
186 case "\\w": return "\w";
187 }
188 return str;
189}
190
191
192//
193// _prompt: Eingabeaufforderung setzen
194// arg: Kommandozeile
195//
196
197static int _prompt(string args)
198{
199 string *pargs;
200
201 args=(extern_call()?_unparsed_args():args);
202 if (!sizeof(args)) args="> ";
203 if (args[0]=='"') args=args[1..<2]; //");
204 if(!sizeof(pargs = regexplode(args, "\\\\[thuwn]")))
205 return USAGE("prompt \"<Eingabeaufforderungsdefinition>\"");
206 pargs=map(pargs,#'_prompt_subst);
207
208 SetProp(P_PROMPT,implode(pargs,""));
209 return 1;
210}
211
212static string _set_prompt(string prompt) {
213 Set(P_PROMPT, prompt, F_VALUE);
bugfix1b04afb2020-04-15 14:52:24 +0200214 modify_prompt(); // neuen Prompt setzen (telnetneg.c)
MG Mud User88f12472016-06-24 23:31:02 +0200215 return prompt;
216}
217
218
219// ##############
220//############################ SHOWPRESAY ###############################
221// ##############
222
223static int _showpresay(string cmdline)
224{
225 int presay;
226 presay=QueryProp(P_CAN_FLAGS)&CAN_PRESAY;
227 cmdline=_unparsed_args(0);
228 if (!sizeof(cmdline))
229 {
230 printf("Dein Presay wird im Moment %sangezeigt.\n"
231 "%sschalten mit \'showpresay %s\'.\n",
232 presay?"":"nicht ",presay?"Aus":"Ein",
233 presay?"aus":"ein");
234 return 1;
235 }
236 if (cmdline=="ein"||cmdline=="an")
237 {
238 printf("Dein Presay wird jetzt angezeigt.\n");
239 SetProp(P_CAN_FLAGS,QueryProp(P_CAN_FLAGS)|CAN_PRESAY);
240 return 1;
241 }
242 if (cmdline=="aus")
243 {
244 printf("Dein Presay wird jetzt nicht mehr angezeigt.\n");
245 SetProp(P_CAN_FLAGS,QueryProp(P_CAN_FLAGS)&~CAN_PRESAY);
246 return 1;
247 }
248 return USAGE("showpresay [ein|an|aus]");
249}
250
251// ########
252//############################### EXEC ###############################
253// ########
254
255static int _exec(string filename)
256{
257 object ob;
258 if (!IS_LORD(this_object())) return 0;
259 if (this_player()!=this_interactive()) return 0;
260 if (this_player()!=this_object()) return 0;
261 if (!(filename=_unparsed_args())) return USAGE("exec <objektname>");
Zesstra876b0d62018-11-08 20:52:22 +0100262 filename=normalize_path(filename, getuid(), 1);
MG Mud User88f12472016-06-24 23:31:02 +0200263 if (file_size(filename)<0&&(!to_filename(filename+".c"))||
264 file_size(to_filename(filename+".c"))<0)
265 {
266 printf("exec: %s: Datei nicht vorhanden oder ein Verzeichnis.\n",filename);
267 return 1;
268 }
Zesstra876b0d62018-11-08 20:52:22 +0100269 if (catch(load_object(filename)))
MG Mud User88f12472016-06-24 23:31:02 +0200270 {
271 printf("exec: Fehler beim Laden von %s.\n",filename);
272 return 1;
273 }
274 if (!(ob=clone_object(filename))) return 0;
275 if (getuid(ob) != getuid(this_object()))
276 {
277 printf("exec: UID-Konflikt: %s <-> %s.\n",getuid(ob),
278 getuid(this_object()));
279 destruct(ob);
280 return 1;
281 }
282 log_file(SHELLLOG("EXEC"),
283 sprintf("%12.12s %40.40s %25.25s\n",
284 capitalize(getuid(this_object())),filename,dtime(time())[4..]));
285 disable_commands();
286 exec(ob,this_object());
287 if (interactive(this_object())||!interactive(ob))
288 {
289 enable_commands();
290 printf("Fehler bei EXEC: Uebertragung der Shell "
291 "nicht moeglich.\n");
292 return 1;
293 }
bugfixd94d0932020-04-08 11:27:13 +0200294 ({int})ob->start_player(capitalize(getuid(this_object())));
MG Mud User88f12472016-06-24 23:31:02 +0200295 remove();
296 return 1;
297}
298// ############
299//############################# SNOOPING ###############################
300// ############
301
302private nosave string snoop_allowed;
303private nosave object snoopee;
304
305nomask int QueryAllowSnoop(object who)
306{
307 return (getuid(who) == snoop_allowed);
308}
309
310static int _sallow(string str)
311{
312 object ob;
313
314 if (!sizeof(str))
315 {
316 if (!snoop_allowed) return USAGE("sallow [<name>]\n");
317 str=snoop_allowed;
318 snoop_allowed=0;
319 printf("Du entziehst %s die Erlaubnis zum Snoopen.\n",capitalize(str));
320 ob=query_snoop(this_player());
321 if (!ob||(getuid(ob)!=str)) return 1;
322 tell_object(ob,break_string(sprintf("%s entzieht Dir die "
323 "Erlaubnis zum snoopen und zwingt Dich so dazu, mit "
324 "dem Snoopen aufzuhoeren.\n",capitalize(getuid()))));
325 snoop(ob);
326 return 1;
327 }
328 if (snoop_allowed) _sallow(""); // Erstmal abschalten
329 ob=find_player(lower_case(str));
330 str=capitalize(str);
331 if (!ob) return
332 printf("sallow: Spieler %s konnte nicht gefunden werden.\n",str),1;
333 if (query_wiz_grp(ob)>query_wiz_grp(this_player()))
334 return printf("sallow: %s hat einen hoeheren Rang als Du und kann "
335 "Dich daher ohnehin snoopen.\n",str),1;
336 snoop_allowed=getuid(ob);
337 return printf("sallow: Du erlaubst %s, Dich zu snoopen.\n",str),1;
338}
339
340static int _snoop(string cmdline)
341{
342 object ob;
343 int flags;
344 string *args;
345
Zesstra12f4fc42020-04-28 22:56:50 +0200346#if __BOOT_TIME__ < 1588106971
347 if (!IS_ARCH(this_object()) && !IS_DEPUTY(this_object()))
348 {
349 printf("Snoopen koennen bis auf Weiteres nur Erzmagier.\n");
350 return 1;
351 }
352#endif
353
MG Mud User88f12472016-06-24 23:31:02 +0200354 if (!sizeof(cmdline=_unparsed_args())||
355 sizeof(args=parseargs(cmdline,&flags,SNOOP_OPTS,0))!=1||flags==-1)
356 {
357 if (!snoop(this_object())) return USAGE("snoop [-" SNOOP_OPTS
358 "] [<spieler>]\n");
359 if (snoopee)
360 printf("Du snoopst %s jetzt nicht mehr.\n",capitalize(getuid(snoopee)));
361 else
362 {
363 printf("Du hoerst auf zu snoopen.\n");
364 // evtl. irgendetwas loggen ... sollte eigentlich nicht passieren.
365 }
Vanion50652322020-03-10 21:13:25 +0100366 snoopee=0;
MG Mud User88f12472016-06-24 23:31:02 +0200367 return 1;
368 }
369 SetProp(P_SNOOPFLAGS,flags); // FUNKTIONIERT NUR, WENN magier.h und
370 // snooping.h abgeglichen sind
371 if (!(ob = find_player(args[0])))
372 return printf("snoop: Konnte keinen Spieler '%s' finden.\n",
373 capitalize(args[0])),1;
374 if (!snoop(this_player(),ob))
375 return printf("snoop: Der Versuch, %s zu snoopen, ist "
376 "fehlgeschlagen.\n%s",capitalize(args[0]),
377 ((~flags)&SNOOP_F)?"Eventuell funktioniert es mit dem "
378 "Flag '-f'.\n":""),1;
379 snoopee=ob;
380 return printf("Du snoopst jetzt %s.\n",capitalize(getuid(ob))),1;
381}
382
383
384// ##########
385//############################ MSCHAU #################################
386// ##########
387
388static int _mschau(string str)
389{
390 if (this_interactive()!=this_object()) return 0;
391 if (str=="ja"||str=="an"||str=="ein")
392 {
393 if ( QueryProp(P_WANTS_TO_LEARN) )
394 printf("Du hast den Magier-Modus doch schon eingeschaltet!\n");
395 else
396 {
397 printf("Du hast jetzt den Magier-Modus eingeschaltet.\n" );
398 SetProp(P_WANTS_TO_LEARN, 1);
399 }
400 return 1;
401 }
402 if (str=="nein"||str=="aus")
403 {
404 if (QueryProp(P_WANTS_TO_LEARN))
405 {
406 printf( "Du schaltest den Magier-Modus aus.\n");
407 set_heart_beat(1);
408 SetProp(P_WANTS_TO_LEARN,0);
409 }
410 else
411 printf("Du hast den Magier-Modus doch schon ausgeschaltet.\n");
412 return 1;
413 }
414 if (str=="+debug")
415 {
416 printf("Du nimmst jetzt Debugausgaben wahr.\n");
417 SetProp(P_WIZ_DEBUG,1);
418 return 1;
419 }
420 if (str=="-debug")
421 {
422 printf("Du nimmst jetzt keine Debugausgaben mehr wahr.\n");
423 SetProp(P_WIZ_DEBUG,0);
424 return 1;
425 }
426 return USAGE("mschau [an|ein|ja|aus|nein|+debug|-debug]\n");
427}
428
429// ###########
430//############################ PROTECT ################################
431// ###########
432
433static int _protect(string str)
434{
435
436 if (this_object()!=this_interactive()) return 0;
437 if (!sizeof(str))
438 return USAGE("protect <propertyname>\n");
439 Set(str, PROTECTED, F_MODE);
440 return printf("Deine Property %s ist jetzt %sgeschuetzt.\n",
441 str,(Query(str,F_MODE) & PROTECTED?"":"nicht mehr ")),1;
442}
443
444
445// ###############
446//########################## VIS + INVIS ##############################
447// ###############
448
449static int _hbstop;
450static int _age;
451
452static int _invis(string inform)
453{
454
455 if (QueryProp(P_INVIS))
456 return printf("Du bist doch schon unsichtbar!\n"),1;
457 tell_room(environment(),sprintf("%s %s.\n",capitalize(Name()),
458 QueryProp(P_MMSGOUT)),({ this_object() }));
459 if (inform=="e") {
460 // Logout-event ausloesen
bugfixd94d0932020-04-08 11:27:13 +0200461 ({int})EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
MG Mud User88f12472016-06-24 23:31:02 +0200462 E_OBJECT: this_object(),
463 E_PLNAME: getuid(this_object()),
464 E_ENVIRONMENT: environment() ]) );
465
466 call_notify_player_change(0);
467 }
468
469 SetProp(P_INVIS, QueryProp(P_AGE));
470 printf("Du bist jetzt unsichtbar.\n");
471 return 1;
472}
473
474static int _vis(string inform)
475{
476 if (!QueryProp(P_INVIS))
477 return printf("Du bist doch schon sichtbar.\n"),1;
478 tell_room(environment(),sprintf("%s %s.\n",capitalize(Name()),
479 QueryProp(P_MMSGIN)),({ this_object() }));
480 SetProp(P_INVIS, 0);
481 if (inform=="e") {
482 // Login-event ausloesen
bugfixd94d0932020-04-08 11:27:13 +0200483 ({int})EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
MG Mud User88f12472016-06-24 23:31:02 +0200484 E_OBJECT: this_object(),
485 E_PLNAME: getuid(this_object()),
486 E_ENVIRONMENT: environment() ]) );
487
488 call_notify_player_change(1);
489 }
490 printf("Du bist jetzt sichtbar.\n");
491 return 1;
492}
493
494// ############
495//########################### LOCALCMD ###############################
496// ############
497
498
499static int _localcmd()
500{
501 int size,more;
502 string *verbs,result;
503
504 // Per Umweg ueber Mapping doppelte Werte einstampfen
505 size=sizeof(verbs=m_indices(mkmapping(query_actions(this_object()))));
506 verbs-=({""});
507 more=(size>sizeof(verbs));
508 if (!sizeof(verbs))
509 {
510 if (more)
511 printf("Die vorhandenen Befehle koennen nicht angezeigt werden, "
512 "da sie per 'add_action(\"funktion\",\"\",1)' definiert "
513 "wurden.\n");
514 else
515 printf("Dir stehen keine Befehle zur Verfuegung ... eigenartig!\n");
516 return 1;
517 }
518 verbs=sort_array(verbs,#'>);
519 result=break_string(sprintf("\'%s\'",implode(verbs,"' '")),78);
520 return printf("\n%'-'78.78s\nDie fuer Dich aktuell verfuegbaren "
521 "Befehle sind:\n\n%s\n%s%'-'78.78s\n","",result,
522 more?"Zudem wurden Befehle per 'add_action("
523 "\"funktion\",\"\",1)' definiert.\n":"",""),1;
524}
525
526// ###########
527//############################ TRAENKE ################################
528// ###########
529
530static int _traenke(string str)
531{
532 if(SetProp(P_TRANK_FINDEN, !QueryProp(P_TRANK_FINDEN)))
533 write("Du kannst jetzt Zaubertraenke finden.\n");
534 else
535 write("Du findest jetzt keine Zaubertraenke mehr.\n");
536 return 1;
537}
538
539static int norm_rusage() {
540 mixed* r;
541 r = rusage();
542 return r[0]/100 + r[1]/100;
543}
544
545// #############
546//############################ ASYNCHRON #################################
547// #############
548
549//
550// asynchron(): Asynchrone Abarbeitung eines Arrays
551// array: Zu bearbeitendes Array
552// cmd: Auszufuehrende Closure
553// data: Extraargumente
554// flags: Zusatzdaten (normalerweise Flags)
555// c: schon asynchron?
556//
557
558static varargs void asynchron(mixed* array, closure cmd, mixed data, mixed flags,int c)
559{
560 int i, j, k;
561 mixed ret_val;
562 string cmd_string;
563
564 k = norm_rusage()+5;
565 j = sizeof(array);
566 i=0;
567
568 switch (cmd_string=explode(sprintf("%O",cmd),"->")[1])
569 {
570 case "_make": cmd_string=(data&UPD_LOAD?"load":"upd");break;
571 case "cp_file": cmd_string =(data?"mv":"cp"); break;
572 case "grep_file": cmd_string = "grep"; break;
573 case "rm_file": cmd_string = "rm"; break;
574 default: break;
575 }
576
577 while(i < j && get_eval_cost() > 200000 && norm_rusage()<k)
578 // Sowohl Too-Long-Eval als auch Lag verhindern
579 {
580 ret_val=apply(cmd,array[i],data, flags);
581 if (closurep(ret_val))
582 {
583 if(c) tell_object(this_object(),
584 sprintf("%s: Verlasse Asynchronen Modus.\n",cmd_string));
585 funcall(ret_val,array[i..],data,flags);
586 return;
587 }
588 if (ret_val==RET_DELETE)
589 {
590 array[i+array[i][SUBDIRSIZE]+1..i+array[i][SUBDIRSIZE]]=
591 ({ (array[i][0..5]+({0})) });
592 }
593 if (ret_val==RET_JUMP) i+=array[i][SUBDIRSIZE];
594 i++;
595 }
596 if(sizeof(array = array[i..]))
597 {
598 if(!c) tell_object(this_object(),
599 sprintf("%s: Asynchroner Modus aktiviert!\n", cmd_string));
600 call_out(#'asynchron, 1, array, cmd, data,flags, 1);
601 }
602 else
603 {
604 if(c) tell_object(this_object(),
605 sprintf("%s: abgeschlossen.\n",cmd_string));
606 else if (query_verb()) tell_object(this_object(),
607 sprintf("%s: abgeschlossen.\n",query_verb()));
608 }
609 return;
610}
611
612//
613// ######################## Driver Status Infos ##########################
614//
615static int _driver_malloc(string str)
616{
617 if(!sizeof(str))
618 {
619 write(efun::driver_info(DI_STATUS_TEXT_MALLOC));
620 return 1;
621 }
622 if(str == "extstats")
623 {
624 write(efun::driver_info(DI_STATUS_TEXT_MALLOC_EXTENDED));
625 return 1;
626 }
627 return 0;
628}
629
630static int _driver_dumpallobj(string str)
631{
632 write("Dumping to /OBJ_DUMP ... ");
633 efun::dump_driver_info(DDI_OBJECTS);
634 efun::dump_driver_info(DDI_OBJECTS_DESTRUCTED);
635 write("done\n");
636 return 1;
637}
638
639static int _driver_opcdump(string str)
640{
641 efun::dump_driver_info(DDI_OPCODES);
642 return 1;
643}
644
645static int _driver_status(string str)
646{
647 int opt;
648
649 switch(str || "")
650 {
651 case "":
652 opt = DI_STATUS_TEXT_MEMORY;
653 break;
654
655 case "tables":
656 case " tables":
657 opt = DI_STATUS_TEXT_TABLES;
658 break;
659
660 case "swap":
661 case " swap":
662 opt = DI_STATUS_TEXT_SWAP;
663 break;
664
665 case "malloc":
666 case " malloc":
667 opt = DI_STATUS_TEXT_MALLOC;
668 break;
669
670 case "malloc extstats":
671 case " malloc extstats":
672 opt = DI_STATUS_TEXT_MALLOC_EXTENDED;
673 break;
674
675 default:
676 return 0;
677 }
678 write(efun::driver_info(opt));
679 return 1;
680}
681
682// ###################
683//########################## INITIALISIERUNG #############################
684// ###################
685
686//
687// _query_localcmds: Welche Kommandos werden in dieser Datei implementiert?
688//
689
690static mixed _query_localcmds()
691{
692 return ({
693 ({"set","_set",0,LEARNER_LVL}),
694 ({"pwd","_pwd",0,LEARNER_LVL}),
695 ({"cd","_cd",0,LEARNER_LVL}),
696 ({"prompt","_prompt",0,LEARNER_LVL}),
697 ({"showpresay","_showpresay",0,LEARNER_LVL}),
698 ({"exec","_exec",0,ARCH_LVL}),
699 ({"sallow","_sallow",0,LEARNER_LVL}),
700 ({"snoop","_snoop",0,WIZARD_LVL}),
701 ({"mschau","_mschau",0,LEARNER_LVL}),
702 ({"protect","_protect",0,WIZARD_LVL}),
703 ({"invis","_invis",0,LEARNER_LVL}),
704 ({"vis","_vis",0,LEARNER_LVL}),
705 ({"localcmd","_localcmd",0,LEARNER_LVL}),
706 ({"traenke","_traenke",0,DOMAINMEMBER_LVL}),
707 ({"malloc","_driver_malloc",0,LEARNER_LVL}),
708 ({"dumpallobj","_driver_dumpallobj",0,ARCH_LVL}),
709 ({"opcdump","_driver_opcdump",0,ARCH_LVL}),
710 ({"status","_driver_status",0,LEARNER_LVL}),
711 })
712 +fileview::_query_localcmds()
713 +upd::_query_localcmds()
714 +objects::_query_localcmds()
715 +fileedit::_query_localcmds()
716// +todo::_query_localcmds()
717 +players::_query_localcmds()
718 +admin::_query_localcmds()
719 +moving::_query_localcmds()
720 +comm::_query_localcmds();
721}
722
723//
724// initialize: Initialisierung der Shell
725//
726
727static void initialize()
728{
729 Set(P_PROMPT, SAVE, F_MODE_AS);
730 Set(P_VARIABLES,SAVE,F_MODE_AS);
731 Set("filesys",SAVE,F_MODE_AD); // P_FILESYS ist obsolet
732 Set("short_cwd",SAVE,F_MODE_AD); // P_SHORT_CWD auch
733 if(!mappingp(QueryProp(P_VARIABLES)))
734 SetProp(P_VARIABLES, ([]));
735 _prompt(QueryProp(P_PROMPT));
736// todo::initialize();
737 _cd2("");
738 return;
739}
740
741static void reconnect() { _cd(QueryProp(P_CURRENTDIR)); }