// MorgenGrauen MUDlib
//
// player/comm.c-- basic player communiction commands
//
// $Id: comm.c 9576 2016-06-18 15:00:01Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma no_clone
//#pragma range_check

inherit "/std/living/comm";
inherit "/std/player/channel";
inherit "/std/player/comm_structs";

#include <input_to.h>

#define NEED_PROTOTYPES
#include <player/quest.h>
#include <player/gmcp.h>
#include <living/description.h>
#include <player/comm.h>
#undef NEED_PROTOTYPES

#include <sys_debug.h>

#include <thing/properties.h>
#include <player/base.h>

#include <properties.h>
#include <config.h>
#include <ansi.h>
#include <wizlevels.h>
#include <language.h>
#include <udp.h>
#include <defines.h>
#include <daemon.h>
#include <strings.h>
#include <regexp.h>
#include <interactive_info.h>
#include <ansi.h>
#include <assert.h>

#define TELLHIST_DISABLED   0
#define TELLHIST_NO_MESSAGE 1
#define TELLHIST_ENABLED    2
#define TELLHIST_LONGLIFE   3

#define ECHO_COST 50
#define ERWIDER_PARAM ","

#define ZDEBUG(x)  if (find_player("zesstra"))\
              efun::tell_object(find_player("zesstra"),"CommDBG: "+x+"\n")

private int tell_history_enabled = TELLHIST_NO_MESSAGE;
private nosave mapping tell_history=([]);
private nosave string *commreceivers = ({});
private nosave string last_comm_partner;
private nosave int last_beep_time;

// Statusreporte aktiviert? Binaere Flags (s. set_report())
private int stat_reports;
// interner Cache fuer die LP/KP/Gift-Werte fuer die Statusreport-Ausgaben
// Eintraege (in dieser Reihenfolge): P_HP, P_SP, Giftstatus
// Initialisierung erfolgt beim ersten Report nach Login
private nosave mixed *report_cache;

// Puffer fuer Kobold.
private nosave struct kobold_buffer_s kobold = (<kobold_buffer_s>
                                             buf: allocate(32),
                                             index: -1,);
// Vault fuer Offline-TMs
// Der KOBOLD (/secure/kobold) muss immer eine Referenz auf dieses Objekt
// halten.
private nosave lwobject "/std/player/comm_vault" commvault;

// Colourmap
// TODO: spaeter konfigurierbar machen
private mapping build_colourmap(string ttype="ansi");
private nosave mapping colourmap = build_colourmap();

varargs string name(int casus, int demonst);

//local property prototypes
static int _query_intermud();
public int RemoveIgnore(string ign);
public int AddIgnore(string ign);

public varargs int ReceiveMsg(string msg, int msg_type, string msg_action,
                              string msg_prefix, object origin);
private int check_ignores(string msg, int msg_type, string msg_action,
                            string msg_prefix, object|string origin);
private varargs void add_struct_tell_history(struct kobold_msg_s msg,
                                         int sent, int recv, int flags );

// erzeugt sortierte Liste an Kommunikationspartnern
private string *sorted_commpartners(int reversed);

protected void create()
{
  ::create();
  Set(P_ALERT, SAVE, F_MODE_AS);
  SetProp(P_ALERT, MB_TELL|MB_MENTION|MB_MISC);
  Set(P_EARMUFFS, 0);
  Set(P_EARMUFFS, SAVE, F_MODE);
  Set(P_EARMUFFS, SECURED, F_MODE);
  Set(P_INTERMUD, SAVE, F_MODE);
  Set(P_IGNORE, ([]), F_VALUE);
  Set(P_IGNORE, SAVE, F_MODE);
  Set(P_BUFFER, SAVE, F_MODE);
  SetProp(P_BUFFER, KOBOLD_OFFLINE);
  Set(P_MESSAGE_PREPEND, SAVE, F_MODE_AS);
  Set(P_MESSAGE_BEEP, SAVE, F_MODE_AS);
}

void create_super()
{
  set_next_reset(-1);
}

private mapping build_colourmap(string ttype)
{
  mapping res = ([0:""]);
  switch(ttype)
  {
    case "dumb":
      return res;
    case "ansi":
      res = ([ 0:ANSI_NORMAL, "normal": ANSI_NORMAL,
               "bold": ANSI_BOLD, "underlined": ANSI_UNDERL,
               "blink": ANSI_BLINK, "invers": ANSI_INVERS,
               "black": ANSI_BLACK, "red": ANSI_RED,
               "green": ANSI_GREEN, "yellow": ANSI_YELLOW,
               "blue": ANSI_BLUE, "purple": ANSI_PURPLE,
               "cyan": ANSI_CYAN, "white": ANSI_WHITE,
               "bg_black": ANSI_BG_BLACK, "bg_red": ANSI_BG_RED,
               "bg_green": ANSI_BG_GREEN, "bg_yellow": ANSI_BG_YELLOW,
               "bg_blue": ANSI_BG_BLUE, "bg_purple": ANSI_BG_PURPLE,
               "bg_cyan": ANSI_BG_CYAN, "bg_white": ANSI_BG_WHITE,
               "mention": ANSI_BOLD+ANSI_BG_BLUE,
             ]);
      break;
    case "vt100":
      res += ([0:ANSI_NORMAL, "normal": ANSI_NORMAL,
               "bold": ANSI_BOLD, "underlined": ANSI_UNDERL,
               "blink": ANSI_BLINK, "invers": ANSI_INVERS,
               "mention": ANSI_BOLD,
              ]);
      break;
    default:
       assert(1, "Ungueltiger Terminaltyp in build_colourmap");
  }
  return res;
}

protected void set_colourmap(string ttype="ansi")
{
  colourmap = build_colourmap(ttype);
}

private void setup_comm_vault()
{
  if (!commvault && (QueryProp(P_BUFFER) & KOBOLD_OFFLINE))
  {
    // Schauen, ob ein Vault im KOBOLD existiert.
    commvault = KOBOLD->RetrieveVault();
    // Wenn nicht, aber eins gewuenscht ist, wird eins erstellt und in KOBOLD
    // hinterlegt.
    if (!commvault)
    {
      commvault = new_lwobject("/std/player/comm_vault");
      KOBOLD->DepositVault(commvault);
    }
  }
}

static int set_report(string str)
{
  int canflags = QueryProp(P_CAN_FLAGS);
  if(!str)
  {
    if (stat_reports)
    {
      string *res=({});
      if (stat_reports & DO_REPORT_HP)
        res+=({"Lebenspunkte"});
      if (stat_reports & DO_REPORT_SP)
        res+=({"Konzentrationspunkte"});
      if (stat_reports & DO_REPORT_POISON)
        res+=({"Vergiftungen"});
      if (stat_reports & DO_REPORT_WIMPY)
        res+=({"Vorsicht"});

      tell_object(ME,break_string(
        "Dir werden jetzt Veraenderungen Deiner "
        +CountUp(res) + " berichtet.",78));
      if (GMCP_Status("MG.char") || GMCP_Status("char")
          || GMCP_Status("Char"))
      {
        tell_object(ME,break_string(
            "Achtung: Dein Client laesst sich den Report per GMCP "
            "(s. 'hilfe GMCP') uebermitteln. Daher wird er Dir nicht "
            "in der Textausgabe des Spiels angezeigt! Moechtest Du "
            "dies nicht, schalte bitte in Deinem Client GMCP-Module mit "
            "Namen wie 'MG.char', 'char', 'Char' oder aehnliche aus."));
      }
    }
    else
      tell_object(ME,
        "Alle Statusreports sind ausgeschaltet.\n");

    return 1;
  }
  else if (str == "aus")
  {
    if (stat_reports & DO_REPORT_HP || stat_reports & DO_REPORT_WIMPY)
    {
      string s="";
      if (stat_reports & DO_REPORT_HP)
      {
        str="ebenfalls ";
        tell_object(ME, "Der Report wurde ausgeschaltet.\n");
      }
      if ( stat_reports & DO_REPORT_WIMPY )
      {
        tell_object(ME, "Der Vorsicht-Report wurde "+s+
          "ausgeschaltet.\n");
      }
      stat_reports=0;
    }
    else
    {
      tell_object(ME, "Der Report ist bereits ausgeschaltet.\n");
    }
    return 1;
  }
  else if (str == "ein")
  {
    if ( stat_reports & DO_REPORT_HP )
    {
      tell_object(ME, "Der Report ist bereits eingeschaltet.\n");
      return 1;
    }
    tell_object(ME, "Der Report wurde eingeschaltet.\n");
    stat_reports |= DO_REPORT_HP;
    if (!(canflags & CAN_REPORT_SP))
    {
      if (QueryQuest("Hilf den Gnarfen")==1)
      {
        SetProp(P_CAN_FLAGS, canflags | CAN_REPORT_SP);
        stat_reports |= DO_REPORT_SP;
      }
      else
      {
        tell_object(ME, break_string(
          "Fuer den Statusreport Deiner Konzentration musst Du jedoch "
          "zunaechst die Quest \"Hilf den Gnarfen\" bestehen.",78));
      }
    }
    else
    {
      stat_reports |= DO_REPORT_SP;
    }
    if (!(canflags & CAN_REPORT_POISON))
    {
      if (QueryQuest("Katzenjammer")==1)
      {
        SetProp(P_CAN_FLAGS, canflags | CAN_REPORT_POISON);
        stat_reports |= DO_REPORT_POISON;
      }
      else
      {
        tell_object(ME, break_string(
          "Fuer den Statusreport Deiner Vergiftung musst Du jedoch "
          "zunaechst die Quest \"Katzenjammer\" bestehen.",78));
      }
    }
    else
    {
      stat_reports |= DO_REPORT_POISON;
    }
    // Cache loeschen, damit beim naechsten Report-Event alle Daten neu
    // eingetragen werden muessen. Muss beim Einschalten des Reports
    // passieren, weil auch in der inaktiven Zeit weiterhin Aenderungen in
    // status_report() eingehen, so dass der Cache zwar erst einmal leer ist,
    // aber beim Wiedereinschalten nicht mehr ungueltig waere und somit
    // veraltete Daten an den Spieler ausgegeben werden. Im unguenstigsten
    // Fall wuerde das sogar dazu fuehren, dass die veralteten Daten lange
    // Zeit nicht aktualisiert werden, wenn z.B. P_HP == P_MAX_HP, so dass
    // kein P_HP-Event mehr eingeht.
    report_cache=0;
    // Fall-through fuer Statusausgabe
  }
  else if (str == "vorsicht")
  {
    if (!(canflags & CAN_REPORT_WIMPY))
    {
      if (QueryQuest("Schrat kann nicht einschlafen")==1)
      {
        SetProp(P_CAN_FLAGS, canflags | CAN_REPORT_WIMPY);
        tell_object(ME, "Der Vorsicht-Report wurde eingeschaltet.\n");
        stat_reports |= DO_REPORT_WIMPY;
      }
      else
      {
        tell_object(ME, break_string(
          "Fuer den Statusreport Deiner Vorsicht musst Du "
          "zunaechst die Quest \"Schrat kann nicht einschlafen\" "
          "bestehen.",78));
      }
    }
    else
    {
      stat_reports |= DO_REPORT_WIMPY;
    }
    // fuer Seher auch Bericht der Fluchtrichtung einschalten.
    if ((stat_reports & DO_REPORT_WIMPY)
        && !(stat_reports & DO_REPORT_WIMPY_DIR)
        && ((canflags & CAN_REPORT_WIMPY) || IS_SEER(ME)))
    {
      stat_reports |= DO_REPORT_WIMPY_DIR;
    }
    // Fall-through fuer Statusausgabe
  }
  // sendet einmalig genau jetzt den konfigurierten report. Kann zum testen
  // (von Triggern) oder beim Login benutzt werden, wenn man einen initialen
  // Datenbestand erhalten will.
  else if (str=="senden")
  {
    // Es wird Ausgabe von LP und Vorsicht getriggert, das sendet beide
    // Zeilen.
    status_report(DO_REPORT_HP, QueryProp(P_HP));
    status_report(DO_REPORT_WIMPY, QueryProp(P_WIMPY));
    return 1;
  }
  else 
    return 0;
  // nur aktuellen Zustand berichten
  set_report(0);
  return 1;
}

