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