blob: 926d0b217fba39d03bb8b7b052b8dda99e1b730d [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>
17#undef NEED_PROTOTYPES
18#include <properties.h>
19#include <files.h>
20#include <events.h>
21#include <player/comm.h>
22
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);
bugfixd94d0932020-04-08 11:27:13 +0200157 ({void})this_object()->modify_prompt(); // Prompt mit neuem Pfad setzen, telnetneg
MG Mud User88f12472016-06-24 23:31:02 +0200158 return path;
159}
160
161private string _query_currentdir()
162{
163 string c;
164 if(!c=Query(P_CURRENTDIR))
165 return Set(P_CURRENTDIR, "/players/"+getuid(this_object()),F_VALUE);
166 return c;
167}
168
169// ##########
170//############################ PROMPT #################################
171// ##########
172
173//
174// _prompt_subst: Mudnamen, Usernamen, Zeilenvorschub in Eingabeauf-
175// forderung einbauen
176// str: Uebergebener Kommandozeilenabschnitt
177//
178
179private string _prompt_subst(string str)
180{
181 switch(str)
182 {
183 case "\\h": return sizeof(MUDNAME)?MUDNAME:"Mud ohne Namen";
184 case "\\u": return capitalize(getuid(this_object()));
185 case "\\n": return "\n";
186 case "\\t": return "\t";
187 case "\\w": return "\w";
188 }
189 return str;
190}
191
192
193//
194// _prompt: Eingabeaufforderung setzen
195// arg: Kommandozeile
196//
197
198static int _prompt(string args)
199{
200 string *pargs;
201
202 args=(extern_call()?_unparsed_args():args);
203 if (!sizeof(args)) args="> ";
204 if (args[0]=='"') args=args[1..<2]; //");
205 if(!sizeof(pargs = regexplode(args, "\\\\[thuwn]")))
206 return USAGE("prompt \"<Eingabeaufforderungsdefinition>\"");
207 pargs=map(pargs,#'_prompt_subst);
208
209 SetProp(P_PROMPT,implode(pargs,""));
210 return 1;
211}
212
213static string _set_prompt(string prompt) {
214 Set(P_PROMPT, prompt, F_VALUE);
bugfixd94d0932020-04-08 11:27:13 +0200215 ({void})this_object()->modify_prompt(); // neuen Prompt setzen (telnetneg.c)
MG Mud User88f12472016-06-24 23:31:02 +0200216 return prompt;
217}
218
219
220// ##############
221//############################ SHOWPRESAY ###############################
222// ##############
223
224static int _showpresay(string cmdline)
225{
226 int presay;
227 presay=QueryProp(P_CAN_FLAGS)&CAN_PRESAY;
228 cmdline=_unparsed_args(0);
229 if (!sizeof(cmdline))
230 {
231 printf("Dein Presay wird im Moment %sangezeigt.\n"
232 "%sschalten mit \'showpresay %s\'.\n",
233 presay?"":"nicht ",presay?"Aus":"Ein",
234 presay?"aus":"ein");
235 return 1;
236 }
237 if (cmdline=="ein"||cmdline=="an")
238 {
239 printf("Dein Presay wird jetzt angezeigt.\n");
240 SetProp(P_CAN_FLAGS,QueryProp(P_CAN_FLAGS)|CAN_PRESAY);
241 return 1;
242 }
243 if (cmdline=="aus")
244 {
245 printf("Dein Presay wird jetzt nicht mehr angezeigt.\n");
246 SetProp(P_CAN_FLAGS,QueryProp(P_CAN_FLAGS)&~CAN_PRESAY);
247 return 1;
248 }
249 return USAGE("showpresay [ein|an|aus]");
250}
251
252// ########
253//############################### EXEC ###############################
254// ########
255
256static int _exec(string filename)
257{
258 object ob;
259 if (!IS_LORD(this_object())) return 0;
260 if (this_player()!=this_interactive()) return 0;
261 if (this_player()!=this_object()) return 0;
262 if (!(filename=_unparsed_args())) return USAGE("exec <objektname>");
Zesstra876b0d62018-11-08 20:52:22 +0100263 filename=normalize_path(filename, getuid(), 1);
MG Mud User88f12472016-06-24 23:31:02 +0200264 if (file_size(filename)<0&&(!to_filename(filename+".c"))||
265 file_size(to_filename(filename+".c"))<0)
266 {
267 printf("exec: %s: Datei nicht vorhanden oder ein Verzeichnis.\n",filename);
268 return 1;
269 }
Zesstra876b0d62018-11-08 20:52:22 +0100270 if (catch(load_object(filename)))
MG Mud User88f12472016-06-24 23:31:02 +0200271 {
272 printf("exec: Fehler beim Laden von %s.\n",filename);
273 return 1;
274 }
275 if (!(ob=clone_object(filename))) return 0;
276 if (getuid(ob) != getuid(this_object()))
277 {
278 printf("exec: UID-Konflikt: %s <-> %s.\n",getuid(ob),
279 getuid(this_object()));
280 destruct(ob);
281 return 1;
282 }
283 log_file(SHELLLOG("EXEC"),
284 sprintf("%12.12s %40.40s %25.25s\n",
285 capitalize(getuid(this_object())),filename,dtime(time())[4..]));
286 disable_commands();
287 exec(ob,this_object());
288 if (interactive(this_object())||!interactive(ob))
289 {
290 enable_commands();
291 printf("Fehler bei EXEC: Uebertragung der Shell "
292 "nicht moeglich.\n");
293 return 1;
294 }
bugfixd94d0932020-04-08 11:27:13 +0200295 ({int})ob->start_player(capitalize(getuid(this_object())));
MG Mud User88f12472016-06-24 23:31:02 +0200296 remove();
297 return 1;
298}
299// ############
300//############################# SNOOPING ###############################
301// ############
302
303private nosave string snoop_allowed;
304private nosave object snoopee;
305
306nomask int QueryAllowSnoop(object who)
307{
308 return (getuid(who) == snoop_allowed);
309}
310
311static int _sallow(string str)
312{
313 object ob;
314
315 if (!sizeof(str))
316 {
317 if (!snoop_allowed) return USAGE("sallow [<name>]\n");
318 str=snoop_allowed;
319 snoop_allowed=0;
320 printf("Du entziehst %s die Erlaubnis zum Snoopen.\n",capitalize(str));
321 ob=query_snoop(this_player());
322 if (!ob||(getuid(ob)!=str)) return 1;
323 tell_object(ob,break_string(sprintf("%s entzieht Dir die "
324 "Erlaubnis zum snoopen und zwingt Dich so dazu, mit "
325 "dem Snoopen aufzuhoeren.\n",capitalize(getuid()))));
326 snoop(ob);
327 return 1;
328 }
329 if (snoop_allowed) _sallow(""); // Erstmal abschalten
330 ob=find_player(lower_case(str));
331 str=capitalize(str);
332 if (!ob) return
333 printf("sallow: Spieler %s konnte nicht gefunden werden.\n",str),1;
334 if (query_wiz_grp(ob)>query_wiz_grp(this_player()))
335 return printf("sallow: %s hat einen hoeheren Rang als Du und kann "
336 "Dich daher ohnehin snoopen.\n",str),1;
337 snoop_allowed=getuid(ob);
338 return printf("sallow: Du erlaubst %s, Dich zu snoopen.\n",str),1;
339}
340
341static int _snoop(string cmdline)
342{
343 object ob;
344 int flags;
345 string *args;
346
347 if (!sizeof(cmdline=_unparsed_args())||
348 sizeof(args=parseargs(cmdline,&flags,SNOOP_OPTS,0))!=1||flags==-1)
349 {
350 if (!snoop(this_object())) return USAGE("snoop [-" SNOOP_OPTS
351 "] [<spieler>]\n");
352 if (snoopee)
353 printf("Du snoopst %s jetzt nicht mehr.\n",capitalize(getuid(snoopee)));
354 else
355 {
356 printf("Du hoerst auf zu snoopen.\n");
357 // evtl. irgendetwas loggen ... sollte eigentlich nicht passieren.
358 }
Vanion50652322020-03-10 21:13:25 +0100359 snoopee=0;
MG Mud User88f12472016-06-24 23:31:02 +0200360 return 1;
361 }
362 SetProp(P_SNOOPFLAGS,flags); // FUNKTIONIERT NUR, WENN magier.h und
363 // snooping.h abgeglichen sind
364 if (!(ob = find_player(args[0])))
365 return printf("snoop: Konnte keinen Spieler '%s' finden.\n",
366 capitalize(args[0])),1;
367 if (!snoop(this_player(),ob))
368 return printf("snoop: Der Versuch, %s zu snoopen, ist "
369 "fehlgeschlagen.\n%s",capitalize(args[0]),
370 ((~flags)&SNOOP_F)?"Eventuell funktioniert es mit dem "
371 "Flag '-f'.\n":""),1;
372 snoopee=ob;
373 return printf("Du snoopst jetzt %s.\n",capitalize(getuid(ob))),1;
374}
375
376
377// ##########
378//############################ MSCHAU #################################
379// ##########
380
381static int _mschau(string str)
382{
383 if (this_interactive()!=this_object()) return 0;
384 if (str=="ja"||str=="an"||str=="ein")
385 {
386 if ( QueryProp(P_WANTS_TO_LEARN) )
387 printf("Du hast den Magier-Modus doch schon eingeschaltet!\n");
388 else
389 {
390 printf("Du hast jetzt den Magier-Modus eingeschaltet.\n" );
391 SetProp(P_WANTS_TO_LEARN, 1);
392 }
393 return 1;
394 }
395 if (str=="nein"||str=="aus")
396 {
397 if (QueryProp(P_WANTS_TO_LEARN))
398 {
399 printf( "Du schaltest den Magier-Modus aus.\n");
400 set_heart_beat(1);
401 SetProp(P_WANTS_TO_LEARN,0);
402 }
403 else
404 printf("Du hast den Magier-Modus doch schon ausgeschaltet.\n");
405 return 1;
406 }
407 if (str=="+debug")
408 {
409 printf("Du nimmst jetzt Debugausgaben wahr.\n");
410 SetProp(P_WIZ_DEBUG,1);
411 return 1;
412 }
413 if (str=="-debug")
414 {
415 printf("Du nimmst jetzt keine Debugausgaben mehr wahr.\n");
416 SetProp(P_WIZ_DEBUG,0);
417 return 1;
418 }
419 return USAGE("mschau [an|ein|ja|aus|nein|+debug|-debug]\n");
420}
421
422// ###########
423//############################ PROTECT ################################
424// ###########
425
426static int _protect(string str)
427{
428
429 if (this_object()!=this_interactive()) return 0;
430 if (!sizeof(str))
431 return USAGE("protect <propertyname>\n");
432 Set(str, PROTECTED, F_MODE);
433 return printf("Deine Property %s ist jetzt %sgeschuetzt.\n",
434 str,(Query(str,F_MODE) & PROTECTED?"":"nicht mehr ")),1;
435}
436
437
438// ###############
439//########################## VIS + INVIS ##############################
440// ###############
441
442static int _hbstop;
443static int _age;
444
445static int _invis(string inform)
446{
447
448 if (QueryProp(P_INVIS))
449 return printf("Du bist doch schon unsichtbar!\n"),1;
450 tell_room(environment(),sprintf("%s %s.\n",capitalize(Name()),
451 QueryProp(P_MMSGOUT)),({ this_object() }));
452 if (inform=="e") {
453 // Logout-event ausloesen
bugfixd94d0932020-04-08 11:27:13 +0200454 ({int})EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
MG Mud User88f12472016-06-24 23:31:02 +0200455 E_OBJECT: this_object(),
456 E_PLNAME: getuid(this_object()),
457 E_ENVIRONMENT: environment() ]) );
458
459 call_notify_player_change(0);
460 }
461
462 SetProp(P_INVIS, QueryProp(P_AGE));
463 printf("Du bist jetzt unsichtbar.\n");
464 return 1;
465}
466
467static int _vis(string inform)
468{
469 if (!QueryProp(P_INVIS))
470 return printf("Du bist doch schon sichtbar.\n"),1;
471 tell_room(environment(),sprintf("%s %s.\n",capitalize(Name()),
472 QueryProp(P_MMSGIN)),({ this_object() }));
473 SetProp(P_INVIS, 0);
474 if (inform=="e") {
475 // Login-event ausloesen
bugfixd94d0932020-04-08 11:27:13 +0200476 ({int})EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
MG Mud User88f12472016-06-24 23:31:02 +0200477 E_OBJECT: this_object(),
478 E_PLNAME: getuid(this_object()),
479 E_ENVIRONMENT: environment() ]) );
480
481 call_notify_player_change(1);
482 }
483 printf("Du bist jetzt sichtbar.\n");
484 return 1;
485}
486
487// ############
488//########################### LOCALCMD ###############################
489// ############
490
491
492static int _localcmd()
493{
494 int size,more;
495 string *verbs,result;
496
497 // Per Umweg ueber Mapping doppelte Werte einstampfen
498 size=sizeof(verbs=m_indices(mkmapping(query_actions(this_object()))));
499 verbs-=({""});
500 more=(size>sizeof(verbs));
501 if (!sizeof(verbs))
502 {
503 if (more)
504 printf("Die vorhandenen Befehle koennen nicht angezeigt werden, "
505 "da sie per 'add_action(\"funktion\",\"\",1)' definiert "
506 "wurden.\n");
507 else
508 printf("Dir stehen keine Befehle zur Verfuegung ... eigenartig!\n");
509 return 1;
510 }
511 verbs=sort_array(verbs,#'>);
512 result=break_string(sprintf("\'%s\'",implode(verbs,"' '")),78);
513 return printf("\n%'-'78.78s\nDie fuer Dich aktuell verfuegbaren "
514 "Befehle sind:\n\n%s\n%s%'-'78.78s\n","",result,
515 more?"Zudem wurden Befehle per 'add_action("
516 "\"funktion\",\"\",1)' definiert.\n":"",""),1;
517}
518
519// ###########
520//############################ TRAENKE ################################
521// ###########
522
523static int _traenke(string str)
524{
525 if(SetProp(P_TRANK_FINDEN, !QueryProp(P_TRANK_FINDEN)))
526 write("Du kannst jetzt Zaubertraenke finden.\n");
527 else
528 write("Du findest jetzt keine Zaubertraenke mehr.\n");
529 return 1;
530}
531
532static int norm_rusage() {
533 mixed* r;
534 r = rusage();
535 return r[0]/100 + r[1]/100;
536}
537
538// #############
539//############################ ASYNCHRON #################################
540// #############
541
542//
543// asynchron(): Asynchrone Abarbeitung eines Arrays
544// array: Zu bearbeitendes Array
545// cmd: Auszufuehrende Closure
546// data: Extraargumente
547// flags: Zusatzdaten (normalerweise Flags)
548// c: schon asynchron?
549//
550
551static varargs void asynchron(mixed* array, closure cmd, mixed data, mixed flags,int c)
552{
553 int i, j, k;
554 mixed ret_val;
555 string cmd_string;
556
557 k = norm_rusage()+5;
558 j = sizeof(array);
559 i=0;
560
561 switch (cmd_string=explode(sprintf("%O",cmd),"->")[1])
562 {
563 case "_make": cmd_string=(data&UPD_LOAD?"load":"upd");break;
564 case "cp_file": cmd_string =(data?"mv":"cp"); break;
565 case "grep_file": cmd_string = "grep"; break;
566 case "rm_file": cmd_string = "rm"; break;
567 default: break;
568 }
569
570 while(i < j && get_eval_cost() > 200000 && norm_rusage()<k)
571 // Sowohl Too-Long-Eval als auch Lag verhindern
572 {
573 ret_val=apply(cmd,array[i],data, flags);
574 if (closurep(ret_val))
575 {
576 if(c) tell_object(this_object(),
577 sprintf("%s: Verlasse Asynchronen Modus.\n",cmd_string));
578 funcall(ret_val,array[i..],data,flags);
579 return;
580 }
581 if (ret_val==RET_DELETE)
582 {
583 array[i+array[i][SUBDIRSIZE]+1..i+array[i][SUBDIRSIZE]]=
584 ({ (array[i][0..5]+({0})) });
585 }
586 if (ret_val==RET_JUMP) i+=array[i][SUBDIRSIZE];
587 i++;
588 }
589 if(sizeof(array = array[i..]))
590 {
591 if(!c) tell_object(this_object(),
592 sprintf("%s: Asynchroner Modus aktiviert!\n", cmd_string));
593 call_out(#'asynchron, 1, array, cmd, data,flags, 1);
594 }
595 else
596 {
597 if(c) tell_object(this_object(),
598 sprintf("%s: abgeschlossen.\n",cmd_string));
599 else if (query_verb()) tell_object(this_object(),
600 sprintf("%s: abgeschlossen.\n",query_verb()));
601 }
602 return;
603}
604
605//
606// ######################## Driver Status Infos ##########################
607//
608static int _driver_malloc(string str)
609{
610 if(!sizeof(str))
611 {
612 write(efun::driver_info(DI_STATUS_TEXT_MALLOC));
613 return 1;
614 }
615 if(str == "extstats")
616 {
617 write(efun::driver_info(DI_STATUS_TEXT_MALLOC_EXTENDED));
618 return 1;
619 }
620 return 0;
621}
622
623static int _driver_dumpallobj(string str)
624{
625 write("Dumping to /OBJ_DUMP ... ");
626 efun::dump_driver_info(DDI_OBJECTS);
627 efun::dump_driver_info(DDI_OBJECTS_DESTRUCTED);
628 write("done\n");
629 return 1;
630}
631
632static int _driver_opcdump(string str)
633{
634 efun::dump_driver_info(DDI_OPCODES);
635 return 1;
636}
637
638static int _driver_status(string str)
639{
640 int opt;
641
642 switch(str || "")
643 {
644 case "":
645 opt = DI_STATUS_TEXT_MEMORY;
646 break;
647
648 case "tables":
649 case " tables":
650 opt = DI_STATUS_TEXT_TABLES;
651 break;
652
653 case "swap":
654 case " swap":
655 opt = DI_STATUS_TEXT_SWAP;
656 break;
657
658 case "malloc":
659 case " malloc":
660 opt = DI_STATUS_TEXT_MALLOC;
661 break;
662
663 case "malloc extstats":
664 case " malloc extstats":
665 opt = DI_STATUS_TEXT_MALLOC_EXTENDED;
666 break;
667
668 default:
669 return 0;
670 }
671 write(efun::driver_info(opt));
672 return 1;
673}
674
675// ###################
676//########################## INITIALISIERUNG #############################
677// ###################
678
679//
680// _query_localcmds: Welche Kommandos werden in dieser Datei implementiert?
681//
682
683static mixed _query_localcmds()
684{
685 return ({
686 ({"set","_set",0,LEARNER_LVL}),
687 ({"pwd","_pwd",0,LEARNER_LVL}),
688 ({"cd","_cd",0,LEARNER_LVL}),
689 ({"prompt","_prompt",0,LEARNER_LVL}),
690 ({"showpresay","_showpresay",0,LEARNER_LVL}),
691 ({"exec","_exec",0,ARCH_LVL}),
692 ({"sallow","_sallow",0,LEARNER_LVL}),
693 ({"snoop","_snoop",0,WIZARD_LVL}),
694 ({"mschau","_mschau",0,LEARNER_LVL}),
695 ({"protect","_protect",0,WIZARD_LVL}),
696 ({"invis","_invis",0,LEARNER_LVL}),
697 ({"vis","_vis",0,LEARNER_LVL}),
698 ({"localcmd","_localcmd",0,LEARNER_LVL}),
699 ({"traenke","_traenke",0,DOMAINMEMBER_LVL}),
700 ({"malloc","_driver_malloc",0,LEARNER_LVL}),
701 ({"dumpallobj","_driver_dumpallobj",0,ARCH_LVL}),
702 ({"opcdump","_driver_opcdump",0,ARCH_LVL}),
703 ({"status","_driver_status",0,LEARNER_LVL}),
704 })
705 +fileview::_query_localcmds()
706 +upd::_query_localcmds()
707 +objects::_query_localcmds()
708 +fileedit::_query_localcmds()
709// +todo::_query_localcmds()
710 +players::_query_localcmds()
711 +admin::_query_localcmds()
712 +moving::_query_localcmds()
713 +comm::_query_localcmds();
714}
715
716//
717// initialize: Initialisierung der Shell
718//
719
720static void initialize()
721{
722 Set(P_PROMPT, SAVE, F_MODE_AS);
723 Set(P_VARIABLES,SAVE,F_MODE_AS);
724 Set("filesys",SAVE,F_MODE_AD); // P_FILESYS ist obsolet
725 Set("short_cwd",SAVE,F_MODE_AD); // P_SHORT_CWD auch
726 if(!mappingp(QueryProp(P_VARIABLES)))
727 SetProp(P_VARIABLES, ([]));
728 _prompt(QueryProp(P_PROMPT));
729// todo::initialize();
730 _cd2("");
731 return;
732}
733
734static void reconnect() { _cd(QueryProp(P_CURRENTDIR)); }