private string get_poison_desc(int p) {
  string ret;
  if ( intp(p) ) {
    switch(p) {
      case 0:    ret="keins";       break;
      case 1..3: ret="leicht";      break;
      case 4..8: ret="gefaehrlich"; break;
      default:   ret="sehr ernst";  break;
    }
    return ret;
  }
  else return "(nicht verfuegbar)";
}

// sprintf()-Formatstrings fuer die Reportausgabe.
#define REPORTLINE "LP: %3d, KP: %3s, Gift: %s.\n"
#define REPORTLINE_WIMPY "Vorsicht: %d, Fluchtrichtung: %s.\n"
// Defines zur Adressierung der Cache-Eintraege
#define REP_HP     0
#define REP_SP     1
#define REP_POISON 2

protected void status_report(int type, mixed val) {
  // Wenn der Spieler GMCP hat und das sich um die Information kuemmert,
  // erfolgt keine textuelle Ausgabe mehr. Daher return, wenn GMCP_Char()
  // erfolg vermeldet hat.
  int flags = QueryProp(P_CAN_FLAGS);
  switch (type) {
    case DO_REPORT_HP:
      if (GMCP_Char( ([ P_HP: val ]) ) ) return;
      break;
    case DO_REPORT_SP:
      if (!(flags & CAN_REPORT_SP)) return;
      if (GMCP_Char( ([ P_SP: val ]) ) ) return;
      break;
    case DO_REPORT_POISON:
       if (!(flags & CAN_REPORT_POISON)) return;
       if (GMCP_Char( ([ P_POISON: val ]) ) ) return;
      break;
    case DO_REPORT_WIMPY:
      if (!(flags & CAN_REPORT_WIMPY)) return;
      if (GMCP_Char( ([ P_WIMPY: val ]) ) ) return;
      break;
    case DO_REPORT_WIMPY_DIR:
      if (!(flags & CAN_REPORT_WIMPY_DIR)) return;
      if (GMCP_Char( ([ P_WIMPY_DIRECTION: val ]) ) ) return;
      break;
  }

  // konventionelle textuelle Ausgabe des Reports ab hier.
  if (!(type & stat_reports))
    return;

  if ( !report_cache ) {
    report_cache = ({
      QueryProp(P_HP),
      (stat_reports&DO_REPORT_SP) ? to_string(QueryProp(P_SP)) : "###",
      (stat_reports&DO_REPORT_POISON) ?
          get_poison_desc(QueryProp(P_POISON)) : "(nicht verfuegbar)"
    });
  }

  switch(type) {
      // LP berichten: Cache aktualisieren und Meldung ausgeben.
      case DO_REPORT_HP:
        report_cache[REP_HP]=val;
        tell_object(ME, sprintf(REPORTLINE, report_cache[REP_HP],
          report_cache[REP_SP], report_cache[REP_POISON]));
        break;
      // KP berichten: Wenn der Spieler den Report freigeschaltet hat,
      // wird bei Aenderungen gemeldet. Wenn nicht, aendert sich nur der
      // Cache-Eintrag. So wird verhindert, dass ein Spieler ueber KP-
      // Veraenderungen auch dann informiert wuerde, wenn er den KP-Report
      // gar nicht benutzen koennte.
      case DO_REPORT_SP:
        report_cache[REP_SP]=to_string(val);
        tell_object(ME, sprintf(REPORTLINE, report_cache[REP_HP],
          report_cache[REP_SP], report_cache[REP_POISON]));
        break;
      // Giftstatus berichten: Wenn der Giftreport freigeschaltet ist,
      // Cache aktualisieren und berichten. Wenn nicht, aendert sich nur
      // der Cache-Eintrag. Erlaeuterung hierzu s.o. beim KP-Report.
      case DO_REPORT_POISON:
        report_cache[REP_POISON] = get_poison_desc(val);
        tell_object(ME, sprintf(REPORTLINE, report_cache[REP_HP],
          report_cache[REP_SP], report_cache[REP_POISON]));
        break;
      // Vorsicht-Report: kann ohne weitere Abfragen ausgegeben werden, da
      // alle noetigen Checks schon zu Beginn dieser Funktion erledigt wurden.
      // Lediglich der Inhalt der Meldung muss abhaengig vom Seherstatus
      // konfiguriert werden.
      case DO_REPORT_WIMPY:
        string res;
        if (IS_SEER(ME)) {
          // QueryProp() aus Kostengruenden im if(), damit die Aufruf-
          // Haeufigkeit zumindest ein wenig reduziert wird.
          string dir = QueryProp(P_WIMPY_DIRECTION)||"keine";
          res = sprintf(REPORTLINE_WIMPY, val, dir);
        }
        else
          res = sprintf(REPORTLINE_WIMPY, val, "(nicht verfuegbar)");
        tell_object(ME, res);
        break;
      // Fluchtrichtungs-Report: wird nur bei Sehern ausgegeben, damit
      // nicht auch Spieler eine VS-/FR-Meldung bekommen, wenn z.B. eine
      // externe Manipulation der Fluchtrichtung stattfindet, sie aber den
      // Report mangels Seherstatus gar nicht freigeschaltet haben.
      case DO_REPORT_WIMPY_DIR:
        if (IS_SEER(ME)) {
          if (!val) val = "keine";
          tell_object(ME,sprintf(REPORTLINE_WIMPY, QueryProp(P_WIMPY), val));
        }
        break;
  }
}

#undef REPORTLINE
#undef REPORTLINE_WIMPY
#undef REP_HP
#undef REP_SP
#undef REP_POISON

private string permutate(string msg)
{
  // Kontrollzeichen rausfiltern. *seufz*
  msg = regreplace(msg,"[[:cntrl:]]","",RE_PCRE|RE_GLOBAL);
  object ob=QueryProp(P_PERM_STRING);
  if (!objectp(ob))
    return msg;

  return ({string})ob->permutate_string(msg)||"";
}

// neue nachricht an den Kobold anhaengen
// Rueckgabewerte: MSG_BUFFER_FULL oder MSG_BUFFERED
private int add_to_kobold(string msg, int msg_type, string msg_action,
                          string msg_prefix, object origin)
{
  // Nachricht soll im Kobold gespeichert werden.
  // Kobold speichert Rohdaten und gibt spaeter das ganze auch wieder via
  // ReceiveMsg() aus - dabei wird MSG_DONT_BUFFER | MSG_DONT_STORE gesetz,
  // damit keine erneute Speicher in Kobold oder Komm-History erfolgt.

  // wenn der Puffer zu klein ist, Groesse verdoppeln, wenn noch unterhalb
  // des Limits.
  if (kobold->index >= sizeof(kobold->buf)-1) {
    if (sizeof(kobold->buf) < MAX_KOBOLD_LIMIT)
      kobold->buf += allocate(sizeof(kobold->buf));
    else
      return MSG_BUFFER_FULL;
  }
  kobold->index = kobold->index +1;
  // neue Nachricht an den Puffer anhaengen.
  string sendername = query_once_interactive(origin) ?
                      origin->query_real_name() :
                      origin->name(WER) || "<Unbekannt>";
  kobold->buf[kobold->index] = (<kobold_msg_s> msg: msg,
      type : msg_type, action : msg_action, prefix : msg_prefix,
      sendername : sendername);
  return MSG_BUFFERED;
}

// speichert den Inhalt vom commvault im Kobold und der TM-History
private void process_comm_vault(lwobject "/std/player/comm_vault" vault)
{
  struct kobold_msg_s *buffer = vault.Retrieve();
  if (!sizeof(buffer))
      return;
  foreach(struct kobold_msg_s msg: buffer)
  {
    // Spieler-definiertes Ignoriere? (nur typen uebergeben, keine Flags)
    int res = check_ignores(msg.msg, msg.type, msg.action, msg.prefix,
                            msg.sendername);
    if (res) {
        // Nachricht wegwerfen. Aber ggf. den Absender informieren, wenn der
        // online ist und wir nicht Invis
        object pl = find_player(msg.sendername);
        if (pl &&
            (!QueryProp(P_INVIS) || IS_LEARNER(pl)) )
          pl->ReceiveNotify(sprintf("Deine Nachricht an %s wurde "
                "ignoriert.",capitalize(getuid(this_object()))), MA_TELL);
        continue;
    }

    // wenn der Puffer zu klein ist, Groesse verdoppeln.
    // Keine Pruefung hier, weil das vault schon die Groesse beschraenkt und
    // der Inhalt auf jeden Fall passen soll.
    if (kobold->index >= sizeof(kobold->buf)-1)
        kobold->buf += allocate(sizeof(kobold->buf));
    kobold->index += 1;
    kobold->buf[kobold->index] = msg;

    // TM-History
    add_struct_tell_history(msg, 0, 1, MSGFLAG_TELL);
  }
  vault.Empty();
}

private void _flush_cache(int verbose) {
  // nur mit genug Evalticks ausgeben.
  if (get_eval_cost() < 500000) return;
  if (kobold->index >= 0)
  {
    ReceiveMsg("Ein kleiner Kobold teilt Dir folgendes mit:",
               MT_NOTIFICATION|MSG_DONT_IGNORE|MSG_DONT_BUFFER,
               0, 0, this_object());
    int prepend = QueryProp(P_MESSAGE_PREPEND);
    foreach(int i: 0 .. kobold->index) // '0 ..' ist wichtig!
    {
      struct kobold_msg_s msg = kobold->buf[i];
      // dies ist dient der Fehlerabsicherung, falls es nen Fehler (z.B. TLE)
      // in der Schleife unten gab: dann ist index nicht auf -1 gesetzt
      // worden, aber einige Nachrichten sind schon geloescht.
      if (!structp(msg)) continue;
      // Im folgenden nicht den string in der struct aendern (die wird ggf.
      // auch noch von der TM-History gebraucht).
      string msgstr = msg.msg;
      // Wenn Nachricht schon laenger her ist, Uhrzeit anhaengen, aber ggf.
      // muss ein \n abgeschnitten werden.
      if (msg.timestamp < time() - 3600)
      {
        if (msgstr[<1] == '\n')
          msgstr = msgstr[0..<2]
                      + " [" + strftime("%d.%m.%y %T", msg.timestamp) + "]";
        else
          msgstr = msgstr
                      + " [" + strftime("%d.%m.%y %T", msg.timestamp) + "]";
      }
      // Ausgabe via efun::tell_object(), weil die Arbeit von ReceiveMsg()
      // schon getan wurde. Allerdings muessen wir uns noch um den Umbruch
      // und Farben kuemmern.
      msgstr = terminal_colour(msgstr, colourmap);
      if ((msg->type) & MSG_DONT_WRAP)
        msgstr = (msg->prefix ? msg->prefix : "") + msgstr;
      else
      {
        int bsflags = msg->type & MSG_ALL_BS_FLAGS;
        if (prepend)
          bsflags |= BS_PREPEND_INDENT;
        msgstr = break_string(msgstr, 78, msg->prefix, bsflags);
      }
      efun::tell_object(this_object(), msgstr);
      kobold->buf[i]=0;
    }
    kobold->index=-1;
  }
  else if (verbose)
  {
    ReceiveMsg("Der kleine Kobold hat leider nichts Neues fuer Dich.",
               MT_NOTIFICATION|MSG_DONT_IGNORE|MSG_DONT_BUFFER,
               0, 0, this_object());
  }
}

