diff --git a/std/player/command.c b/std/player/command.c
new file mode 100644
index 0000000..230445d
--- /dev/null
+++ b/std/player/command.c
@@ -0,0 +1,1074 @@
+// MorgenGrauen MUDlib
+//
+// player/commands.c -- alias, history and player command handling
+//
+// $Id: command.c 9576 2016-06-18 15:00:01Z Zesstra $
+#pragma strong_types
+#pragma save_types
+//#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <player/command.h>
+#include <player/comm.h>
+#include <thing/properties.h>
+#include <living/moving.h>
+#include <player.h>
+#undef NEED_PROTOTYPES
+
+#include <properties.h>
+#include <language.h>
+#include <new_skills.h>
+#include <config.h>
+#include <defines.h>
+#include <wizlevels.h>
+#include <logging.h>
+#include <strings.h>
+
+#define CBLOG(x)    log_file(SHELLLOG("DISABLECOMMANDS"),x,200000)
+
+#define HIST_SIZE 40
+#define EPMASTER "/secure/explorationmaster"
+
+private mapping aliases;
+private string *commands;
+private int hist_size, show_processing, histmin;
+private string default_notify_fail;
+private nosave string *history, *unparsed_args, unmodified;
+private nosave int hist_now;
+private nosave object last_command_env;
+private nosave int cmds_per_time, last_chg, max_commands, *cmd_types;
+// Datenstruktur: ({Setzer, Ablaufzeit, String/Closure})
+private nosave mixed disablecommands;
+private nosave object* syntaxdb;
+
+nomask void __set_bb(int flag);
+
+static varargs int __auswerten(string str, string intern);
+varargs int SoulComm(string str, string _verb);
+varargs mixed More(string str, int fflag, string returnto);
+static int _starts_with(string str, string start);
+static void reallocate_histbuf();
+
+private void AddHistory(string str)
+{
+  if (!stringp(str) || str=="" || str[0]=='&' || str[0]=='^' ||
+      str=="hist")
+    return;
+  if (!hist_size) return;
+  if (!pointerp(history) || sizeof(history)!=hist_size)
+    reallocate_histbuf();
+  if (sizeof(str)>=histmin && history[(hist_size+hist_now-1)%hist_size]!=str)
+    history[(hist_now++)%hist_size]=str;
+}
+
+static void create()
+{
+  last_chg=0;
+  histmin=hist_now=0;
+  Set(P_LOCALCMDS,({}));
+  Set(P_LOCALCMDS,PROTECTED,F_MODE_AS);
+  Set("_syntaxdb", SECURED|SAVE, F_MODE_AS);
+
+  show_processing=1;
+  unparsed_args=({0,0,0});
+  hist_size=HIST_SIZE;
+}
+
+static int replacedisplay(string str)
+{
+  if (!str || str=="" || !sscanf(str,"%d",show_processing))
+    printf("Unzulaessige Eingabe!\n%s 0|1|2\n",query_verb());
+    printf("Ersetzungsanzeige auf Level %d.\nLevel 0: Nichts anzeigen\n"+
+     "Level 1: Nur History-Ersetzungen anzeigen\n"+
+     "Level 2: History- und Alias-Ersetzungen anzeigen\n",show_processing);
+  if (show_processing>2&&!IS_WIZARD(ME)) show_processing=2;
+  return 1;
+}
+
+static int histmin(string str)
+{
+  int len;
+
+  if (!str||!sscanf(str,"%d",len)||len<0)
+  {
+    write("Benutzung: histmin ZAHL\nLegt die Mindestlaenge fest, die eine \
+Befehlszeile haben muss, um in den\nHistory-Puffer zu gelangen. Derzeit \
+eingestellt auf "+(string)histmin+" Zeichen.\n");
+    return 1;
+  }
+  histmin=len;
+  write("Mindestlaenge auf "+(string)len+" eingestellt.\n");
+  return 1;
+}
+
+static void reallocate_histbuf()
+{
+  int i;
+
+  history=allocate(hist_size);
+  hist_now=0;
+  for (i=0;i<hist_size;i++)
+    if (!stringp(history[i]))
+      history[i]="\n\n";
+}
+
+static int histlen(string str)
+{
+  int d;
+  if (!str||!sscanf(str,"%d",d)||d<0||d>40)
+  {
+    write("Benutzung: histlen ZAHL\nZAHL muss zwischen 0 und 40 liegen.\n");
+    printf("Deine History-Buffer-Laenge liegt bei %d Befehlen.\n",hist_size);
+    return 1;
+  }
+  hist_size=d;
+  printf("Deine History-Buffer-Laenge liegt jetzt bei %d Befehlen.\n",
+   hist_size);
+  reallocate_histbuf();
+  return 1;
+}
+
+static void initialize()
+{
+  if (!pointerp(history)||sizeof(history)!=hist_size)
+    reallocate_histbuf();
+  add_action("__auswerten","",1);
+    max_commands = EPMASTER->QueryCommands();
+    cmd_types = EPMASTER->QueryCmdTypes() || ({});
+
+    if ( !mappingp(aliases) )
+        aliases = ([]);
+
+    if ( !pointerp(commands) )
+        commands = ({});
+
+    if (QueryProp("_syntaxdb"))
+        syntaxdb = ({find_object("/secure/syntaxdb")});
+/*    else if (QueryProp(P_TESTPLAYER))
+    {
+      SetProp("_syntaxdb", 1);
+      call_out(#'_notify, 2,
+          "\nDa Du als Testspieler markiert bist, wurde bei Dir "
+          "die Syntaxsammlung eingeschaltet. Du kannst dies "
+          "wieder ausschalten. (hilfe syntaxsammlung) "
+          "Es waere schoen, wenn Du es beim Testen von "
+          "Gebieten einschaltest.", 0);
+    }*/
+}
+
+static mixed _set_default_notify_fail(string s)
+{
+  if (stringp(s)&&s!="")
+  {
+    if (s[<1]!='\n') s+="\n";
+    return default_notify_fail=s;
+  }
+  else if (!s||s=="")
+    return (default_notify_fail=0);
+}
+
+static mixed _query_default_notify_fail()
+{
+  return default_notify_fail;
+}
+
+static int set_errormessage(string s)
+{
+  if (!(s=_unparsed_args()))
+  {
+    _set_default_notify_fail(0);
+    write("Standard-Fehlermeldung auf \"Wie bitte?\" gesetzt.\n");
+  } else
+  {
+    write(break_string(sprintf("Standard-Fehlermeldung auf %s gesetzt.\n",
+             s),78));
+    _set_default_notify_fail(s);
+  }
+  return 1;
+}
+
+void reconnect()
+{
+  if (!mappingp(aliases)) aliases=([]);
+
+    if ( !pointerp(commands) )
+        commands = ({});
+
+    max_commands = EPMASTER->QueryCommands();
+    cmd_types = EPMASTER->QueryCmdTypes() || ({});
+}
+
+static int show_hist()
+{
+  int i;
+  string comm;
+
+  tell_object( ME, "Die History-Liste enthaelt folgende Kommandos:\n" );
+
+  for( i = 0; i < hist_size; i++ )
+      if ((comm=history[(hist_now+i)% hist_size])!= "\n\n")
+          tell_object( ME, " &"+(hist_now+i-hist_size)+"/-"+ (hist_size-i-1)
+      +"\t= "+comm+"\n");
+  return 1;
+}
+
+static string present_alias(mixed *ali)
+{
+  int j,k;
+  string s,s2;
+
+  for (s="",j=sizeof(ali)-1;j>=0;j--)
+    if (intp(ali[j]))
+      if ((k=ali[j])<0)
+  s="$"+(k==-1?"":(string)-k)+"*"+s;
+      else
+  s="$"+(string)k+s;
+    else
+      {
+         s2=implode(explode(ali[j],"\\"),"\\\\");
+         s=implode(explode(s2,"$"),"\\$")+s;
+      }
+  return s;
+}
+
+#define ALIFORMAT ({" %s\t= %s", "alias %s %s"})[display_as_aliascommand]
+// Ich weiss, den Variablennamen im define zu haben ist unfein, aber das
+// macht es im Code dann angenehm uebersichtlich.  -HrT
+
+static int query_aliases(int display_as_aliascommand)
+{
+  int i;
+  string *a,*ali;
+
+  if(i=sizeof(ali=sort_array(m_indices(aliases),#'<))) //')))
+  {
+    for(a=({}),i--; i>=0; i--)
+        a+=({sprintf(ALIFORMAT, ali[i], present_alias( aliases[ali[i]] ) ) });
+    More("Du hast folgende Aliase definiert:\n"+implode(a,"\n"));
+  }
+  else
+    write("Du hast keine Aliase definiert.\n");
+  return 1;
+}
+
+static int
+_starts_with(string str, string start)
+{
+  return (sizeof(start)>sizeof(str) ? 0
+    : str[0..sizeof(start)-1]==start);
+}
+
+static int alias(string str)
+{
+  string command;
+  string *tmp,um,*hits;
+  int num, l, pos, cont;
+  int display_as_aliascommand;
+
+  if (unmodified&&unmodified!="")
+    um=implode(old_explode(unmodified," ")[1..]," ");
+  if (um=="") um=0;
+  if(!(str=um||_unparsed_args()) || str=="*") return query_aliases(0);
+
+    if (str=="-a" || strstr(str, "-a ")==0 )  {
+    str=str[2..];
+    if (str && str!="" && str[0]==' ') str=str[1..];
+    if (!str || str=="" || str=="*") return query_aliases(1);
+    display_as_aliascommand=1;
+  }
+
+  if ((pos=member(str,' '))<0) // 1 Arg only
+  {
+    if ((tmp=aliases[str]))
+      printf(ALIFORMAT+"\n",str,present_alias(tmp));
+    else
+      if (str[<1]=='*')
+      {
+        str=str[0..<2];
+        hits=filter(m_indices(aliases), #'_starts_with, str);
+        if (!sizeof(hits))
+        {
+          printf("Du hast kein Alias, das mit \"%s\" anfaengt.\n", str);
+          return 1;
+        }
+        hits=sort_array(hits, #'>);
+        for (l=sizeof(hits); l--;)
+          hits[l]=sprintf(ALIFORMAT, hits[l], present_alias(aliases[hits[l]]));
+        More("Folgende Aliase beginnen mit \""+str+"\":\n"+implode(hits,"\n"));
+      }
+    else
+      printf("Du hast kein Alias \"%s\" definiert.\n",str);
+    return 1;
+  }
+  if (!pos)
+  {
+    write("Fehler: Blanc am Alias-Anfang\n");
+    return 1;
+  }
+  if ((command=str[0..pos-1])=="unalias")
+  {
+    write
+      ("Es nicht moeglich, den Befehl unalias zu ueberladen (waer dumm :))\n");
+    return 1;
+  }
+  if ((command=str[0..pos-1])=="*")
+  {
+    write
+      ("Es nicht moeglich, den Befehl \"*\" zu ueberladen.\n");
+    return 1;
+  }
+
+  str=str[pos+1..],tmp=({});
+  while (l=sizeof(str)) {
+    pos=0,cont=1;
+    while (cont) {
+      if (pos<l) {
+        if(str[pos]=='\\') {
+          str=str[0..pos-1]+str[pos+1..];
+          l--;
+        } else {
+          if (str[pos]=='&' || str[pos]=='$') {
+            cont=0;
+            if (pos>0) {
+              tmp+=({str[0..pos-1]});
+            }
+            if (pos==l-1) {
+              printf("Fehler: %c am Zeilenende\n",str[pos]);
+              return 1;
+            }
+            if ((num=str[++pos])=='*') {
+              num=1;
+              pos--;
+            } else {
+              num-='0';
+            }
+            if (num<0 || num>9) {
+              printf("Fehler: Nach %c muss Ziffer oder * folgen\n",
+               str[pos-1]);
+              return 1;
+            }
+            if ((str=str[pos+1..])!=""&&str[0]=='*') {
+              str=str[1..];
+              num=-num;
+            }
+            tmp+=({num});
+          }
+        }
+        pos++;
+      } else {
+        cont=0;
+        if (str!="") tmp+=({str});
+        str="";
+      }
+    }
+  }
+  if ((!aliases[command]) && (sizeof(aliases)>2000))
+    printf("Du hast schon genuegend Aliase definiert!\n");
+  else
+  {
+    aliases[command]=tmp;
+    printf("Neues Alias: %s\t= %s\n",command,present_alias(tmp));
+  }
+  return 1;
+}
+
+static int unalias(string str) {
+  int i;
+  string *als,um;
+
+  if (unmodified&&unmodified!="")
+    um=implode(old_explode(unmodified," ")[1..]," ");
+  if (um=="") um=0;
+  if ( !(str=um || _unparsed_args())) return 0;
+  if (str == "*.*" || str == "*") {
+    write(break_string(
+      "Versuchs mal mit 'unalias .*', wenn Du wirklich alle Alias entfernen "
+      "willst.",78));
+    return 1;
+  }
+  if (!member(aliases,str)) {
+    als=regexp(m_indices(aliases),("^"+str+"$"));
+    if (!(i=sizeof(als))) {
+      write("So ein Alias hast Du nicht definiert.\n");
+      return 1;
+    }
+    for (--i;i>=0;i--)
+      m_delete(aliases,als[i]);
+    write(break_string(("Du entfernst folgende Aliase: "+
+      implode(als," ")+".\n"),75));
+    return 1;
+  }
+  m_delete(aliases,str);
+  write("Du entfernst das Alias \""+str+"\".\n");
+  return 1;
+}
+
+varargs string _unparsed_args(int level)
+{
+  return unparsed_args[level];
+}
+
+#define ARTIKEL ({"das","der","die","des","dem","den","ein","eine","einer",\
+                  "eines"})
+
+#define TRENNER ({"in","aus","ueber","auf","unter","mit","durch","fuer",\
+                  "von","vom","im","aufs","ein","weg","zurueck"})
+
+static string _single_spaces(string str)
+{
+  return regreplace(str, "  *", " ", 1);
+}
+
+static mixed _return_args(string str)
+{
+  string *t,*t2,verb,s2;
+  int i,l,j,l2;
+
+  t=explode(trim(str,TRIM_BOTH)," ");
+  verb=t[0];
+  t = t[1..];
+  if (!sizeof(t))
+  {
+    unparsed_args[0]=unparsed_args[1]=unparsed_args[2]=0;
+    return str=verb;
+  }
+  else
+    str = unparsed_args[0] = implode(t, " ");
+
+  str=unparsed_args[1]=lower_case(_single_spaces(str));
+  t=regexplode(str,"\\<im\\>|\\<ins\\>");
+  for (i=1;i<sizeof(t);i+=2) t[i]="in";
+  t=regexplode(implode(t,""),"[\\,\\!\\:][\\,\\!\\:]*");
+  l=sizeof(t);
+  for(i=1;i<l;i+=2) t[i]="";
+  t=old_explode(implode(t,"")," ")-({""});
+  for (i=sizeof(t)-2;i>=0;i--)
+  {
+    if (member(ARTIKEL,t[i])>=0)
+      t=t[0..i-1]+t[i+1..];
+  }
+  unparsed_args[2]=implode(t," ");
+  t=regexplode((str=implode(t," ")),"[0-9][0-9]*\\.");
+  if ((l=sizeof(t))>2)
+  {
+    i=1;
+    while (i<l-1)
+    {
+      t[i]=" "+t[i][0..<2]+" ";
+      if ((l2=sizeof(t2=old_explode(t[i+1]," ")))<2)
+  t[i+1]+=t[i];
+      else
+      {
+  for (j=1;j<l2;j++)
+  {
+    if (member(TRENNER,t2[j])>=0)
+    {
+      t2[j-1]+=t[i];
+      l2=0;
+    }
+  }
+  if (!l2)
+    t[i+1]=implode(t2," ");
+  else
+    t[i+1]+=t[i];
+      }
+      t[i]="";
+      i+=2;
+    }
+    str=_single_spaces(verb+" "+implode(t," "));
+    if (str[<1]==' ') str=str[0..<2];
+  } else str=verb+(str==""?"":" "+str);
+  if (show_processing>2)
+    printf("-> {%s}\n",str);
+  return str;
+}
+
+static void decay_average()
+{
+  if (absolute_hb_count()-last_chg>14)
+  {
+    last_chg=absolute_hb_count()-last_chg;
+    if (last_chg>3000)
+      last_chg=absolute_hb_count(),cmds_per_time=0;
+    else
+    {
+      while (last_chg>14)
+  cmds_per_time=cmds_per_time*9/10, last_chg-=15;
+      last_chg=absolute_hb_count()-last_chg;
+    }
+  }
+}
+
+private void DelayPreparedSpells() {
+  mixed ps;
+
+  if (pointerp(ps=QueryProp(P_PREPARED_SPELL))
+      && sizeof(ps)>=1 && intp(ps[0])) {
+    ps[0]++;
+    SetProp(P_PREPARED_SPELL,ps);
+    write("Die Ausfuehrung Deines vorbereiteten Spruches wird verzoegert.\n");
+  } else if (ps) {
+    SetProp(P_PREPARED_SPELL,0);
+  }
+}
+
+static mixed bb;
+#ifndef BBMASTER
+#define BBMASTER "/secure/bbmaster"
+#endif
+
+/** Interpretiert Aliase und History-Kommandos
+  Eigentlich muesste hier noch die Umwandlung der Sonderzeichen
+  verschiedener Zeichensaetze mit convert_charset gemacht werden,
+  aber noch gibt es keine Moeglichkeit, den vom Spieler genutzten
+  Zeichensatz zu identifizieren.
+  \param[in] str string - Kommando des Spielers
+  \return interpretiertes Alias bzw. korrektes Kommando aus der History
+*/
+private string parsecommand(string str)
+{
+  if (str[0]=='\\')
+  {
+    // Kommando soll nicht interpretiert werden
+    return str[1..];
+  }
+  else if (str[0]=='&')
+  {
+    // Kommando aus der History
+    string cmd = str[1..];
+    int cmd_size = sizeof(cmd);
+    int cmd_found = 0;
+    if (cmd_size)
+    {
+      // Test ob &<text> etwas findet
+      for (int i=0;i<hist_size-1 && !cmd_found;i++)
+      {
+        int idx = (hist_size-i+hist_now-1)%hist_size;
+        if (history[idx][0..cmd_size-1]==cmd)
+        {
+          str = history[idx];
+          cmd_found = 1;
+        }
+        if (cmd_found)
+        {
+          if (show_processing)
+            printf("[%s]\n",str);
+        }
+      }
+    }
+    if (!cmd_found)
+    {
+      // Test, ob &<nr> klappt
+      int nummer;
+      if (str=="&&")
+        str = "&-0";
+      if (sscanf(str,"&%d",nummer))
+      {
+        if (nummer<0 || (!nummer && str[1]=='-'))
+        {
+          if (nummer<-(hist_size-1))
+            nummer=-1;
+          else
+            nummer=(hist_now+nummer-1+hist_size)%hist_size;
+        }
+        else
+        {
+          if (nummer>hist_now || hist_now-nummer>hist_size)
+            nummer=-1;
+          else
+            nummer=nummer%hist_size;
+        }
+        if (nummer<0 
+            || ( (cmd=history[nummer]) =="\n\n") )
+          notify_fail("Der Befehl ist nicht in der History!\n");
+        else
+        {
+          str = cmd;
+          if (show_processing)
+            printf("[%s]\n",str);
+        }
+      }
+    }
+  }
+  switch (str)
+  {
+    case "n": return "norden";
+    case "s": return "sueden";
+    case "w": return "westen";
+    case "o": return "osten";
+    case "nw": return "nordwesten";
+    case "sw": return "suedwesten";
+    case "so": return "suedosten";
+    case "no": return "nordosten";
+    case "ob": return "oben";
+    case "u": return "unten";
+  }
+  // Test auf Alias
+  string output = "";
+  string* input = explode(str," ");
+  int input_size = sizeof(input);
+  mixed alias = aliases[input[0]];
+  if (!alias)
+    return str;
+  foreach (mixed a:alias)
+  {
+    if (!intp(a))
+      output += a;
+    else
+    {
+      if (a >= 0)
+      {
+        if (input_size > a)
+          output += input[a];
+      }
+      else
+      {
+        a = -a;
+        if (input_size > a)
+          output += implode(input[a..]," ");
+      }
+    }
+  }
+  output = _single_spaces(output);
+  str = trim(output,TRIM_RIGHT);
+  if (show_processing>1)
+    printf("[%s]\n",str);
+  return str;
+}
+
+/** Behandelt alle Sonderfaelle der Eingabe des Spielers
+  Alle Befehle des Spielers, die nicht durch Objekte behandelt
+  werden sollen, werden hier erkannt und ausgefuehrt.
+  Dazu gehoert auch die Interpretation von Aliases und History-
+  befehlen.
+  \param[in] str string: Kommando des Spielers
+  \return auszufuehrendes Kommando
+    oder 0 fuer ein nicht interpretierbares Kommando
+    oder 1 fuer ein bereits durchgefuehrtes Kommando
+*/
+mixed modify_command(string str)
+{
+
+  if (extern_call() && previous_object() &&
+      (previous_object()!=this_object() || process_call()) )
+  {
+    return 0;
+  }
+
+  // Leerzeichen an den Enden abschneiden.
+  str = trim(str, TRIM_BOTH);
+
+  if (bb)
+    BBMASTER->BBWrite(trim(str,TRIM_RIGHT,"\n"), 0);
+
+  decay_average();
+  cmds_per_time+=10000;
+
+  unparsed_args[0]=unparsed_args[1]=unparsed_args[2]=unmodified=""; 
+
+  if (!sizeof(str)) return "";
+
+  // Kommando wird geparst
+  unmodified=parsecommand(str);
+
+  // Environment schonmal merken.
+  last_command_env=environment();
+
+  if (unmodified == "")
+      return "";
+  // Kommando in History merken, auch wenn es im Kommandoblock abgebrochen
+  // wird.
+  AddHistory(unmodified);
+
+  // pruefen, ob Kommandoblock gesetzt ist.
+  // (Fuer Magier mit mschau ein wird das ignoriert.)
+  // BTW: Es wird absichtlich nicht das Ergebnis der Closure zurueckgegeben,
+  // sonst wuerde man beliebigen Objekten nicht nur das Abbrechen, sondern
+  // auch das Aendern von Kommandos ermoeglichen.
+  if (disablecommands && !IS_LEARNING(ME) )
+  {
+    if (disablecommands[B_TIME] >= time()
+      && objectp(disablecommands[B_OBJECT]))
+    {
+      // disablecommands valid
+      // hart-kodierte Ausnameliste pruefen
+      if ( member(({"mrufe","mschau","bug","idee","typo","detail"}),
+            explode(str," ")[0]) == -1)
+      {
+        if (closurep(disablecommands[B_VALUE]))
+        {
+          if (funcall(disablecommands[B_VALUE],_return_args(unmodified)))
+          {
+            // Non-zero Closure-Ergebnis, Abbruch. Die gerufene Funktion ist
+            // fuer eine geeignete Meldung an den Spieler verantwortlich.
+            return 1;
+          }
+        }
+        // wenn Text, dann auch pruefen, ob das Kommandoverb in den Ausnahmen
+        // steht. (query_verb() geht leider hier noch nicht.)
+        else if (stringp(disablecommands[B_VALUE])
+                 && member(disablecommands[B_EXCEPTIONS],
+                           explode(str," ")[0]) == -1)
+        {
+          // meldung ausgeben...
+          tell_object(PL, disablecommands[B_VALUE]);
+          // und Ende...
+          return 1;
+        }
+      }
+    }
+    else disablecommands=0;
+  }
+
+  // Verfolger direkt ins Env reinholen.
+  if (remove_call_out("TakeFollowers")>=0)
+    catch(TakeFollowers();publish);
+
+  DelayPreparedSpells();
+
+  // Historyeintrag korrigieren
+  if (unmodified[0]=='^')
+  {
+    string *oldnew,pre,post;
+    if (sizeof(oldnew=explode(unmodified,"^"))>2)
+    {
+      int hist_idx = (hist_now-1)%hist_size;
+      sscanf(history[hist_idx],"%s"+oldnew[1]+"%s", pre, post);
+      unmodified = pre+oldnew[2]+post;
+      if (show_processing)
+        write("["+unmodified+"]\n");
+      // korrigiertes Kommando natuerlich auch in die History.
+      AddHistory(unmodified);
+    }
+  }
+
+  if( bb )
+    BBMASTER->BBWrite(" -> " + unmodified, 1);
+
+  if (show_processing>1)
+    printf("[%s]\n",unmodified);
+
+  mixed ret = _return_args(unmodified);
+
+  // wenn Spieler eingewilligt hat und die SyntaxDB geladen ist, Befehl
+  // dorthin melden.
+  if (syntaxdb)
+  {
+    if (!objectp(syntaxdb[0]))
+      syntaxdb[0] = find_object("/secure/syntaxdb");
+    if (syntaxdb[0])
+      catch(syntaxdb[0]->start_cmd(unmodified);nolog);
+  }
+  return ret;
+}
+
+static int do_list(string str)
+{
+  string *cmdlist;
+  int i;
+
+  if (!QueryProp(P_WANTS_TO_LEARN))
+    return 0;
+  cmdlist=old_explode(_unparsed_args()||"",";")-({ "" });
+  for (i=0;i<sizeof(cmdlist);i++)
+  {
+    cmdlist[i]=implode(old_explode(cmdlist[i]," ")-({}), " ");
+    if (show_processing)
+      write("["+cmdlist[i]+"]\n");
+    command(cmdlist[i]);
+  }
+  return 1;
+}
+
+//falls die aliasliste kaputt ist ...
+
+int unalias_all()
+{
+  if (IS_ELDER(this_interactive())) aliases=([]);
+  return 1;
+}
+
+object _query_last_command_env()
+{
+  return last_command_env;
+}
+
+int _query_show_alias_processing()
+{
+  return show_processing;
+}
+
+int _query_histmin()
+{
+  return histmin;
+}
+
+varargs void AddAction(mixed fun, mixed cmd, int flag, int lvl)
+{
+  int i;
+  mixed *cmds;
+
+  log_file( "ARCH/ADD_ACTION", sprintf(
+	"%s:\n  TO: %O TP: %O PO: %O\n   fun: %O cmd: %O flag: %O lvl: %O",
+        dtime(time()), this_object(), this_player(), previous_object(),
+	fun, cmd, flag, lvl));
+
+  if (!(cmds=Query(P_LOCALCMDS))) cmds=({});
+
+  if (!pointerp(cmd)) cmd=({cmd});
+
+  for (i = sizeof(cmd)-1; i>=0; i--)
+    cmds += ({({ cmd[i] , fun, flag, lvl})});
+
+  Set(P_LOCALCMDS, cmds);
+}
+
+static int auswerten(mixed cmd, string str)
+{
+  if (closurep(cmd))
+    return funcall(cmd,str);
+  if (stringp(cmd))
+    return call_other(this_object(),cmd,str);
+  return 0;
+}
+
+static varargs int __auswerten(string str, string intern)
+{
+  string verb;
+  mixed *cmd, cmds;
+  int i,ret,lvl,l,vl;
+
+  if (!intern)
+    verb=query_verb();
+  else
+    verb=intern;
+  lvl=query_wiz_level(ME);
+  vl=sizeof(verb);
+  cmds=QueryProp(P_LOCALCMDS);
+
+  for(i=sizeof(cmds)-1;i>=0;i--)
+  {
+    cmd=cmds[i],l=sizeof(cmd[0]);
+    if (cmd[0]==verb[0..l-1] && cmd[3]<=lvl && (cmd[2]||vl==l) &&
+  (ret=auswerten(cmd[1],str)))
+      return ret;
+  }
+  // An dieser Stelle gibt es hier und vermutlich nirgendwo anders etwas, was
+  // dieses Kommando als gueltig betrachtet. Wir informieren ggf. die
+  // Syntax-DB. (Achtung: wenn jemand ne add_action() im Spielerobjekt
+  // einbaut, die vor dieser eingetragen wird, ist die Annahme ggf. falsch.)
+  // wenn Spieler eingewilligt hat und die SyntaxDB geladen ist, Befehl
+  // dorthin melden.
+  if (syntaxdb)
+  {
+    if (!objectp(syntaxdb[0]))
+      syntaxdb[0] = find_object("/secure/syntaxdb");
+    if (syntaxdb[0])
+      catch(syntaxdb[0]->cmd_unsuccessful();nolog);
+  }
+
+  return 0;
+}
+
+public void syntax_log_ep(int type)
+{
+  // wenn Spieler eingewilligt hat und die SyntaxDB geladen ist, Befehl
+  // dorthin melden.
+  if (syntaxdb && syntaxdb[0])
+  {
+      catch(syntaxdb[0]->LogEP(type);nolog);
+  }
+}
+
+static mixed _query_localcmds()
+{
+  mixed *l;
+
+  l=Query(P_LOCALCMDS);
+  if (!pointerp(l))
+    l=({});
+  return ({
+    ({"ali","alias",0,0}),
+    ({"alias","alias",0,0}),
+    ({"unali","unalias",1,0}),
+    ({"histmin","histmin",0,0}),
+    ({"histlen","histlen",0,0}),
+    ({"hist","show_hist",0,0}),
+    ({"history","show_hist",0,0}),
+    ({"do","do_list",0,LEARNER_LVL}),
+    ({"ersetzungsanzeige","replacedisplay",0,0}),
+    ({"syntaxsammlung","collect_cmds",0,0}),
+    ({"fehlermeldung","set_errormessage",0,SEER_LVL}),
+  })+l;
+}
+
+static int collect_cmds(string cmd)
+{
+  if (!stringp(cmd))
+  {
+    _notify("Mit diesem Befehl kannst Du mithelfen, Syntaxen im MG zu "
+            "verbessern. Wenn Du einverstanden bist, speichern wir "
+            "anonym (d.h. ohne Deinen Charnamen), welche Deiner Befehle "
+            "erfolgreich und nicht erfolgreich waren. Uebliche "
+            "Kommunikationsbefehle werden dabei nicht gespeichert.",
+            0);
+    _notify("Mit 'syntaxsammlung ja' kannst Du die Speicherung einschalten, "
+            "mit 'syntaxsammlung nein' kannst Du sie ausschalten.",0);
+    _notify("Deine Befehle werden zur Zeit"
+            + (QueryProp("_syntaxdb") ? " " : " NICHT ")
+            + "gespeichert.", 0);
+  }
+  else if (cmd == "ja")
+  {
+    SetProp("_syntaxdb", 1);
+    _notify("Ab jetzt werden Deine Befehle gespeichert. Vielen Dank!", 0);
+  }
+  else
+  {
+    SetProp("_syntaxdb", 0);
+    _notify("Ab jetzt werden Deine Befehle NICHT gespeichert.", 0);
+  }
+  return 1;
+}
+
+int _query_command_average()
+{
+  decay_average();
+  return cmds_per_time;
+}
+
+nomask void __set_bb(int flag)  {
+  if( previous_object()!=find_object(BBMASTER) || process_call() )
+    return;
+  bb=flag;
+}
+
+
+nomask public void countCmds( int type, string key )
+{
+    string tmp;
+
+    if ( this_player() != this_interactive()
+         || this_interactive() != this_object()
+         || member( cmd_types, type ) < 0 )
+        return;
+
+    tmp = sprintf( "%d\n%s", type, key );
+
+    commands -= ({ tmp });
+    commands += ({ tmp });
+    commands = commands[0..max_commands-1];
+}
+
+
+nomask public string *getCmds()
+{
+    string *tmp;
+
+    if ( previous_object() != find_object(BBMASTER) )
+        return ({});
+
+    tmp = commands;
+    commands = ({});
+
+    return tmp;
+}
+
+/*
+ * Force the monster to do a command. The force_us() function isn't
+ * always good, because it checks the level of the caller, and this function
+ * can be called by a room.
+ */
+int command_me(string cmd)
+{
+  if (IS_LEARNER(ME))
+  {
+    if (!this_interactive() || !previous_object())
+      return 0;
+    if( geteuid(ME)!=geteuid(this_interactive())
+        || geteuid(ME)!=geteuid(previous_object()) )
+    {
+      if( query_wiz_level(ME)<query_wiz_level(previous_object()))
+        tell_object(ME,previous_object()->name()+" zwingt Dich zu: "
+                    + cmd + ".\n");
+      else
+      {
+        tell_object(ME,previous_object()->name()
+                    + " versucht, Dich zu " + cmd + " zu zwingen.\n" );
+        return 0;
+      }
+    }
+  }
+  return command(cmd);
+}
+
+
+static mixed _query_p_lib_disablecommands() {
+    // abgelaufen oder Objekt zerstoert? Weg damit.
+    if (pointerp(disablecommands)
+        && (disablecommands[B_TIME] < time()
+          || !objectp(disablecommands[B_OBJECT])) )
+        return(disablecommands = 0);
+
+    // sonst Kopie zurueck (copy(0) geht)
+    return(copy(disablecommands));
+}
+
+static mixed _set_p_lib_disablecommands(mixed data) {
+
+  // setzendes Objekt ermitteln, da diese Funktion nur per SetProp() gerufen
+  // werden sollte (!), ist das PO(1);
+  object origin = previous_object(1);
+  // wenn nicht existent, direkt abbruch
+  if (!objectp(origin))
+    return _query_p_lib_disablecommands();
+
+  // Prop loeschen? Explizit loeschen darf jeder, allerdings nicht direkt
+  // ungeprueft ueberschreiben.
+  if (!data) {
+      return (disablecommands = 0 );
+  }
+  // mal direkt buggen bei falschen Datentyp, damits auffaellt.
+  if (!pointerp(data) || sizeof(data) < 2 || !intp(data[0])
+      || (!stringp(data[1]) && !closurep(data[1]))
+      || (sizeof(data) >= 3 && !pointerp(data[2])) )
+      raise_error(sprintf(
+            "Wrong data type for P_DISABLE_COMMANDS. Expected Array with "
+            "2 or 3 elements (int, string|closure, [string*]), got %.25O\n",
+            data));
+
+  // Wenn abgelaufen oder gleiches Objekt wie letztes Mal: eintragen.
+  if (!disablecommands || (disablecommands[B_TIME] < time()
+        || !objectp(disablecommands[B_OBJECT]) 
+        || disablecommands[B_OBJECT] == origin) ) {
+      // Loggen nur, wenn eine Closure eingetragen wird. Reduziert den
+      // Logscroll und Strings haben deutlich weniger Missbrauchspotential.
+      if (closurep(data[1])) {
+        CBLOG(sprintf("[%s] CB gesetzt von %O, gueltig bis %s, Daten: %O\n",
+        strftime("%Y%m%d-%H:%M:%S"),origin,
+        strftime("%Y%m%d-%H:%M:%S",data[0]),
+        (stringp(data[1]) ? regreplace(data[1],"\n","\\n",0)
+                          : data[1])));
+      }
+      if (sizeof(data)+1 <= B_EXCEPTIONS)
+        disablecommands = ({ origin, data[0], data[1], ({}) });
+      else
+        disablecommands = ({ origin, data[0], data[1], data[2] });
+      return(copy(disablecommands));
+  }
+
+  return(_query_p_lib_disablecommands());
+}
+
+static mixed _set__syntaxdb(mixed v)
+{
+  Set("_syntaxdb", v, F_VALUE);
+  if (v)
+      syntaxdb = ({find_object("/secure/syntaxdb")});
+  else
+      syntaxdb = 0;
+  return QueryProp("_syntaxdb");
+}
+