varargs int cmd_kobold(string arg)
{
  if (!sizeof(arg))
  {
    _flush_cache(1);
    return 1;
  }
  switch(arg)
  {
    case "ein":
      SetProp(P_BUFFER, KOBOLD_ONLINE|KOBOLD_OFFLINE);
      ReceiveNotify("Der Kobold merkt sich jetzt alles!");
      break;
    case "online":
      SetProp(P_BUFFER, KOBOLD_ONLINE);
      ReceiveNotify("Der Kobold merkt sich jetzt alles, "
                    "wenn Du online bist!");
      break;
    case "offline":
      SetProp(P_BUFFER, KOBOLD_OFFLINE);
      ReceiveNotify("Der Kobold merkt sich jetzt alles, "
                    "wenn Du offline bist!");
      break;
    case "aus":
      SetProp(P_BUFFER, 0);
      ReceiveNotify("Der Kobold wird Dich nicht stoeren!");
      break;
    default:
        ReceiveNotify("Der Kobold sagt: Was soll ich mir denn merken? "
                      "('ein', 'aus', 'offline' oder 'online')");
        return 1;
  }
  if (QueryProp(P_BUFFER) & KOBOLD_OFFLINE)
      setup_comm_vault();
  else
  {
      // Comm-Vault entfernen. Aber zur Sicherheit nochmal abrufen und
      // verarbeiten (sollte aber eigentlich ueberfluessig sein)
      commvault = KOBOLD->ForgetVault();
      if (commvault) {
        process_comm_vault(commvault);
        commvault = 0;
      }
  }
  return 1;
}

public int TestIgnoreSimple(string *arg)
{   mapping ignore;

    if (!pointerp(arg) || !mappingp(ignore=Query(P_IGNORE,F_VALUE)))
        return 0;
    foreach(string s: arg)
    {
      if (member(ignore,s))
        return 1;
    }
    return 0;
}

//TODO: deprecated - entfernen, wenn Message() entfernt wird.
private int check_ignore(mixed ignore, string verb, string name)
{
  if (ignore == verb)
    return 1;
  ignore = explode(ignore, ".");
  return ((sizeof(ignore) > 1) &&
     (name == ignore[0] && member(ignore[1..], verb) != -1));
}

// Die Nachricht kommt mit einem Alert oder Mention. comm_beep() prueft, ob
// ein Piepston ausgegeben werden soll (langfristig andere Benachrichtigungen
// geplant!).
// Ueblicherweise werden nur alle <P_MESSAGE_BEEP> Sekunden Toene
// uebermittelt.
private void comm_beep(string msg_action, int mention=0)
{
  // Wenn Alerts komplett abgeschaltet sind, gibts nix.
  int alert_config = ({int})QueryProp(P_ALERT);
  if (alert_config & AL_NO_SOUND)
    return; // kein ton
  // und maximal alle P_MESSAGE_BEEP Sekunden aufmerksam machen; bei 0s ist
  // jedes Mal erlaubt.
  int beep_interval=({int})QueryProp(P_MESSAGE_BEEP);
  if ((time()-last_beep_time) < beep_interval)
    return;
  int required;
  switch(msg_action)
  {
      case MA_TELL:
        required |= MB_TELL;
        break;
      case MA_SAY:
        required |= MB_SAY;
        break;
      case MA_CHANNEL:
        required |= MB_CHANNEL;
        break;
      case MA_SHOUT:
        required |= MB_SHOUT;
        break;
      default:
        // Alle anderen Aktionen, die keine gesonderten Aktionsfilter haben
        required |= MB_MISC;
        break;
  }
  if (mention)
      required |= MB_MENTION;

  // wenn in alert min. ein notwendiges Flag drin ist darf gepiepst werden
  if (required & alert_config)
  {
    last_beep_time = time();
    binary_message(b"\a", 1);
  }
}

private varargs void add_struct_tell_history(struct kobold_msg_s msg,
                                         int sent, int recv, int flags )
{
  /* tell_history ist ein Mapping mit UIDs der Gespraechspartner als Key.
     Als Wert ist eine Strukur vom Typ chat_s eingetragen.
     Strukturen chat_s und kobold_msg_s sind in /std/player/comm_structs.c
     definiert.
     TODO fuer spaeter, gerade keine Zeit fuer:
     Als Wert ist ein Array von chat_s enthalten, wobei das 0. Element das
     jeweils juengste Gespraech mit diesem Gespraechspartner ist und alle
     weiteren Elemente in der zeitlichen Reihenfolge kommen (also letztes
     Element ist aeltestes Gespraech).
     */

  // Gespraechspartner fuer erwidere auch ohne tmhist speichern.
  if (flags & (MSGFLAG_TELL|MSGFLAG_RTELL))
    last_comm_partner = msg.sendername;

  // ist ein sortiertes Array von max. MAX_SAVED_CHATS Groesse, welches die
  // Spieler enthaelt, denen man schon was mitgeteilt hat. Aktuellste am
  // Anfang.
  if (sent) {
    if (!sizeof(commreceivers))
      commreceivers = ({msg.sendername});
    else if (commreceivers[0] != msg.sendername) {
      // nur wenn der aktuelle Partner nicht am Anfang steht, muss man hier was
      // tun. Comm-Partner an den Anfang stellen und ggf. alten Eintrag
      // entfernen.
      // TODO: Effizienter gestalten.
      commreceivers = ({msg.sendername}) + (commreceivers-({msg.sendername}));
      // ggf. kuerzen. (wenn !tell_history_enabled, wird es ggf. unten
      // gemacht, denn die Hist muss min. alle UID enthalten, die auch in
      // commreceivers drin sind.)
      if (!tell_history_enabled && sizeof(commreceivers) > MAX_SAVED_CHATS)
        commreceivers = commreceivers[0..MAX_SAVED_CHATS];
    }
  }

  // mit eingeschalteter History weitere Details speichern.
  if (!tell_history_enabled)
    return;

  if (msg.msg[<1] == '\n')
      msg.msg = msg.msg[..<2];

  struct chat_s chat;
  // Gespraechspartner unbekannt?
  if (!member(tell_history, msg.sendername)) {
    // zuviele Gespraeche in Hist? >= ist Absicht weil ja gleich noch eins
    // dazu kommt.
    if (sizeof(tell_history) >= MAX_SAVED_CHATS) {
      string deluid;
      int zeit = __INT_MAX__;
      foreach(string tuid, chat : tell_history) {
        // aeltestes Gespraech suchen
        if (zeit > chat->time_last_msg) {
          deluid = tuid;
          zeit = chat->time_last_msg;
        }
      }
      // aeltestes Gespraech raus.
      m_delete(tell_history, deluid);
      if (member(commreceivers,deluid)>-1)
        commreceivers-=({deluid});
    }
    // neues Gespraech anlegen
    chat = (<chat_s> uid: msg.sendername, time_first_msg: msg.timestamp,
               time_last_msg: msg.timestamp,
         sentcount: sent, recvcount: recv,
         msgbuf: 0, ptr: 0 );
    tell_history[msg.sendername] = chat;
  }
  else {
    // Gespraechspartner bekannt, altes Gespraech weiterbenutzen
    chat = tell_history[msg.sendername];
    chat->time_last_msg = msg.timestamp;
    chat->sentcount += sent;
    chat->recvcount += recv;
  }

  // ggf. auch INhalte von Gespraechen speichern
  if (tell_history_enabled < TELLHIST_ENABLED)
    return;

  // ggf. Array fuer Messages anlegen
  if (!pointerp(chat->msgbuf))
    chat->msgbuf = allocate(MAX_SAVED_MESSAGES);

  // neue Struct ins Array schreiben
  chat->msgbuf[chat->ptr] = msg;
  // Index auf naechste Messagestruktur ermitteln
  chat->ptr = (chat->ptr + 1) % MAX_SAVED_MESSAGES;
}

private varargs void add_to_tell_history( string uid, int sent, int recv,
                                 string message, string indent, int flags )
{
  //TODO: Entfernen, wenn das nicht mehr passiert.
  if (!stringp(uid))
  {
    ReceiveMsg(sprintf(
      "\nadd_to_tell_history(): got bad uid argument %O."
      "sent: %d, recv: %d, flags: %d, msg: %s", 
      uid, sent, recv, flags, message),MT_DEBUG|MSG_BS_LEAVE_LFS,0,0,ME);
  }
  // Message-Struktur anlegen
  struct kobold_msg_s msg = (<kobold_msg_s> msg: message, prefix: indent,
                             sendername: uid, timestamp: time());
  add_struct_tell_history(msg, sent, recv, flags);
}

protected void clear_tell_history(int force)
{
  /* Nach einem "schlafe ein" werden die gespeicherten Mitteilungen geloescht,
     sofern der Spieler nichts abweichendes eingestellt hat. */

  // bei manuellem Loeschen (force==1) immer loeschen, ansonsten nur, wenn die
  // History nicht "long-life" ist.
  if (tell_history_enabled < TELLHIST_LONGLIFE || force)
  {
    tell_history = ([]);
    commreceivers = ({});
  }
}

protected void reset(void)
{
  /* Wird 15 Minuten nach dem Verlust der Verbindung aufgerufen. Falls der
     Spieler nicht inzwischen eine Verbindung wiederhergestellt hat, werden
     wie bei einem "schlafe ein" die Mitteilungen geloescht. */

  if (!interactive())
    clear_tell_history(0);

}

// gerufen, wenn zielgerichtet mit jemandem kommuniziert wird _und_ das
// Ergebnis des ReceiveMsg() geprueft werden und eine Meldung ausgegeben
// werden soll.
private void _send(object ob, string msg, int msg_type,
                   string msg_action, string msg_prefix)
{
  int res = ob->ReceiveMsg(msg, msg_type, msg_action, msg_prefix, ME);

  switch(res) {
    case MSG_DELIVERED:
      break;  // nix machen
    case MSG_BUFFERED:
      ReceiveMsg(ob->Name(WER) + " moechte gerade nicht gestoert werden. "
          "Die Mitteilung wurde von einem kleinen Kobold in Empfang "
          "genommen. Er wird sie spaeter weiterleiten!",
          MT_NOTIFICATION, msg_action, 0, this_object());
      break;
    case MSG_IGNORED:
    case MSG_VERB_IGN:
    case MSG_MUD_IGN:
      ReceiveMsg(ob->Name(WER) + " hoert gar nicht zu, was Du sagst.",
           MT_NOTIFICATION, msg_action, 0, this_object());
      break;
    case MSG_SENSE_BLOCK:
      ReceiveMsg(ob->Name(WER) + " kann Dich leider nicht wahrnehmen.",
          MT_NOTIFICATION, msg_action, 0, this_object());
      break;
    case MSG_BUFFER_FULL:
      ReceiveMsg(ob->Name(WER) + " moechte gerade nicht gestoert werden. "
          "Die Mitteilung ging verloren, denn der Kobold kann sich "
          "nichts mehr merken!", MT_NOTIFICATION, msg_action, 
          0, this_object());
      break;
    default:
      ReceiveMsg(ob->Name(WER) + " hat Deine Nachricht leider nicht "
          "mitbekommen.", MT_NOTIFICATION, msg_action, 0, this_object());
      break;
  }
}

// aehnlich wie _send(), aber gerufen, wenn die Empfaengerin nicht online ist,
// aber ein Kobold-Vault deponiert hat und versucht werden soll, dort eine
// Nachricht zu hinterlegen.
private void _send_to_kobold(string pluid, string msg, int msg_type,
                   string msg_action, string msg_prefix)
{
  int res = KOBOLD->DepositMsg(pluid, msg, msg_type, msg_action,
                               msg_prefix, ME);
  switch(res) {
    case MSG_BUFFERED:
      ReceiveMsg(sprintf("%s ist gerade nicht online, aber Deine Botschaft "
          "wurde von einem fuer kleinen Kobold aufgeschrieben und er wird "
          "versuchen, sie %s bei naechster Gelegenheit zu uebermitteln. "
          "Der Kobold macht Dich darauf aufmerksam, dass er aber keine "
          "Uebermittlung garantieren kann.",
          capitalize(pluid), capitalize(pluid)),
          MT_NOTIFICATION, msg_action, 0, this_object());
      break;
    case MSG_BUFFER_FULL:
      ReceiveMsg(sprintf("%s ist gerade nicht online und leider ist auf "
          "der Schriftrolle des kleinen Kobolds kein Platz mehr fuer "
          "Deine Botschaft. Vielleicht schickst Du %s besser einen Brief.",
          capitalize(pluid), capitalize(pluid)),
          MT_NOTIFICATION, msg_action, 0, this_object());
      break;
    default:
      ReceiveMsg(sprintf("%s ist gerade nicht online und leider konnte "
          "sich der kleine Kobold Deine Botschaft nicht merken. "
          "Vielleicht schickst Du %s besser einen Brief.",
          capitalize(pluid),capitalize(pluid)),
          MT_NOTIFICATION, msg_action, 0, this_object());
      break;
  }
}

// Ausgabe an das Objekt selber und Aufzeichnung in der Kommhistory, falls
// noetig. Wird bei _ausgehenden_ Nachrichten im eigenen Objekt gerufen, damit
// die Nachricht ggf. in den Kommhistory erfasst wird.
// TODO: entfernen, wenn alles Aufrufer ersetzt sind durch ReceiveMsg().
protected varargs int _recv(object ob, string message, int flag, string indent)
{
  write(break_string(message, 78, indent,
        QueryProp(P_MESSAGE_PREPEND) ? BS_PREPEND_INDENT : 0));
  if ((flag & MSGFLAG_TELL || flag & MSGFLAG_REMOTE) &&
      query_once_interactive(ob))
  {
    if (flag & MSGFLAG_WHISPER)
      add_to_tell_history(getuid(ob), 1, 0,
        "Du fluesterst " + ob->name(WEM) + " aus der Ferne etwas zu.", 0,
        flag);
    else
      add_to_tell_history(getuid(ob), 1, 0, message, indent, flag);
  }
  return 1;
}

// <sender> sollte ein Objekt sein. In seltenen Faellen (z.B.
// Fehlerbehandlung) ist es jedoch auch mal ein String.
varargs int Message(string msg, int flag, string indent,
                    string cname, mixed sender)
{
  object ti;
  string verb, reply, *ignore, tin;
  int em, te;
  mixed deaf;

  // Bei den Kanaelen 'Debug' und 'Entwicklung' kann man gezielt Bugs
  // einzelner Magier ignorieren. Dazu wird der Kanalname zum 'verb',
  // damit 'ignoriere name.debug' funktioniert.
  if( flag == MSGFLAG_CHANNEL ){
      if((msg[1..5] == "Debug" || msg[1..11] == "Entwicklung"
            || msg[1..9]=="Warnungen"))
      {
        // Missbrauch der Variable 'ignore' als Zwischenspeicher
        ignore = regexplode( msg, ":| |\\]" );
        verb = lower_case(ignore[0][1..]);
        tin = lower_case(ignore[2]);
      }
      else
      {
        if(cname)
          verb=lower_case(cname);
        else
          verb=query_verb();
        if( ti = this_interactive() )
        {
          tin = getuid(this_interactive());
        }
        else
        {
          //falls doch kein Objekt...
          if (objectp(sender))
            tin=lower_case(sender->name(RAW)||"<Unbekannt>");
        }
      }
  }
  else {
    if( ti = this_interactive() )
      tin = getuid(this_interactive());
    verb = query_verb();
  }

  te = flag & (MSGFLAG_TELL | MSGFLAG_WHISPER);

  // fuer "erwidere"
  if (ti && (flag & MSGFLAG_TELL || flag & MSGFLAG_REMOTE)) {
    if (!ti->QueryProp(P_INVIS)||IS_LEARNER(ME)) {
      if (flag & MSGFLAG_WHISPER)
        add_to_tell_history(getuid(ti), 0, 1,
          capitalize((((IS_LEARNER(ti) && !ti->QueryProp(P_INVIS) &&
            (ti->QueryProp(P_CAN_FLAGS) & CAN_PRESAY)) ?
            ti->QueryProp(P_PRESAY) : "") + ti->name()) || "") +
          " fluestert Dir aus der Ferne etwas zu.", 0, flag, 0);
      else
        add_to_tell_history(getuid(ti), 0, 1, msg, indent, flag, 0);
    }
  }
  // Hoert der Spieler nicht?
  em = (ti &&
        (te || flag & MSGFLAG_SHOUT) &&
        (QueryProp(P_EARMUFFS) &&
          (query_wiz_level(ti) < QueryProp(P_EARMUFFS))));
  ignore = (pointerp(ignore = QueryProp(P_IGNORE)) ? ignore : ({}));

  // Werden der Sender oder das Verb ignoriert?
  if(!ti && tin && flag == MSGFLAG_CHANNEL)
  {
     if((member(ignore, tin) != -1))
     {
       return MESSAGE_IGNORE_YOU;
     }
     if(verb &&  sizeof(filter(ignore, #'check_ignore, verb, tin)) )
     {
       return MESSAGE_IGNORE_YOU;
     }
  }
  if (ti && (member(ignore, getuid(ti)) != -1)) {
    if(te && (IS_LEARNER(ti)||!QueryProp(P_INVIS)))
      efun::tell_object(ti, capitalize(name())+
                      " hoert gar nicht zu, was Du sagst.\n");
    return MESSAGE_IGNORE_YOU;
  }
  if(tin && verb &&
     sizeof(filter(ignore, #'check_ignore/*'*/, verb, tin)))
  {
    if(ti && verb[0..2] != "ruf" && verb[0..3] != "mruf" &&
       verb[0..3] != "echo" && verb[0] != '-' && !(flag & MSGFLAG_CHANNEL) )
      efun::tell_object(ti, name()+" wehrt \""+verb+"\" ab.\n");
    return MESSAGE_IGNORE_VERB;
  }
  if (flag & MSGFLAG_RTELL) {
    int at;

    verb = lower_case(old_explode(msg, " ")[0][1..]);
    at = member(verb, '@');
    /* verb wird hier eh missbraucht, also auch fuer ein intermud-erwidere*/
    add_to_tell_history(verb, 0, 1, msg, indent, flag, 0);

    if ((member(ignore, verb) >= 0) || (member(ignore,verb[0..at]) >= 0))
      return MESSAGE_IGNORE_YOU;
    else if (at > 0 && member(ignore, verb[at..]) >= 0)
      return MESSAGE_IGNORE_MUD;
  }

  // Taubheit/Oropax
  te |= (flag & MSGFLAG_SAY);

  if (QueryProp(P_DEAF) && (flag & MSGFLAG_DEAFCHK) && !(flag & MSGFLAG_CHIST)) {
    deaf = QueryProp(P_DEAF);
    if (te)
      reply = stringp(deaf) ?
        capitalize(sprintf(deaf, name())) :
        capitalize(name())+" ist momentan leider taub.\n";
  }
  else if (em)
    reply = capitalize(name())+" hat Oropax in den Ohren.\n";

  msg = break_string(msg, 78, indent,
    (QueryProp(P_MESSAGE_PREPEND) ? BS_PREPEND_INDENT : 0) | BS_LEAVE_MY_LFS);

  if((QueryProp(P_BUFFER) & KOBOLD_ONLINE) &&
     (deaf ||
      query_editing(this_object()) ||
      query_input_pending(this_object())))
  {
    deaf = MESSAGE_DEAF;
    if(flag & MSGFLAG_CACHE)
    {
      if(!stringp(reply))
        reply = name()+" moechte gerade nicht gestoert werden.\n";

      msg = msg[0..<2]+" [" + strftime("%H:%M",time()) + "]\n";

      int res =  add_to_kobold(msg, 0, 0, 0,
                               objectp(sender) ? sender : ME);
      if(res == MSG_BUFFERED)
      {

        reply += "Die Mitteilung wurde von einem kleinen Kobold in Empfang "+
                 "genommen.\nEr wird sie spaeter weiterleiten!";
        deaf = MESSAGE_CACHE;
      }
      else {
        reply += "Die Mitteilung ging verloren, denn "+
                 "der Kobold kann sich nichts mehr merken!";
        deaf = MESSAGE_CACHE_FULL;
      }
      if(ti && (IS_LEARNER(ti)||!QueryProp(P_INVIS)))
        efun::tell_object(ti, reply+"\n");
    }
    return deaf;
  }
  else if((deaf || em) &&
          ( (flag & MSGFLAG_RTELL) ||
            (ti && (IS_LEARNER(ti)||!QueryProp(P_INVIS))))) {
    if (te && ti)
      efun::tell_object(ti, reply);
    return MESSAGE_DEAF;
  }

  _flush_cache(0);
  if(te && QueryProp(P_AWAY))
    msg = msg[0..<2]+" [" + strftime("%H:%M",time()) + "]\n";

  if(!objectp(sender) || sender != ME)
  {
    if (flag & MSGFLAG_SAY)
      comm_beep(MA_SAY);
    else if (flag & MSGFLAG_TELL)
      comm_beep(MA_TELL);
    else if (flag & MSGFLAG_CHANNEL)
      comm_beep(MA_CHANNEL);
    else if (flag & MSGFLAG_SHOUT)
      comm_beep(MA_SHOUT);
  }
  efun::tell_object(ME, msg);
  return MESSAGE_OK;
}

static int ignoriere(string str)
{
  str = _unparsed_args(1);
  mapping ignore=Query(P_IGNORE, F_VALUE);

  if (!str)
  {
    string* ignarr = m_indices(ignore);
    if (!sizeof(ignarr))
        tell_object(ME, "Du ignorierst niemanden.\n");
      else
        ReceiveMsg("Du ignorierst:\n"
                   + break_string(CountUp(map(sort_array(ignarr, #'> ),
                                          #'capitalize ) 
                                         ) + ".",78),
                   MT_NOTIFICATION|MSG_DONT_IGNORE|MSG_DONT_STORE|MSG_DONT_WRAP,
                   0,0,this_object());
      return 1;
  }
  // trim spaces from args and convert to lower case.
  str = lower_case(trim(str, TRIM_BOTH));

  if (member(ignore, str))
  {
    RemoveIgnore(str);
    tell_object(ME, sprintf("Du ignorierst %s nicht mehr.\n", capitalize(str)));
  }
  else if (sizeof(ignore)>100)
  {
   tell_object(ME, "Du ignorierst schon genuegend!\n");
  }
  else if (AddIgnore(str) == 1)
  {
    tell_object(ME,
        sprintf("Du ignorierst jetzt %s.\n", capitalize(str)));
  }
  else
  {
    tell_object(ME,
        sprintf("'%s' kannst Du nicht ignorieren.\n",str));
  }
  return 1;
}


private int _alert_filter_flags(int flag, string text)
{
  return (flag & QueryProp(P_ALERT));
}

static int _msg_beep(string str)
{
  int beep_interval;

  notify_fail(
    "Syntax:\n"
    "- klingelton <1 bis 3600 Sekunden>\n"
    "- klingelton aus\n"
    "- klingelton ein\n"
    "- klingelton <+/-><tm / sag / ebenen / ruf / erwaehnung / sonstige / alle / >\n");

  if(!sizeof(str))
    return 0;
  if (!regmatch(str,"^[[:digit:]]", RE_PCRE))
  {
    if (str=="aus")
          SetProp(P_ALERT, QueryProp(P_ALERT) | AL_NO_SOUND);
    else if (str=="ein")
          SetProp(P_ALERT, QueryProp(P_ALERT) & ~AL_NO_SOUND);
    else
    {
      mapping flags = ([
        "tm": MB_TELL, "teilemit": MB_TELL,
        "sag": MB_SAY, "sage": MB_SAY,
        "ebene": MB_CHANNEL, "ebenen": MB_CHANNEL,
        "ruf": MB_SHOUT, "rufe": MB_SHOUT,
        "erwaehnung": MB_MENTION, "erwaehnungen": MB_MENTION,
        "sonstige": MB_MISC, "sonstiges": MB_MISC,
        "alle": MB_ALL, "alles": MB_ALL,
        ]);
      foreach(string part : explode(str, " ") - ({""}))
      {
        if(!(part[1..] in flags)) continue;
        if(part[0] == '+')
        {
          SetProp(P_ALERT,
            QueryProp(P_ALERT) | flags[part[1..]]);
        }
        else if(part[0] == '-')
        {
          SetProp(P_ALERT,
            QueryProp(P_ALERT) & ~ flags[part[1..]]);
        }
      }
      // 0 hat leider historisch die Bedeutung von MB_MISC, daher muss hier
      // statt dessen auf AL_NO_SOUND gesetzt werden.
      if(!QueryProp(P_ALERT))
      {
        SetProp(P_ALERT, AL_NO_SOUND);
      }
    }
  }
  else
  {
    beep_interval = to_int(str);
    if(beep_interval >= 0)
    {
        SetProp(P_MESSAGE_BEEP, beep_interval);
    }
  }

  beep_interval=({int})QueryProp(P_MESSAGE_BEEP);
  mapping text = ([
    MB_SAY: "sage",
    MB_TELL: "teile mit",
    MB_CHANNEL: "Ebenenmeldungen",
    MB_MENTION: "Erwaehnungen",
    MB_SHOUT: "rufe",
    MB_MISC: "sonstige",]);
  string types = CountUp(map(filter(m_indices(text), #'_alert_filter_flags), text));
  if(!sizeof(types))
  {
    types = "Keine";
  }
  ReceiveNotify(
    "Gewaehlte Klingeltoene: " + types + "\n"
    "Zeitabstand: "
    + (beep_interval ? "maximal alle " + beep_interval + " Sekunden." : "kein") + "\n"
    + (QueryProp(P_ALERT) & AL_NO_SOUND ? " Allerdings sind Toene insgesamt "
         "bei Dir abgeschaltet. (\'hilfe ton\')" : ""),
    query_verb());
  return 1;
}

static int _msg_prepend(string str) {
  notify_fail("Syntax: senderwiederholung ein/aus\n");
  if (stringp(str)) {
    if (str=="aus")  
      SetProp(P_MESSAGE_PREPEND,1);
    else if (str=="ein")  
      SetProp(P_MESSAGE_PREPEND,0);
    else return 0;
  }

  ReceiveNotify("Senderwiederholung bei Mitteilungen: "+ 
          (({int})QueryProp(P_MESSAGE_PREPEND) ?  "aus" : "ein")+".",
          query_verb());

  return 1;
}

static int _communicate(mixed str, int silent)
{
  string  verb;
  string  myname;
  string  msg;

  if (!str || extern_call()) str=_unparsed_args()||"";
  /* str=_unparsed_args()||""; */
  verb = query_verb();
  if(stringp(verb) && verb[0] == '\'') str = verb[1..] + " " + str;
  if (str==""||str==" "||!str)
  {
    ReceiveNotify("Was willst Du sagen?",MA_SAY);
    return 1;
  }
  msg=permutate(str);

  myname=(((QueryProp(P_INVIS)||!IS_LEARNER(ME))||
     !(QueryProp(P_CAN_FLAGS)&CAN_PRESAY)?
    "":QueryProp(P_PRESAY))+name())||"";

  // an alles im Raum senden. (MT_LISTEN, weil dies gesprochene Kommunikation
  // ist, keine MT_COMM)
  send_room(environment(), msg, MT_LISTEN|MSG_ALERT, MA_SAY,
            capitalize(myname)+" sagt: ", ({this_object()}) );

  if(!silent)
  {
    ReceiveMsg(msg, MT_NOTIFICATION|MSG_DONT_IGNORE|MSG_DONT_STORE,
               MA_SAY, "Du sagst: ", ME);
  }
  return 1;
}

static int _shout_to_all(mixed str)
{
  string pre, myname, realname, wizards_msg, players_msg;
  string wizard_prefix, player_prefix;
  int chars;

  if (!(str=_unparsed_args()))
  {
    ReceiveNotify("Was willst Du rufen?",MA_SHOUT);
    return 1;
  }
  chars=sizeof(str)/2;
  if (chars<4) chars=4;
  pre = (!IS_LEARNER(ME) ||
   QueryProp(P_INVIS) ||
   !(QueryProp(P_CAN_FLAGS) & CAN_PRESAY)) ? "" : QueryProp(P_PRESAY);
  realname = capitalize((pre + capitalize(getuid()))||"");
  myname = capitalize(pre + name()||"");
  if (QueryProp(P_INVIS))
    realname = "("+realname+")";

  wizards_msg = permutate(str);
  wizard_prefix = myname+" ruft: ";

  if(QueryProp(P_FROG)) {
    players_msg = "Quaaak, quaaaaak, quuuuaaaaaaaaaaaaaaaaaaaak !!";
    player_prefix = myname+" quakt: ";
  }
  else {
    players_msg = wizards_msg;
    player_prefix = wizard_prefix;
  }

  if(!IS_LEARNER(this_player()))
  {
    if(QueryProp(P_GHOST)) {
        ReceiveNotify("So ganz ohne Koerper bekommst Du keinen Ton heraus.",
                MA_SHOUT);
        return 1;
    }
    if (QueryProp(P_SP) <(chars+20))
    {
      ReceiveNotify("Du musst erst wieder magische Kraefte sammeln.",
              MA_SHOUT);
      ReceiveNotify("Tip: Benutz doch mal die Ebenen (Hilfe dazu mit 'hilfe "
              "Ebenen').", MA_SHOUT);
      return 1;
    }
    SetProp(P_SP, QueryProp(P_SP) - chars - 20);
  }

  ReceiveMsg(wizards_msg, MT_NOTIFICATION|MSG_DONT_IGNORE|MSG_DONT_STORE,
             MA_SHOUT, "Du rufst: ", ME);

  foreach ( object ob : users()-({this_object()}) )
    if ( IS_LEARNER(ob) )
      ob->ReceiveMsg(wizards_msg, MT_LISTEN|MT_FAR|MSG_ALERT, MA_SHOUT,
                     wizard_prefix, this_object());
    else
      ob->ReceiveMsg(players_msg, MT_LISTEN|MT_FAR|MSG_ALERT, MA_SHOUT,
                     player_prefix, this_object());

  return 1;
}

varargs int _tell(string who, mixed msg)
{
  object    ob;
  string    away,myname,ret;
  string    *xname;
  int       i,visflag;

  if (extern_call() && this_interactive()!=ME) return 1;
  if (!who || !msg) {
    ReceiveNotify("Was willst Du mitteilen?",MA_TELL);
    return 1;
  }

  if(who == ERWIDER_PARAM)
  {
    if (!last_comm_partner)
    {
      _notify_fail("Du hast aber noch keine Mitteilungen erhalten, auf die "
          "Du was erwidern\nkoenntest.\n");
      return 0;
    }
    who=last_comm_partner;
  }

  // teile .x mit teilt bisherigen Gespraechspartnern etwas mit.
  if (who == ".")
   who = ".1";

  if ( sscanf(who, ".%d", i) == 1 ) {
    if(i > 0 && i <= sizeof(commreceivers))
      who = commreceivers[i-1];
    else {
      _notify_fail("So vielen Leuten hast Du noch nichts mitgeteilt!\n");
      return 0;
    }
  }

  xname = explode(who, "@");

  if (sizeof(xname) == 2)
  {
    if ( QueryProp(P_QP) )
    {
      if (ret=({string})INETD->_send_udp(xname[1],
                                    ([ REQUEST:   "tell",
                                       RECIPIENT: xname[0],
                                       SENDER:    getuid(ME),
                                       DATA:     msg ]), 1))
      {
        ReceiveNotify(ret, MA_TELL);
      }
      else
      {
        write("Nachricht abgeschickt.\n");
        add_to_tell_history(who, 1, 0, msg,
          "Du teilst " + capitalize(who) + " mit: ", MSGFLAG_RTELL, 1);
      }
    }
    else
      write("Du hast nicht genug Abenteuerpunkte, um Spielern in anderen \n"
        "Muds etwas mitteilen zu koennen.\n");
    return 1;
  }

  string|int lname = lower_case(who);
  if (!ob=find_player(lname))
  {
    lname = match_living(lname, 0);
    if (!stringp(lname))
    {
      switch(lname)
      {
      case -1:
        ReceiveNotify("Das war nicht eindeutig!",MA_TELL);
        return 1;
      case -2:
        // check KOBOLD
        ob = load_object(KOBOLD);
        lname = ({string|int})ob->find_player(lower_case(who));
        if (lname == -1) {
          ReceiveNotify("Das war nicht eindeutig!",MA_TELL);
          return 1;
        }
        else if (!stringp(lname)) {
          ReceiveNotify("Kein solcher Spieler (online)!",MA_TELL);
          return 1;
        }
      }
      // jetzt ist ob der KOBOLD und lname die UID eines Spielers.
    }
    // Wenn wir noch kein ob haben, sollte lname jetzt aber durch das
    // match_living() der Name eines Livings sein, dessen Objekt wir noch
    // brauchen.
    if (!ob)
      ob = find_player(lname) || find_living(lname);
    if(!ob) {
      ReceiveNotify("Kein solcher Spieler (online)!",MA_TELL);
      return 1;
    }
  }

  if(QueryProp(P_INVIS))
  {
    if(!IS_LEARNER(ob))
      myname = name();
    else
      myname="("+
             ((QueryProp(P_CAN_FLAGS) & CAN_PRESAY)?QueryProp(P_PRESAY):"")+
             capitalize(getuid()) + ")";
  }
  else
    myname=((IS_LEARNER(ME) && (QueryProp(P_CAN_FLAGS) & CAN_PRESAY)) ?
              QueryProp(P_PRESAY):"") + capitalize(getuid(ME));
  if (myname && sizeof(myname))
    myname=capitalize(myname);

  // Wir haben Zielobjekt und unseren eigenen Namen. Erstmal an Empfaenger
  // senden.
  if (living(ob))
    _send(ob, permutate(msg), MT_COMM|MT_FAR|MSG_ALERT, MA_TELL,
          myname + " teilt Dir mit: ");
  else
    _send_to_kobold(lname, permutate(msg), MT_COMM|MT_FAR|MSG_ALERT, MA_TELL,
          myname + " teilt Dir mit: ");

  // dann evtl. noch an Absender ausgeben...
  visflag = !ob->QueryProp(P_INVIS);
  if (visflag || IS_LEARNER(this_player()))
    _recv(ob, msg, MSGFLAG_TELL, "Du teilst " + capitalize(lname) + " mit: ");
  // oder irgendwas anderes an den Absender ausgeben...
  if (!visflag && interactive(ob))
      ReceiveNotify("Kein solcher Spieler online!",MA_TELL);
  else if (away = ({string})ob->QueryProp(P_AWAY))
      ReceiveMsg( break_string( away, 78, capitalize(lname)
                           + " ist gerade nicht da: ", BS_INDENT_ONCE ),
          MT_NOTIFICATION|MSG_DONT_WRAP|MSG_DONT_IGNORE,
          MA_TELL, 0, this_object());
  else if (interactive(ob) && (i=query_idle(ob))>=600)
  { //ab 10 Mins
      if (i<3600)
        away=time2string("%m %M",i);
      else
        away=time2string("%h %H und %m %M",i);

      ReceiveNotify(sprintf("%s ist seit %s voellig untaetig.",
              capitalize(lname),away),
              MA_TELL);
    }

  return 1;
}

static int _teile(string str)
{
  string who, message;
  if (!(str=_unparsed_args())) return 0;
  if (sscanf(str, "%s mit %s", who, message) == 2)
    return _tell(who, message,1);
  return 0;
}
static int _teile_mit_alias(string str)
{
  str = _unparsed_args(), TRIM_LEFT;
  if (!str) return 0;
  str = trim(str, TRIM_LEFT);
  // Ziel muss min. 2 Buchstaben haben (.<nr>)
  if (sizeof(str) < 4) return 0;
  int pos = strstr(str, " ");
  if (pos >= 2)
    return _tell(str[..pos-1], str[pos+1..]);
  return 0;
}

static int _erzaehle(string str)
{
  string who, message;

  if (!(str=_unparsed_args())) return 0;
  if (sscanf(str, "%s %s", who, message) == 2)
    return _tell(who, message,1);
  return 0;
}

static int _whisper(string str)
{
  object    ob;
  string    who;
  string    msg;
  string    myname;

  if (!(str=_unparsed_args()) ||
       (sscanf(str, "%s zu %s", who, msg) != 2 &&
        sscanf(str, "%s %s", who, msg) !=2 )) {
    ReceiveNotify("Was willst Du wem zufluestern?",MA_SAY);
    return 1;
  }
  who = lower_case(who);
  if (!(ob = present(who, environment(this_player()))) || !living(ob)) {
    ReceiveNotify(capitalize(who)+" ist nicht in diesem Raum.",MA_SAY);
    return 1;
  }

  myname = capitalize((((IS_LEARNER(ME) &&
       !QueryProp(P_INVIS) &&
       (QueryProp(P_CAN_FLAGS) & CAN_PRESAY))?
      QueryProp(P_PRESAY) : "") + name()) || "");

  _send(ob, permutate(msg), MT_LISTEN|MSG_DONT_STORE,
        MA_SAY, myname + " fluestert Dir zu: ");
  send_room(environment(),
            myname + " fluestert " + ob->name(WEM, 1) + " etwas zu.",
            MT_LISTEN|MSG_DONT_STORE, MA_SAY, 0, ({this_object(),ob}));

  _recv(ob, msg, MSGFLAG_WHISPER, "Du fluesterst " + ob->name(WEM) + " zu: ");


  return 1;
}

static int _remote_whisper(string str)
{
  /* Wie 'teile mit', nur mit MSGFLAG_WHISPER. Dadurch wird der Inhalt der
     Nachricht nicht in der tell_history verewigt. */

  object    ob;
  string    who;
  string    msg;
  string    myname;

  if (!(str=_unparsed_args()) ||
       (sscanf(str, "%s zu %s", who, msg) != 2 &&
        sscanf(str, "%s %s", who, msg) !=2 )) {
    ReceiveNotify("Was willst Du wem aus der Ferne zufluestern?",MA_EMOTE);
    return 1;
  }

  string|int lname = lower_case(who);
  if (!ob=find_player(lname))
  {
    lname = match_living(lname, 0);
    if (!stringp(lname))
    {
      switch(lname)
      {
      case -1:
        ReceiveNotify("Das war nicht eindeutig!",MA_TELL);
        return 1;
      case -2:
        // rfluester benutzt keinen KOBOLD.
        ReceiveNotify("Kein solcher Spieler!",MA_TELL);
        return 1;
      }
    }
    // lname sollte nun eindeutig sein.
    ob = find_player(lname) || find_living(lname);
    if(!ob) {
      ReceiveNotify("Kein solcher Spieler online!",MA_TELL);
      return 1;
    }
  }

  if (environment(ob) == environment()) {
    ReceiveNotify("Wenn jemand neben Dir steht, nimm fluester.",MA_EMOTE);
    return 1;
  }

  myname = capitalize((((IS_LEARNER(ME) &&
       !QueryProp(P_INVIS) &&
       (QueryProp(P_CAN_FLAGS) & CAN_PRESAY))?
      QueryProp(P_PRESAY) : "") + name()) || "");

  // An Empfaenger senden.
  _send(ob, permutate(msg), MT_COMM|MT_FAR|MSG_DONT_STORE,
        MA_EMOTE, myname + " fluestert Dir aus der Ferne zu: ");
  // wenn Empfaenger invis und wir kein Magier , ggf. fakefehler ausgeben.
  if (ob->QueryProp(P_INVIS) && !IS_LEARNER(this_player())) {
    ReceiveNotify("Kein solcher Spieler online!",MA_EMOTE);
    return 1;
  }
  // sonst eigene Meldung via _recv() ausgeben.
  else 
    _recv(ob, msg, MSGFLAG_WHISPER | MSGFLAG_REMOTE,
        "Du fluesterst " + ob->name(WEM) + " aus der Ferne zu: ");

  return 1;
}

static int _converse(string arg)
{
  ReceiveNotify("Mit '**' wird das Gespraech beendet.",MA_SAY);
  if (stringp(arg) && strstr(arg, "-s") == 0)
    input_to("_converse_more", INPUT_PROMPT, "]", 1);
  else
    input_to("_converse_more", INPUT_PROMPT, "]", 0);
  return 1;
}

static int _converse_more(mixed str, int silent)
{
  if (str == "**") {
    ReceiveNotify("Ok.",MA_SAY);
    return 0;
  }

  if(str != "")
    _communicate(str, silent);

  input_to("_converse_more", INPUT_PROMPT, "]", silent);
  return 1;
}

private int is_learner(object o) { return IS_LEARNER(o); }

static int _shout_to_wizards(mixed str)
{
  string    myname;

  str = _unparsed_args();
  if (!str||!sizeof(str)) {
    ReceiveNotify("Was willst Du den Magiern zurufen?",MA_SHOUT);
    return 1;
  }
  // Kontrollzeichen rausfiltern.
  str = regreplace(str,"[[:cntrl:]]","",RE_PCRE|RE_GLOBAL);
  myname = capitalize(getuid(this_object()));
  if (!IS_LEARNER(this_object()))
    _recv(0, str, MSGFLAG_MECHO, "Du teilst allen Magiern mit: ");

  // mrufe ist nicht ignorierbar, da es nur fuer schwere Probleme gedacht ist.
  filter(users(), #'is_learner)->ReceiveMsg(str,
      MT_COMM|MT_FAR|MSG_DONT_IGNORE|MSG_DONT_STORE|MSG_ALERT,
      MA_SHOUT, myname+" an alle Magier: ", this_object());

  return 1;
}

static int _echo(string str) {
  if (!IS_SEER(ME) || (!IS_LEARNER(ME)
        && !(QueryProp(P_CAN_FLAGS) & CAN_ECHO)))
    return 0;

  if (!(str=_unparsed_args())) {
    ReceiveNotify("Was moechtest Du 'echoen'?", 0);
    return 1;
  }

  if (!IS_LEARNER(this_interactive()))
  {
    if (QueryProp(P_GHOST))
    {
      _notify_fail("Ohne Koerper fehlt Dir dazu die noetige magische Kraft.\n");
      return 0;
    }
    if (QueryProp(P_SP)<ECHO_COST)
    {
      _notify_fail("Du musst erst wieder magische Kraefte sammeln.\n");
      return 0;
    }
    SetProp(P_SP,QueryProp(P_SP)-ECHO_COST);
    str=">\b"+str;
    log_file("ARCH/ECHO_SEHER", sprintf("%s %s: %s\n", dtime(time()), getuid(),
           str));
  }
  // An den Raum senden. Typ ist MT_COMM, aber das Echo soll weder in der
  // Kommhistory noch im Kobold landen.
  send_room(environment(ME), str, MT_COMM|MSG_DONT_STORE|MSG_DONT_BUFFER,
            MA_UNKNOWN, 0, 0);
  return 1;
}

// Dient als Verteidigung gegen Leute, die eher unbedacht reinschreiben, nicht
// gegen Leute, die da absichtlich reinschreiben. Die werden geteert
// und gefedert.
static string *_set_ignore(mixed arg)
{
  raise_error("Direktes Setzen von P_IGNORE ist nicht erlaubt. "
      "Benutze AddIgnore/RemoveIgnore()!\n");
}
// Kompatibiltaet zum alten Ignore: Array von Indices liefern. Aendert aber
// nix dran, dass alle TestIgnore() & Co benutzen sollen.
static string *_query_ignore() {
  mixed ign=Query(P_IGNORE, F_VALUE);
  if (mappingp(ign))
    return m_indices(ign);
  return ({});
}

public int AddIgnore(string ign) {
  // Einige strings sind nicht erlaubt, z.B. konsekutive .
  if (!sizeof(ign)
      || regmatch(ign,"[.]{2,}",RE_PCRE)
      || regmatch(ign," ",RE_PCRE)
      || sizeof(explode(ign,"."))>3)
    return 0;

  mapping ignores=Query(P_IGNORE, F_VALUE);
  ignores[ign]=time();
  // kein Set() noetig.
  return 1;
}

public int RemoveIgnore(string ign)
{
  mapping ignores=Query(P_IGNORE,F_VALUE);
  m_delete(ignores,ign);
  // Kein Set() noetig
  return 1;
}

static int _query_intermud()
{
  mixed tmp;
  return member(pointerp(tmp=Query(P_CHANNELS))?tmp:({}), "Intermud") > -1;
}


int erwidere(string str)
{
  str=_unparsed_args();
  if (!str) return 0;
  return _tell(ERWIDER_PARAM, str ,1);
}

static int tmhist(string str)
{

  if (str == "aus") {
    tell_history_enabled = TELLHIST_DISABLED;
    write("Ok, es wird nichts mehr gespeichert.\n");
    if (sizeof(tell_history)) {
      clear_tell_history(1);
      write("Deine Mitteilungsgeschichte wurde geloescht.\n");
    }
    return 1;
  }
  if (str == "loeschen")
  {
    if (sizeof(tell_history)) {
      clear_tell_history(1);
      write("Deine Mitteilungsgeschichte wurde geloescht.\n");
    }
    else
      write("Deine Mitteilungsgeschichte war schon leer.\n");
    return 1;
  }

  if (str == "namen") {
    int flag;
    tell_history_enabled = TELLHIST_NO_MESSAGE;
    write("Ok, die Namen zukuenftiger Gespraechspartner werden gespeichert.\n");
    foreach (string uid, struct chat_s chat: tell_history)
      if (pointerp(chat->msgbuf)) {
        chat->msgbuf = 0;
        chat->ptr = 0;
        flag = 1;
      }
    if (flag)
      write("Der Inhalt Deiner Mitteilungen wurde geloescht.\n");
    return 1;
  }

  if (str == "ein" || str == "an") {
    tell_history_enabled = TELLHIST_ENABLED;
    write("Ok, zukuenftige Mitteilungen werden gespeichert.\n");
    return 1;
  }

  if (str == "langlebig") {
    tell_history_enabled = TELLHIST_LONGLIFE;
    write("Ok, zukuenftige Mitteilungen werden jeweils bis zum naechsten "
          "Ende/Crash/\nReboot gespeichert.\n");
    return 1;
  }

  if (str == "status") {
    switch (tell_history_enabled) {
      case TELLHIST_DISABLED:
        write("Die Namen Deiner Gespraechspartner werden nicht gespeichert.\n");
        break;
      case TELLHIST_NO_MESSAGE:
        write("Die Namen Deiner Gespraechspartner werden gespeichert.\n");
        break;
      case TELLHIST_ENABLED:
        write("Deine Mitteilungen werden gespeichert.\n");
        break;
      case TELLHIST_LONGLIFE:
        write("Deine Mitteilungen werden jeweils bis zum naechsten Ende/"
              "Crash/Reboot\ngespeichert.\n");
        break;
    }
    return 1;
  }

  if (tell_history_enabled == TELLHIST_DISABLED) {
    _notify_fail("Deine Gespraechspartner werden nicht gespeichert.\n");
    return 0;
  }

  if (!sizeof(tell_history)) {
    _notify_fail("Du hast noch keinem etwas mitgeteilt "
                 "und noch keine Mitteilungen erhalten.\n");
    return 0;
  }

  if (str && sizeof(str)) {

    if (tell_history_enabled < TELLHIST_ENABLED) {
      _notify_fail("Der Inhalt Deiner Mitteilungen wird nicht gespeichert.\n");
      return 0;
    }

    string uid;
    if (member(tell_history, str)) {
      // Name gewuenscht, da der String in der History vorkommt.
      uid = str;
    }
    else {
      // evtl. ne Zahl angegeben.
      int i;
      string *partners = sorted_commpartners(0);
      if ((i = to_int(str) - 1) >= 0 && i < sizeof(partners))
        uid = partners[i];
      else {
        notify_fail("Mit so vielen Leuten hast Du nicht gesprochen!\n");
        return 0;
      }
    }

    mixed *data = tell_history[uid]->msgbuf;
    if (!data) {
      _notify_fail(
        "Der Inhalt dieser Mitteilung ist nicht (mehr) gespeichert.\n");
      return 0;
    }

    int ptr = tell_history[uid]->ptr;

    More(sprintf("%@s", map(data[ptr..MAX_SAVED_MESSAGES-1] +
                              data[0..ptr-1],
         function string (struct kobold_msg_s msg) {
             if (!structp(msg)) return "";
               return break_string(terminal_colour(msg->msg, colourmap)
                 + " ["
                 + strftime("%H:%M:%S",msg->timestamp) + "]", 78,
                 msg->prefix || "", msg->prefix ? BS_LEAVE_MY_LFS : 0);
         } ) ) );
    return 1;
  }

  string history = "Folgende Gespraeche hast Du bereits gefuehrt:\n";
  int i;
  foreach (string uid : sorted_commpartners(0) ) {
    int j;
    struct chat_s chat = tell_history[uid];
    history += sprintf("%2d.%-4s %s  %-11s  %d gesendet/%d empfangen\n", ++i,
      ((j=member(commreceivers,uid))>-1 ? sprintf("/%2d.",j+1) : ""),
      strftime("%a, %e.%m.%y",chat->time_last_msg),
      capitalize(chat->uid), chat->sentcount, chat->recvcount);
  }

  More(history);

  return 1;
}

static mixed _query_localcmds()
{
  return ({
    ({"kobold", "cmd_kobold",0,0}),
     ({"sag","_communicate",0,0}),
     ({"sage","_communicate",0,0}),
     ({"'","_communicate",1,0}),
     ({"mruf","_shout_to_wizards",0,0}),
     ({"mrufe","_shout_to_wizards",0,0}),
     ({"ruf","_shout_to_all",0,0}),
     ({"rufe","_shout_to_all",0,0}),
     ({"erzaehl","_erzaehle",0,0}),
     ({"erzaehle","_erzaehle",0,0}),
     ({"teil","_teile",0,0}),
     ({"teile","_teile",0,0}),
     ({"tm","_teile_mit_alias",0,0}),
     ({"fluester","_whisper",0,0}),
     ({"fluestere","_whisper",0,0}),
     ({"rfluester","_remote_whisper",0,0}),
     ({"rfluestere","_remote_whisper",0,0}),
     ({"gespraech","_converse",0,0}),
     ({"echo","_echo",0,0}),
     ({"ignorier","ignoriere",0,0}),
     ({"ignoriere","ignoriere",0,0}),
     ({"tmhist","tmhist",0,0}),
     ({"erwider","erwidere",0,0}),
     ({"erwidere","erwidere",0,0}),
     ({"klingelton","_msg_beep",0,0}),
     ({"senderwiederholung","_msg_prepend",0,0}),
     ({"report","set_report",0,0}),
    })+channel::_query_localcmds();
}

private string *sorted_commpartners(int reversed) {
  return sort_array(m_indices(tell_history),
      function int (string uid1, string uid2) {
          if (reversed)
            return tell_history[uid1]->time_last_msg >
                   tell_history[uid2]->time_last_msg;
          else
            return tell_history[uid1]->time_last_msg <=
                   tell_history[uid2]->time_last_msg;
      } );
}

// Setzt den Prompt eines Interactives. Gerufen bei Objekterstellung,
// Reconnect und bei Magiern, wenn diese ihren Prompt oder ihr aktuelles
// Verzeichnis aendern.
static void modify_prompt() {
    string text = Query(P_PROMPT, F_VALUE);

    if ( !stringp(text) || !sizeof(text) )
        text = "> ";
    else {
        string path = Query(P_CURRENTDIR, F_VALUE);
        if (stringp(path) && sizeof(path))
          text = regreplace(text,"\\w",path,0); // Pfad einsetzen
    }
    configure_interactive(this_object(), IC_PROMPT, text);
}

// Prueft auf Ingoriereeintraege.
// Rueckgabe: 0 (nicht ignoriert) oder MSG_IGNORED
public int TestIgnore(string|string* srcnames)
{
  mapping ign = Query(P_IGNORE, F_VALUE);
  if (stringp(srcnames))
    srcnames = ({srcnames});

  foreach(string srcname: srcnames)
  {
    // einfachster Fall, exakter Match
    if (member(ign, srcname))
      return MSG_IGNORED;
    // ansonsten muss aufgetrennt werden.
    if (strstr(srcname,".") > -1)
    {
      string *srcparts=explode(srcname,".");
      switch(sizeof(srcparts))
      {
        // case 0 und 1 kann nicht passieren.
        case 3:
          // zu pruefen: [sender].aktion.qualifizierer.
          // Der Fall, dass der Spieler dies _genau_ _so_ ignoriert hat, wird
          // oben schon geprueft. im Spieler geprueft werden muss noch:
          // spieler, .aktion, spieler.aktion und .aktion.qualifizierer
          if ( (sizeof(srcparts[0]) && member(ign,srcparts[0])) // spieler
              || member(ign, "."+srcparts[1])      // .aktion
              || member(ign, srcparts[0]+"."+srcparts[1]) // [spieler].aktion
              || member(ign, "."+srcparts[1]+"."+srcparts[2]) // .akt.qual
             )
          {
            return MSG_IGNORED;
          }
          break;
        case 2:
          // zu pruefen: spieler.aktion
          // Der Fall, dass der Spieler das _genau_ _so_ eingegeben hat, ist
          // oben schon geprueft. Im Spieler zu pruefen ist noch:
          // spieler und .aktion
          if ((sizeof(srcparts[0]) && member(ign,srcparts[0]))
              || member(ign, "."+srcparts[1]))
          {
            return MSG_IGNORED;
          }
          break;
        default: // mehr als 3 Teile...
          raise_error(sprintf("TestIgnoreExt(): too many qualifiers, only 1 "
                "is supported. Got: %s\n",srcname));
      }
    }
  }
  // Default: nicht ignorieren.
  return 0;
}

#ifdef __LPC_UNIONS__
public int TestIgnoreExt(string|string* srcnames)
#else
public int TestIgnoreExt(mixed srcnames)
#endif
{
  return TestIgnore(srcnames);
}

// Prueft fuer ReceiveMsg() auf Ingoriereeintraege. Ignoriert aber nicht alle
// Typen. 
// Rueckgabe: 0 oder MSG_IGNORED | MSG_VERB_IGN | MSG_MUD_IGN
private int check_ignores(string msg, int msg_type, string msg_action,
                            string msg_prefix, object|string origin)
{
  // Einige Dinge lassen sich nicht ignorieren.
  if (msg_type & (MT_NEWS|MT_NOTIFICATION))
    return 0;
  // alles andere geht zur zeit erstmal, wenn origin bekannt UND NICHT das
  // eigene Objekt ist. Waer ggf. sonst doof. Ausserdem muss es natuerlich
  // eine ignorierbare msg_action geben.
  else if (stringp(msg_action) && origin && origin != ME)
  {
    string srcname;
    if (objectp(origin))
      srcname =
      (query_once_interactive(origin) ? origin->query_real_name()
                                      : origin->name(WER) || "");
    else
      srcname = origin;

    mapping ign = Query(P_IGNORE, F_VALUE);

    if (member(ign, srcname))
      return MSG_IGNORED;
    // vielleicht wird irgendwas a la name.aktion ignoriert?
    // dies ignoriert auch spieler.ebenen.<ebene> (s. msg_action bei
    // Ebenenmeldungen)
    if (member(ign, srcname+"."+msg_action))
      return MSG_VERB_IGN;
    // Oder die Aktion komplett? Dies ignoriert auch .ebenen.<ebene>, obwohl
    // das reichlich sinnfrei ist.
    if (member(ign, "."+msg_action))
      return MSG_VERB_IGN;
    // Spieler auf Ebenen ignoriert?
    // msg_action ist hier nach diesem Muster: MA_CHANNEL.<ebene>
    if (strstr(msg_action, MA_CHANNEL) == 0)
    {
      // spieler.ebenen? (spieler.ebenen.<ebene> oben schon geprueft)
      if (member(ign, srcname + "."MA_CHANNEL))
        return MSG_IGNORED;
      // spieler.ebenen.ebenenname ist oben schon abgedeckt.
      // .ebenen halte ich fuer sinnfrei, nicht geprueft.
    }
    // Spieler aus anderem mud? *seufz*
    if (strstr(srcname,"@") > -1)
    {
      string *srcparts = explode(srcname,"@");
      if (sizeof(srcparts)==2)
      {
        // spieler@?
        if (member(ign, srcparts[0]+"@"))
          return MSG_IGNORED;
        // oder Mud per @mud?
        if (member(ign, "@" + srcparts[1]))
          return MSG_MUD_IGN;
        // BTW: spieler@mud wurde schon ganz oben erfasst.
      }
    }
  }
  // Default: nicht ignorieren.
  return 0;
}

// Wird die nachricht wahrgenommen? Die Pruefung erfolgt aufgrund von
// msg_type. Zur wird MT_LOOK und MT_LISTEN beruecksichtigt (Pruefung auf
// BLindheit/Taubheit). In Zukunft koennten aber weitere Typen und weitere
// Kriterien wichtig werden und weitere Argumente uebergeben werden. (Dies
// bitte beachten, falls diese Funktion protected/public werden sollte.)
// Wichtig: enthaelt msg_action weder MT_LOOK noch MT_LISTEN, wird die
// Nachricht wahrgenommen, da davon ausgegangen wird, dass sie mit den beiden
// Sinn gar nix zu tun hat.
// Rueckgabe: 0 oder MSG_SENSE_BLOCK
private int check_senses(int msg_type)
{
  int senses = msg_type & (MT_LOOK|MT_LISTEN);
  // Wenn von vorherein kein Sinn angesprochen, dann ist es eine nachricht,
  // die von keinem der beiden wahrgenommen wird und sollte demnach nicht
  // unterdrueckt werden.
  if (!senses)
    return 0;
  
  int orig_senses = senses;
  
  if ((senses & MT_LOOK) && CannotSee(1))
    senses &= ~MT_LOOK;  // Sinn loeschen

  if ((senses & MT_LISTEN) && QueryProp(P_DEAF))
    senses &= ~MT_LISTEN;

  // Wenn kein Sinn mehr ueber ist oder all_types gesetzt ist und nicht mehr
  // alle Sinne vorhanden sind, wird die Nachricht nicht wahrgenommen.
  if (orig_senses == senses // kein Sinn geloescht, haeufigster Fall
      || (!(msg_type&MSG_ALL_SENSES) && senses) ) // min. ein Sinn uebrig
    return 0;

  return MSG_SENSE_BLOCK;
}

public int ReceiveMsg(string msg, int msg_type, string msg_action,
                              string msg_prefix, object origin)
{
  if (!msg) return MSG_FAILED;

  // Flags und Typen spalten
  int flags = msg_type & MSG_ALL_FLAGS;
  int type = msg_type & ~flags;

  // msg_action kommt per Defaultargument, msg_type hat per Default 0, daher
  // ggf. auch noch den Typ raten (leider geht msg_type nicht als
  // Defaultargument, da es *nach* msg_action ausgewertet werden muss, aber in
  // der Argumentliste leider *vor* msg_action kommt...
  type ||= comm_guess_message_type(msg_action, origin);

  // Debugmeldungen nur an Magier oder Testspieler mit P_WIZ_DEBUG
  if (msg_type & MT_DEBUG)
  {
    if (!QueryProp(P_WIZ_DEBUG)
        || (!IS_LEARNER(ME) && !QueryProp(P_TESTPLAYER)) )
    return MSG_FAILED;
  }

  // Zuerst werden Sinne und P_IGNORE sowie ggf. sonstige Filter geprueft. In
  // dem Fall ist direkt Ende, kein Kobold, keine Komm-History, keine
  // Weiterbearbeitung.
  // aber bestimmte Dinge lassen sich einfach nicht ignorieren.
  if (!(flags & MSG_DONT_IGNORE))
  {
    // Sinne pruefen.
    int res=check_senses(msg_type);
    if (res) return res;

    // Spieler-definiertes Ignoriere? (nur typen uebergeben, keine Flags)
    res=check_ignores(msg, type, msg_action, msg_prefix, origin);
    if (res) return res;
  }

  // Mentions in der Form @Charname werden in Kommunikation oder beim Hoeren
  // von Rufen und Sagen markiert und gegebenfalls gibt es ein Pieps dafuer
  int mention;
  if ((type & MT_COMM)
      || ((type & MT_LISTEN) && msg_action in ({MA_SAY, MA_SHOUT}))
      )
  {
    // Um den Charnamen Tags fuer terminal_colour() einfuegen.
    // Lookahead und Lookbehind assertions um die Whitespaces um das Wort
    // nicht in den Match einzuschliessen (und zu ersetzen).
    string tmp = regreplace(msg,
                    sprintf("(?<=\\s){0,1}@%s(?=\\s*){0,1}",getuid(ME)),
                    sprintf("%%^mention%%^@%s%%^normal%%^",
                            capitalize(getuid(ME))),
                    RE_PCRE|RE_GLOBAL|RE_CASELESS);
    send_debug(ME, tmp);
    // Der Vergleich ist weniger schlimm als es aussieht, weil die Strings
    // unterschiedlich gross sein werden und daher nicht zeichenweise
    // verglichen werden muessen. Es ist dann jedenfalls schneller als
    // getrennt mit regmatch oder strstr zu schauen, ob @charname
    // vorkommt.
    if (tmp != msg)
    {
        msg = tmp;
        mention = 1;
    }
  }

  // Fuer MT_COMM gibt es ein paar Sonderdinge zu machen.
  if ((type & MT_COMM))
  {
    // erstmal in der Komm-History ablegen, wenn gewuenscht.
    if ((!(flags & MSG_DONT_STORE)))
    {
      string uid;
      if (query_once_interactive(origin))
        uid = origin->query_real_name();
      else
        uid = origin->name(WER) || "<unbekannt>";
      add_to_tell_history(uid, 0, 1, msg, msg_prefix,
                          (msg_action == MA_TELL ? MSGFLAG_TELL : 0 ) );
    }

    // ggf. Uhrzeit bei abwesenden Spielern anhaengen, aber nicht bei
    // Ebenenmeldungen. (Die haben ggf. schon.)
    if (stringp(msg_action) && QueryProp(P_AWAY)
        && strstr(msg_action, MA_CHANNEL) != 0)
    {
      // Uhrzeit anhaengen, aber ggf. muss ein \n abgeschnitten werden.
      if (msg[<1] == '\n')
        msg = msg[0..<2]+" [" + strftime("%H:%M",time()) + "]\n";
      else
        msg = msg + " [" + strftime("%H:%M",time()) + "]";
    }
    // Kobold erlaubt und gewuenscht? Kobold ist fuer die
    // direkte Kommunikation mittels MT_COMM vorgesehen.
    // Oropax von Magiern leitet inzwischen auch nur in Kobold um statt zu
    // ignorieren.
    // die if-Konstruktion ist so, weil ich das _flush_cache() im else
    // brauche.
    if (query_editing(this_object()) || query_input_pending(this_object())
        || QueryProp(P_EARMUFFS))
    {
      if (!(flags & MSG_DONT_BUFFER)
            && (QueryProp(P_BUFFER) & KOBOLD_ONLINE))
      {
        // Nachricht soll im Kobold gespeichert werden.
        return add_to_kobold(msg, msg_type, msg_action, msg_prefix, origin);
      }
    }
    else
    {
      // wenn nicht in Editor/input_to, mal versuchen, den Kobold zu
      // entleeren.
      _flush_cache(0);
    }
  }

  // Farbtags ersetzen
  msg = terminal_colour(msg, colourmap);

  // Alertton senden?
  if ((msg_type & MSG_ALERT) || mention)
    comm_beep(msg_action, mention);

  // Ausgabenachricht bauen und an den Spieler senden.
  if (flags & MSG_DONT_WRAP)
    msg = (msg_prefix ? msg_prefix : "") + msg;
  else
  {
    int bsflags = flags & MSG_ALL_BS_FLAGS;
    if (QueryProp(P_MESSAGE_PREPEND))
      bsflags |= BS_PREPEND_INDENT;
    msg = break_string(msg, 78, msg_prefix, bsflags);
  }
  efun::tell_object(ME, msg);

  return MSG_DELIVERED;
}

// called from base.c in Reconnect()
protected void reconnect() {
  // Cache fuer den report zuruecksetzen, der koennte veraltet sein (insb.
  // falls in der letzten Session GMCP benutzt wurde und jetzt nicht).
  report_cache = 0;
}

protected void updates_after_restore(int newflag) {
  // Colourmap aktualisieren nach Restore
  colourmap = build_colourmap(QueryProp(P_TTY));

  // Altes Ignoriere loeschen...
  mixed ign = Query(P_IGNORE,F_VALUE);
  if (!mappingp(ign))
  {
    if (pointerp(ign))
      ReceiveNotify(break_string(
        "Deine Ignoriere-Einstellungen wurden soeben geloescht, "
        "weil es eine Aktualisierung der Ignorierefunktion gab, "
        "bei der eine Konversion der Daten leider nicht "
        "moeglich war.",78), 0);

    Set(P_IGNORE, ([]), F_VALUE);
  }
  // ggf. Comm-Vault abrufen oder neu erstellen.
  setup_comm_vault();
  // Wenn es eins gibt, den Inhalt zu unserem internen Koboldpuffer
  // hinzufuegen, von wo es spaeter angezeigt wird.
  if (commvault)
      process_comm_vault(commvault);

  // P_ALERT korrigieren. Das historische Originalverhalten war, bei P_ALERT
  // == 0 alle Klingeltoene abzuspielen. Default fuer heute soll die gezielte
  // Kommunikation an den Spieler einschliessen.
  if(!QueryProp(P_ALERT))
  {
    SetProp(P_ALERT, MB_TELL|MB_MENTION|MB_MISC);
  }
}

