//--------------------------------------------------------------------------------
// Name des Objects:    Aufbewahrungtruhe fuer Autoload-Objekte
//
// Magier:              Zesstra
//--------------------------------------------------------------------------------
#pragma strong_types,rtt_checks

#include "schrankladen.h"
inherit LADEN("swift_std_container");

//#include <ansi.h>
#include <class.h>
#include <wizlevels.h>
#include "/d/seher/haeuser/haus.h"

#define IDS     0
#define NAME   1
#define ALDATA  2

#define LOG(x,y) log_file(x,sprintf("%s [%s, %O, %O]: %s\n",dtime(time()),\
      (uuid?uuid:" "),PL,object_name(ME),y))
#define STORELOG(x) LOG("zesstra/ALTRUHE_STORE.log",x)
#define PICKLOG(x) LOG("zesstra/ALTRUHE_PICK.log",x)

#define ITEMLOG(x) log_file("zesstra/ALTRUHE_ITEMS.log",\
    sprintf("%s [%O]: %s\n",dtime(time()),\
      this_interactive()||PL,x))

#define ERRLOG(x) LOG("zesstra/ALTRUHE.ERR",x)

#undef BS
#define BS(x) break_string(x,78)

#define VERSION_OBJ "5"

#ifdef MAINTAINER
#undef MAINTAINER
#endif
#define MAINTAINER ({"zesstra"})

// Savefile der Blueprint
#ifdef SAVEFILE
#undef SAVEFILE
#endif
#define SAVEFILE __FILE__[..<3]

#define DEBUG(x)    if (funcall(symbol_function('find_player),MAINTAINER[0]))\
          tell_object(funcall(symbol_function('find_player),MAINTAINER[0]),\
                      "ALTruhe: "+x+"\n")

#define ACCESS (my_secure_level() >= ARCH_LVL)

// Diese 4 sind fuer die Blueprint (Master aller Truhen)
mapping whitelist=([]); // erlaubte Autoloader, alle anderen nicht erlaubt.
mapping blacklist=([]); // bereits explizit durch EM+ abgelehnte Autoloader
mapping vorschlaege=m_allocate(1,2); // vorschlaege der Spieler
mapping data=([]);  // hier speichert die BP alle Daten der Truhen
                    // WICHTIG: dieses Mapping wird in /secure/memory
                    // abgelegt und muss auch beim Neuladen ggf. von dort
                    // wieder abgeholt werden. Ausserdem teilen sich alle
                    // Truhen eines Spielers und diese Blueprint die Mappings
                    // darin, damit Aenderungen sofort in allen Truhen und dem
                    // Master bekannt sind.

/* die einzelnen Truhen speichern in autoloader. Format: 
   3 Werte pro Key, Keys sind die Namen der Blueprints der Objekte:
   ([<blueprint>: <P_IDS>; <ob->name()>; <P_AUTOLOADOBJ> ])
   */
nosave mapping autoloader=m_allocate(1,3);
nosave string uuid; // UUID des Eigentuemers
nosave object ob_in_bewegung; // uebler Hack eigentlich. :-(

void NotifyInsert(object ob, object oldenv);
static mapping QueryData();
static mapping SetData(mixed data);
protected void save_me();
protected void check_content();

nomask private int my_secure_level(); //Args.

protected void create() {

  // Ja, es is Absicht, dass das create der BP erst spaeter abgebrochen wird!
  swift_std_container::create();

  seteuid(getuid(ME));

  // falls dies die BP ist:
  // 1. das Savefile zu laden.
  // 2. versuchen, die truhendaten von /secure/memory zu holen, damit nach dem
  //    Neuladen der Master und die Client immer nach _dieselben_ Mappings
  //    haben.
  if (!clonep(ME))
  {
    // Savefile restaurieren (auch wenn data im Memory ist, muss das sein,
    // damit die anderen Variablen wieder eingelesen sind).
    restore_object(SAVEFILE);
    // jetzt Daten aus Memory holen, sofern verfuegbar
    mapping tmp = "/secure/memory"->Load("truhendaten");
    if (mappingp(tmp))
    {
      // Daten aus Savefile durch die vom Memory ersetzen
      data = tmp;
    }
    else
    {
      // Keine Daten in Memory. Jetzt in jedem Fall den Pointer auf das Mapping data in
      // /secure/memory ablegen
      if ("/secure/memory"->Save("truhendaten",data) != 1)
      {
        raise_error("Could not save memory to /secure/memory.");
      }
    }
  }
  else
  {
    // brauchen Clones nicht.
    set_next_reset(-1);
    data=0; // brauchen Clones nicht.
  }

  SetProp(P_SHORT, "Eine kleine, magische Holztruhe");
  SetProp("cnt_version_obj", VERSION_OBJ);
  SetProp(P_NAME, "Holztruhe");
  SetProp(P_GENDER, FEMALE);
  SetProp(P_NAME_ADJ,({"klein", "magisch"}));
  SetProp(P_LONG, BS(
     "Die kleine Holztruhe ist aus stabilem Eichenholz gefertigt. Eigentlich "
     "saehe sie recht unscheinbar aus, waeren da nicht die vielen kunstvollen "
     "Runen an den Seiten und auf dem Deckel.")
    +"@@cnt_status@@");

  AddId(({"autoloadertruhe", "holztruhe", "truhe"}));

  // den Rest vom Create braucht die BP nicht.
  if (!clonep(ME)) return;

  SetProp(P_LOG_FILE,"zesstra/ALTRUHE.rep");

  SetProp(P_WEIGHT, 3000);         // Gewicht 5 Kg
  // die drei hier sind in diesme Fall eigentlich voellig ohne Bedeutung
  SetProp(P_MAX_WEIGHT, 1000000);  // Es passen fuer 1000 kg Sachen rein.
  SetProp(P_WEIGHT_PERCENT, 100);
  SetProp(P_MAX_OBJECTS, 100);     // sind eh immer 0 echte Objekte drin.

  SetProp(P_VALUE, 0);             // Kein materieller Wert. Ist eh nicht verkaufbar.
  SetProp(P_NOBUY, 1);             // Wird im Laden zerstoert, falls er verkauft wird.
  SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
  SetProp(P_MATERIAL, ([MAT_OAK:49, MAT_MISC_MAGIC:50, MAT_JOFIUM: 1]) );
  SetProp(P_INFO, BS("In diese stabile Truhe kannst Du bestimmte "
        "Autoload-Objekte hineinlegen und sie lagern, wenn Du sie gerade "
        "nicht brauchst. (Mit 'deponiere <was>' kannst Du etwas in der "
        "Truhe zur Aufbewahrung deponieren, mit 'entnehme <was> oder "
        "'nimm <was> aus truhe' kannst Du einen Gegenstand wieder "
        "herausnehmen.)"));

  // Prop fuer rebootfeste Moebel
  // Der endgueltige Wert (UUID des Spielers) wird per SetBesitzer() gesetzt,
  // sobald die Truhe das erste Mal in ein Seherhaus bewegt wurde.
  SetProp(H_FURNITURE, 1);

  AD(({"platz","groesse"}), 
      BS("Die Truhe ist recht klein, aber merkwuerdigerweise "
        "scheint sie viel mehr an Gegenstaenden aufnehmen zu koennen, als "
        "es von ihrer Groesse her scheint."));
  AD(({"gegenstand","gegenstaende"}),
      BS("Die Truhe scheint zwar vielen Gegenstaenden Platz zu bieten, aber "
        "dafuer nimmt sie nicht jeden Gegenstand auf."));
  AD(({"holz","eichenholz"}),
      BS("Das Eichenholz ist sehr stabil. Es ist ganz glatt geschliffen und "
        "traegt viele kunstvolle Runen in sich."));
  AD(({"seiten","seite"}),
      BS("Die Truhe hat 4 Seiten, die allesamt mit Runen verziert sind."));
  AD(({"boden"}),
      BS("Der Boden der Truhe traegt keinerlei Runen."));
  AD(({"deckel"}),
      BS("Auch der Deckel der Truhe ist mit Runen verziert."));
  AD(({"runen","rune"}),
      BS("Die Runen bedecken alle 4 Seiten und den Deckel der Truhe. Man "
        "hat sie zweifellos in muehsamer Arbeit aus dem harten Holz "
        "geschnitzt. Anschliessend wurden sie offenbar mit einem "
        "Metall gefuellt. Du verstehst zwar ueberhaupt nicht, was "
        "die Runen bedeuten, aber sie sind bestimmt magisch, denn wann immer "
        "Du den Deckel oeffnest oder schliesst oder Gegenstaende hineinlegst "
        "oder herausnimmst, leuchten die Runen hell auf."));
  AD(({"metall"}),
      BS("Was das wohl fuer ein Metall sein mag? Zweifellos hat es auch was "
        "mit Magie zu tun."));
  AD(({"magie"}),
      BS("In dieser Truhe scheint viel Magie zu stecken, wenn selbst ein "
        "Weltuntergang ihr nichts anhaben kann."));
  AD(({"arbeit","fertigung"}),
      BS("Die Fertigung dieser Truhe muss sehr aufwendig gewesen sein. "
        "Kein Wunder, dass die Truhe so teuer ist."));
  AD(({"wunder"}),
      BS("Ein Wunder scheint es zu sein."));
  AD(({"weltuntergang","armageddon"}),
      BS("Dir schaudert beim Gedanken an den Weltuntergang."));
  AD(({"gedanken"}),
      BS("Denk doch lieber an was anderes..."));

  AddCmd("deponier|deponiere&@PRESENT","cmd_deponiere",
      "Was moechtest Du in der Eichenholztruhe deponieren?");
  AddCmd("entnimm|entnehme|entnehm","cmd_entnehmen");

  // bei dieser Truhe waere das Erlauben voellig sinnlos. ;-)
  RemoveCmd(({"serlaube"}));

}

// keine Truhen zerstoeren, die irgendeinen INhalt haben.
int zertruemmern(string str) {
  // aus swift_std_container
  string nf_str;
  nf_str="Syntax: zertruemmer [Objekt-Id]\n"
        +"Bsp.:   zertruemmer "+QueryProp(P_IDS)[1]+"\n";
  notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
  if(!str) return 0;
  notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
  if(present(str)!=TO)   // Ueberpruefe, ob auch dieses Objekt gemeint ist!
    return 0;
  if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
  {
    write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" zertruemmern!"));
    return 1;
  }
  // Objekte enthalten? Wenn ja, abbruch.
  if (sizeof(autoloader)) {
    tell_object(PL,BS("Du willst gerade zum Schlag ausholen, um "
          +name(WEN,1)+ " zu zertruemmern, als Dir einfaellt, dass "
          +QueryPronoun(WER)+ " ja gar nicht leer ist! Nene, wer weiss, ob "
          "Du das nicht noch brauchen koenntest."));
    return 1;
  }
  // sonst geerbten Kram ausfuehren.
  return ::zertruemmern(str);
}

// Zesstra, 1.7.07, fuers Hoerrohr
string GetOwner() {return "zesstra";}

// Prueft das Objekt auf Eignung fuer die Truhe, speichert seine Daten und
// zerstoert es anschliessend. NODROP-Objekte koennen nur so in die Truhe
// gelegt werden, alle anderen koennen auch mit "stecke ... in truhe"
// deponiert werden, woraufhin ebenfalls PreventInsert() und NotifyInsert()
// durchlaufen werden.
protected int cmd_deponiere(string cmd, mixed args) {
  if (!objectp(PL)) return 0;

  notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
  if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;
  
  notify_fail("Was moechtest Du in der Eichenholztruhe deponieren?\n");
  if (!stringp(cmd) || !sizeof(cmd) 
      || !pointerp(args) || !sizeof(args)) return 0;
  object ob=args[0];
  if (!objectp(ob)) return 0;
  // wuerde die Truhe das Objekt ueberhaupt aufnehmen? Fehlerausgabe durch
  // PrevenInsert()
  if (PreventInsert(ob)) return 1;
  // Ausziehen... Schade, dass DoUnwear nix vernuenftiges an Rueckgabewert
  // hat. :-(
  if (objectp(ob->QueryProp(P_WORN))) {
    ob->DoUnwear();
    if (objectp(ob->QueryProp(P_WORN))) {
      tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
            "ausziehen!"));
      return 1;
    }
  }
  // wegstecken
  if (objectp(ob->QueryProp(P_WIELDED))) {
    ob->DoUnwield();
    if (objectp(ob->QueryProp(P_WIELDED))) {
      tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
            "wegstecken!"));
      return 1;
    }
  }
  // NO_CHECK und Silent-Bewegung, Meldungen an den Spieler selber machen.
  tell_object(PL, BS("Du steckst "+ ob->name(WEN,1) + " in " + name(WEN,1) +
      "."));
    
  tell_room(environment(),BS(PL->Name(WER) + " legt " + ob->name(WEN,0) +
      " in " + name(WEN,1) + " hinein."),({PL}));
  ob->move(ME, M_NOCHECK|M_SILENT);
  return 1;
}

// alternative zum "nimm bla aus truhe". Spieler wollten was kurzes dafuer
// haben.
protected int cmd_entnehmen(string cmd) {
  int res;
  mixed noget;

  if (!objectp(PL)) return 0;

  notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
  if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;

  notify_fail(BS("Was moechtest Du aus "+name(WEM,1)+ " entnehmen?\n"));
  if (!stringp(cmd) || !sizeof(cmd)) return 0;

  object *obs=present_objects(cmd);

  if (!sizeof(obs) || !objectp(obs[0]))
    return 0;

  // NOGET ist hier bloed. So ist es zwar auch nicht richtig doll... *seufz*
  // Die hier ist/waere aber nen uebler Hack, erstmal auskommentiert lassen.
  // also, P_NOGET sichern.
  /*if (!closurep(noget=ob->Query(P_NOGET,F_QUERY_METHOD))) {
    noget=ob->Query(P_NOGET,F_VALUE);
    ob->Set(P_NOGET,0,F_VALUE);
  }
  else {
    ob->Set(P_NOGET,0,F_QUERY_METHOD);
  }*/
  // nehmen.
  res=PL->pick_obj(obs[0]);
  // P_NOGET zurueckschreiben. (Ja, wenn eine Closure als F_VALUE drinsteht,
  // landet die jetzt als F_QUERY_METHOD im Objekt.
  /*if (closurep(noget)) {
    ob->Set(P_NOGET,noget,F_QUERY_METHOD);
  }
  else
    ob->Set(P_NOGET,noget,F_VALUE);
*/
  return(res);
}

// Hier wird auch das PreventInsert() von der Blueprint gerufen. Das
// erleichtert es, die Liste an erlaubten Objekten zu aendern, ohne dass man
// alle Clones ersetzen muss.
varargs int PreventInsert(object ob) {
  string oname;
  // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
  if (!objectp(ob) || ob_in_bewegung==ob) return 0;
  
  oname=BLUE_NAME(ob);
  
  // Pruefung in Clonen:
  if (clonep(ME))
  {
    // nur Eigentuemer
    if (!stringp(uuid) || !sizeof(uuid)) {
      if (objectp(PL))
        tell_object(PL,BS(sprintf("%s gehoert Dir nicht, daher kannst Du "
            "auch keine Gegenstaende in %s legen.",
            Name(WER,1),QueryPronoun(WEN))));
      return 1;
    }
    if (!objectp(PL) || getuuid(PL)!=uuid) {
      if (objectp(PL))
        tell_object(PL,BS(sprintf("Nur %s darf Gegenstaende in %s "
          "hineinlegen.",capitalize(explode(uuid,"_")[0]),name(WEN,1))));
      return 1;
    }
    // jedes Objekt nur einmal.
    if (member(autoloader,oname)) {
      if (objectp(PL))
        tell_object(PL,BS(Name(WER,1)+ " kann von einem Gegenstand jeweils "
          "nur ein Exemplar aufnehmen, es ist aber bereits "
          +ob->name(WER,0) + " in " + QueryPronoun(WEM) + "."));
      return 1;
    }
    // jetzt Erlaubnisliste der BP fragen.
    if (objectp(blueprint(ME)))
      return blueprint(ME)->PreventInsert(ob);
    else
      return load_object(load_name(ME))->PreventInsert(ob);
  }
  // Ende fuer Pruefung fuer Clone.

  // ab hier jetzt die Pruefung durch die BP.
  // Keine (freigegebener) Autoloader? Hat in diesem Container nix verloren!
  if( !ob->QueryProp(P_AUTOLOADOBJ) ) {
    if (objectp(PL))
      tell_object(PL,BS("In "+name(WEN,1)
            +" kannst Du nur Autoload-Objekte hineinlegen. "));
    return 1;
  }
  else if (member(blacklist,oname)) {
    if (objectp(PL))
      tell_object(PL,BS("In "+name(WEN,1)
            +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
            +ob->Name(WER,1) + " wurde explizit als nicht erwuenscht "
            "befunden."));
    return 1;
  }
  else if (!member(whitelist,oname)) {
    if (!member(vorschlaege,oname)) {
      vorschlaege[oname,0]=ob->name(WER,0) || "";
      vorschlaege[oname,1]=ob->short() || "";
    }
    if (objectp(PL))
      tell_object(PL,BS("In "+name(WEN,1)
            +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
            +ob->Name(WER,1) + " ist momentan nicht auf der Liste. Der "
            "Gegenstand wurde jetzt als Vorschlag gespeichert. Bitte hab "
            "etwas Geduld, bis sich jemand den Gegenstand angeschaut hat."));
    // ggf. reset reaktivieren und Maintainer informieren.
    if (!query_next_reset())
      set_next_reset(1);
    return 1;
  }
  // getragenes?
  if (ob->QueryProp(P_WORN)) {
      ob->DoUnwear(0);
      if (ob->QueryProp(P_WORN)) { //ARGL. GRUMMEL.
        if (objectp(PL))
          tell_object(PL,BS("Willst Du "+ob->name(WEN,1) + " nicht erstmal "
                "ausziehen?"));
        return 1;
      }
  }
  // enthaelt es irgendwelche anderen Objekte?
  if (sizeof(all_inventory(ob))) {
      if (objectp(PL))
        tell_object(PL,BS(ob->Name(WER,1) + " ist nicht leer."));
      return 1;
  }

  // andere Einschraenkungen, als hier geprueft werden, gibt es nicht.
  return 0;
}

// hier ist das Objekt jetzt in der Truhe, d.h. Daten speichern und Objekt
// destructen. ;)
void NotifyInsert(object ob, object oldenv) {

  // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
  if (!objectp(ob) || ob==ob_in_bewegung)
    return;
  STORELOG(sprintf("%s deponiert %s [%O], Daten: %O",getuid(PL),ob->name(WEN,0),
        ob,ob->QueryProp(P_AUTOLOADOBJ)));
  // noetig sind die IDs, den Namen und die AUTOLOADOBJ-Daten des Objekts.
  // ;-)
  autoloader[BLUE_NAME(ob),ALDATA]=ob->QueryProp(P_AUTOLOADOBJ);
  autoloader[BLUE_NAME(ob),IDS]=ob->QueryProp(P_IDS);
  // Objekte, die 0 als short liefern, kriegen eine Standard-Short und werden
  // sichtbar gemacht, da sie sonst nicht wiederzufinden sind. Objekte, die
  // unsichtbar sein sollen, duerfen nicht erlaubt werden.
  // TODO eine ID als Short nehmen?
  autoloader[BLUE_NAME(ob),NAME]=capitalize((ob->short()||"<Unbekannt>.\n")[..<3]);
  // nach dem Move die realen Objekte destructen.
  call_out(#'check_content, 0);
  save_me();
}

// Objekt wurde entnommen, also aus der Liste der enthaltenen Autoloader
// loeschen. Ausserdem Objekt konfigurieren. Dies wird erst hier gemacht und
// nicht in create_object(), damit es so aehnlich wie moeglich zum clonen der
// Autoloader beim erstellen des Spielerobjektes wird (dort wird erst bewegt,
// dann konfiguriert).
void NotifyLeave(object ob, object dest) {
  string error, oname;
 
  if (!objectp(ob))
    return;
  
  oname=BLUE_NAME(ob);
  if (!member(autoloader,oname)) {
    // Das sollte definitiv nicht passieren.
    ERRLOG(sprintf("Gegenstand (%O) wurde entnommen, der nicht "
      "gespeichert war!",ob));
    return;
  }

  // wenn kein Fehler: Objekt aus Liste loeschen. Sonst wird das Objekt
  // zerstoert. Damit bleiben die Autoloader-Daten hier erhalten und der
  // Spieler hat kein disfunktionales Objekt im Inventar.
  if (error) {
    ERRLOG(sprintf("Fehler beim Konfigurieren von %O. Fehlermeldung: %O."
        "Daten: %O",ob,error,autoloader[oname,ALDATA]));
    ob->remove(1);
    if (objectp(ob))
      destruct(ob);
  }
  else {
    PICKLOG(sprintf("Objekt (%O) wurde entnommen.",ob));
    m_delete(autoloader,oname);
    // speichern
    save_me();
  }
}

protected void check_content() {
  // wenn Objekte noch in der Truhe sind, also nicht erfolgreich in
  // einen Spieler bewegt wurden, werden zerstoert. Datenverlust gibt es
  // hierbei nicht, weil die Daten der Autoloader nur durch NotifyLeave()
  // geloescht werden.
  foreach(object ob: all_inventory()) {
    ob->remove(1);
    if (objectp(ob)) destruct(ob);
  }
}

// hier nochmal schauen, ob das Objekt auch in den richtigen Spieler bewegt
// wird... Falls das move dann hier abgebrochen wird, wird das Objekt im
// naechsten HB von der Truhe zerstoert. (chk_contents())
varargs int PreventLeave(object ob, mixed dest) {
  object ob2;
  
  //DEBUG(sprintf("PreventLeave(): Ob: %O, Dest: %O (%O)",
  //        ob,dest,(objectp(dest)?"Objekt":"Non-Object")));

  if (!objectp(ob)) return 0; 
  // falls string uebergeben, erstmal zug. Spieler finden.
  if (stringp(dest) && sizeof(dest))
    dest=find_player(dest);

  // richtiges INteractive? Dann darf das Objekt raus. Sonst nicht. ;-)
  if (!objectp(dest) || !interactive(dest) || getuuid(dest)!=uuid)
      return 1;

  // pruefen, ob der Spieler schon ein Objekt dieser Blueprint dabei hat. Wenn
  // ja, Abbruch, das koennte sonst zuviele Probleme geben.
  if (objectp(ob2=present_clone(ob,dest))) {
    tell_object(dest,BS("Du hast bereits "+ob2->name(WEN,0) +
        " dabei. Zwei Gegenstaende dieser Art kannst du nicht gleichzeitig "
        "mit Dir herumtragen."));
    return 1; //nicht rausnehmen.
  }
  return 0;
}

// Objekte ausgeben, die hier angeblich drin sind. ;-) Gibt aber nur die
// Autoloader aus, keine echten Objekt, die Container sind. Allerdings sollte
// sowas eh nicht vorkommen. ;-)
// flags: 1 - return array, 2 - don't collect equal objects '
// flags: 4 - don't append infos for wizards
varargs mixed make_invlist(object viewer, mixed inv, int flags) {
  int iswiz;
  mixed objs;

  iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
  // Mapping benutzen, um multiplen Overhead fuer allokation im foreach() zu
  // vermeiden.
  objs=m_allocate(sizeof(autoloader),1);
  foreach(string oname, string *ids, string sh: autoloader) {
    if (iswiz && !(flags & 4))
      objs[oname]=sh + ". ["+oname+"]";
    else
      objs[oname]=sh + ".";
  }
  if(flags & 1) return(m_values(objs)-({""}));
  if(!sizeof(autoloader)) return "";
  return sprintf("%"+(sizeof(objs) > 6 ? "#" : "=")+"-78s",
                 implode(m_values(objs)-({""}), "\n")) + "\n";
}

// erzeugt das benannte Objekt und liefert es zurueck. Liefert 0 im Fehlerfall.
// ausserdem bewegt es das Objekt in die Truhe, damit es ein Env hat und die
// Truhe via NotifyLeave() mitkriegt, dass es tatsaechlich entnommen wurde.
private object create_object(string oname) {
  string error;
  object ob;
  mixed noget;
  if (!member(autoloader,oname)) return 0;

  //Blueprint finden (ja, das ist nicht unbedingt noetig, man koennte auch
  //direkt clonen)
  if (error=catch(ob=load_object(oname);publish) ||
      !objectp(ob)) {
    ERRLOG(sprintf("Konnte %s nicht laden/finden. Fehler: %O",
          oname,error));
    return 0;
  }
  // clonen
  if (error=catch(ob=clone_object(oname);publish) ||
      !objectp(ob)) {
    ERRLOG(sprintf("Konnte %s nicht clonen. Fehler: %O",
        oname,error));
    return 0;
  }
  // konfigurieren
  error=catch(ob->SetProp(P_AUTOLOADOBJ,autoloader[oname,ALDATA]);publish);

  //Objekt bewegen, dabei Objekt in glob. Var. merken, damit PreventInsert()
  //und NotifyInsert() es ignorieren. *seufz*
  ob_in_bewegung=ob;
  ob->move(ME,M_NOCHECK);
  ob_in_bewegung=0;

  // jetzt noch nen Callout starten, damit das Objekt zerstoert wird, wenn es
  // nicht wirklich in einen Spieler bewegt wird.
  call_out(#'check_content,1);

  return(ob);
}

// Schauen, ob die truhe ein Objekt mit passender ID enthaelt. Wenn
// ja, das Objekt erzeugen und zurueckliefern. 
// Diese Funktion hat eine Reihe von Nachteilen bzw. Defiziten ggue. der
// normalerweise in Containern definierten Funktion:
// - Nur das erste Objekt, auf das id passt. Ich hab erstmal keine Lust,
//   hier mehrere Objekte zu erzeugen. Mal schauen, ob es so geht. Auch waere
//   es ein Problem, wenn viele Objekt die Evalgrenze bzw. nicht alle in den
//   Spieler bewegt werden, nachdem sie erzeugt wurden.
// - keine komplexen Ausdruecke, nur reine IDs.
// Ich halte den Aufwand fuer nicht gerechtfertigt.
object *present_objects( string complex_desc ) {
  object ob;
  if (!stringp(complex_desc) || !sizeof(complex_desc))
      return ({});
  // diese Funktion liefert nur Objete zurueck, wenn der richtige Interactive
  // versucht, sie zu entnehmen. ;-)
  if (!objectp(this_interactive()) ||
      getuuid(this_interactive())!=uuid)
      return ({});

  // "alles" liefert das erstbeste Objekt.
  if (complex_desc=="alles" && sizeof(autoloader))
  {
    string oname=m_indices(autoloader)[0];
    ob=create_object(oname);
    if (objectp(ob)) return ({ob});
  }

  // ueber alle Eintraege gehen, bis eine ID stimmt, erstes passendes Objekt
  // erzeugen und in einem Array zurueckliefern.
  foreach(string oname, string *ids: autoloader) {
    if (member(ids,complex_desc)==-1) continue;
    ob=create_object(oname);
    break; //objekt gefunden, fertig hier
  }
  if (objectp(ob)) return ({ob});
  return ({}); // nix gefunden
}



// ******************* Verwaltung *********************************

// registriert die Truhe auf den jeweiligen Eigentuemer.
protected void SetBesitzer(string unused, string newuuid) {
  if (!stringp(newuuid) || !sizeof(newuuid)) return;
  // wenn schon registriert, abbrechen
  if (stringp(uuid) && sizeof(uuid)) return;

  uuid=newuuid;
  Set(H_FURNITURE,uuid,F_VALUE); //Setmethode umgehen, sonst Rekursion 
  // ab jetzt nur noch von der Truhe selber.
  Set(H_FURNITURE,SECURED,F_MODE_AS);
  
  // Daten fuer den Benutzer aus der Blueprint holen (BP liefert KEINE Kopie
  // und es darf KEINE gemacht werden!):
  autoloader=(mapping)load_name()->GetData(uuid);
  
  // keine Daten gekriegt? -> Fehler loggen
  if (!mappingp(autoloader))
  {
    ERRLOG(sprintf("Keine gueltigen Daten vom Truhenmaster (BP) erhalten. "
        "initialisiere mit leerem Mapping. :-("));
    raise_error(sprintf(
          "Keine gueltigen Daten vom Truhenmaster (BP) fuer UUID %s "
          "erhalten.\n",uuid));
  }
}

// Set-Funktion
string _set_h_furniture(mixed arg) {
  if (stringp(arg))
  {
    SetBesitzer(0,arg); // bricht ab, wenn bereits registriert.
  }
  return(uuid);
}

// Falls das Speichern in der BP nicht klappte, rufen die Clones diese
// Funktion. Schreiben der Daten in in Logfile zur Restaurieren per Hand.
private void EmergencyStore(int res) {
    ERRLOG(sprintf("EmergencyStore() called. Rueckgabewert des "
        "Truhenmaster (BP) war: %O. Speichere Daten in Logfile. ",res));
    write_file(__DIR__+"ALTRUHE.NOTFALLDATEN",
        sprintf("Daten fuer %O:\n%O\n",uuid,autoloader));
}

protected void save_me() {
  int res;
  // nur BP speichern
  if (!clonep(ME))
    save_object(SAVEFILE);
  else
  {
    if (objectp(blueprint(ME)))
      res=(int)blueprint(ME)->StoreData(uuid,autoloader);
    else
      res=(int)load_object(load_name(ME))->StoreData(uuid,autoloader);

    if (res!=1)
      EmergencyStore(res); // Daten in einem Notfall-Logfile ablegen.
  }
}


// diese Funktion wird vom Seherhausraum gerufen, sobald ein rebootfestes
// Moebelstueck erzeugt und konfiguriert wurde.
void post_create() {
    if (!clonep()) return;

    // wenn jetzt kein Env: destructen
    if (!objectp(environment())) {
        remove(1);
        return;
    }
    //beim Schrankmaster registrieren
    SCHRANKMASTER->RegisterCnt(ME, QueryProp("cnt_version_std")
      +":"+QueryProp("cnt_version_obj"), environment()->QueryOwner(),
       environment());
}

// diese Funktion wird vom Schrankmaster gerufen, wenn dieser meint, dass
// dieses Objekt neu erstellt werden sollte.
int UpdateMe()
{
  if (!clonep())
    return 0;
  if (!objectp(environment()))
    return 1;
  object ob=clone_object(load_name(ME));
  if (objectp(ob)) {
    object oldenv=environment();
    // UUID uebertragen
    ob->SetProp(H_FURNITURE, uuid);
    // hierhier bewegen, dabei werden UUID und Daten von der neuen Truhe meist
    // automatisch geholt.
    ob->move(oldenv,M_NOCHECK);
    // jetzt erst post_create() rufen!
    ob->post_create();
    // dieses Objekt rausbewegen (damit das Seherhaus es austraegt).
    move("/room/void",M_NOCHECK);
    // Seherhausraum speichern (koennte teuer sein!)
    oldenv->Save(1);
    // selbstzerstoeren
    // __INT_MAX__ bedeutet: nicht speichern, die neue Truhe hat die daten
    // schon aus der BP abgefragt.
    remove(__INT_MAX__);
  }
  return(1);
}

// bei Selbstzerstoerung speichern bzw. Daten an die Blueprint uebermitteln
// und beim Schrankmaster abmelden.
varargs int remove(int silent) {
  string uid="";

  // Blueprint speichern im Savefile, Clones uebertragen die Daten hier an die
  // Blueprint. Clones nur, wenn nicht __INT_MAX__ uebergeben wurde.
  if (silent!=__INT_MAX__ || !clonep())
    save_me();

  if (clonep()) {
    // Clone melden sich beim Schrankmaster ab.
    if (objectp(environment())) {
        uid=environment()->QueryOwner();
    }
    //beim Schrankmaster deregistrieren
    SCHRANKMASTER->RemoveCnt(ME,uid);
  }
  return(::remove(silent));
}

// ***************** NUR BLUEPRINTS *********************************

// neuen Autoloader zulassen (nur EM+!)
varargs int AddAutoloader(string path,string nam) {
  object ob;
  if (clonep(ME)) return 0;
  if (!stringp(path) || !sizeof(path)) return -1;
  if (!ACCESS) return -2;
  //if (!ARCH_SECURITY) return -2;
  if (member(whitelist,path)) return -3;
  if (catch(ob=load_object(path);publish)
      || !objectp(ob))
      return -4;
  // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
  if (!stringp(nam) || !sizeof(nam)) {
      nam=ob->name(WER,0);
      if (!stringp(nam) || !sizeof(nam)) return -5;
  }
  ITEMLOG(sprintf("%s erlaubt: %s (%s)\n",getuid(this_interactive()),
          path,nam));
  whitelist+=([path:capitalize(nam)]);
  if (member(vorschlaege,path))
    m_delete(vorschlaege,path);
  save_me();
  return(1);
}

// Autoloader aus Erlaubnisliste entfernen (nur EM+!)
int RemoveAutoloader(string path) {
  if (clonep(ME)) return 0;
  if (!stringp(path) || !sizeof(path)) return -1;
  if (!ACCESS) return -2;
  //if (!ARCH_SECURITY) return -2;
  if (!member(whitelist,path)) return -3;
  ITEMLOG(sprintf("%s widerruft Erlaubnis: %s (%s)\n",getuid(this_interactive()),
          path,whitelist[path]));
  whitelist-=([path]);
  save_me();
  return(1);
}

// erlaubte Autoloader abfragen
mapping QueryAutoloader() {
  return(copy(whitelist));
}

// neuen Autoloader in Blacklist eintragen (nur EM+!)
varargs int AddBlacklist(string path, string nam) {
  object ob;
  if (clonep(ME)) return 0;
  if (!stringp(path) || !sizeof(path)) return -1;
  if (!ACCESS) return -2;
  //if (!ARCH_SECURITY) return -2;
  
  if (member(blacklist,path)) return -3;

  if (catch(ob=load_object(path);publish)
      || !objectp(ob))
      return -4;
  // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
  if (!stringp(nam) || !sizeof(nam)) {
      nam=ob->name(WER,0);
      if (!stringp(nam) || !sizeof(nam)) return -5;
  }
  // ggf. erlaubten entfernen.
  if (member(whitelist,path))
    RemoveAutoloader(path);
  ITEMLOG(sprintf("%s verbietet: %s (%s)\n",getuid(this_interactive()),
          path,nam));

  blacklist+=([path:capitalize(nam)]);

  if (member(vorschlaege,path))
    m_delete(vorschlaege,path);

  save_me();
  return(1);
}

// Autoloader aus Blacklist entfernen (nur EM+!)
int RemoveBlacklist(string path) {
  if (clonep(ME)) return 0;
  if (!stringp(path) || !sizeof(path)) return -1;
  if (!ACCESS) return -2;
  //if (!ARCH_SECURITY) return -2;
  if (member(blacklist,path)==-1) return -3;
  ITEMLOG(sprintf("%s loescht: %s (%s) von Blacklist\n",getuid(this_interactive()),
          path,blacklist[path]));
  blacklist-=([path]);
  save_me();
  return(1);
}

// gesperrte Autoloader abfragen
mapping QueryBlacklist() {
  return(copy(blacklist));
}

// vorschlaege abfragen
varargs mixed QueryVorschlaege(int format) {
  string res="\n";
  if (!format) return(copy(vorschlaege));

  foreach(string oname, string nam, string sh: vorschlaege) {
    res+=sprintf("%.78s:\n   %.37s,%.37s\n",oname,nam,sh); 
  }

  if (format==2 && objectp(PL))
    tell_object(PL,res);
  else
    return res;
  return 0;
}

// Wird diese funktion in der Blueprint gerufen, liefert sie die Daten fuer
// eine Truhe mit dieser UUID zurueck. Aber nur dann, wenn die auch von einer
// truhe abgerufen wird und keinem beliebigen anderen Objekt oder wenn ein EM
// abfragt.
mapping GetData(string uid) {
  if (clonep(ME)) return 0;
  if (extern_call())
  {
    if (!objectp(previous_object())) return 0;
    if (blueprint(previous_object()) != ME
        && load_name(previous_object()) != __FILE__[..<3]
        && !ACCESS)
        return(0);
  }
  if (!stringp(uid)) return ([]);

  if (!member(data, uid))
    data[uid] = m_allocate(1,3);

  // Absichtlich keine Kopie, damit die Truhen (falls jemand mehrere kauft)
  // sich alle eine Kopie des Mappings teilen.
  return data[uid];
}

// Loest die Speicherung der Daten im Savefile aus, denn irgendwelche Daten
// haben sich in einem Clone geaendert, welche noch auf die Platte muessen.
// Diese Funktion speicherte frueher Daten aus den Clones wieder im Mapping
// des Masters (der Blueprint). Dies ist heute nicht mehr so, weil alle Truhen
// (eines Benutzers) sich data[uid] teilen. Daher wird hier ein Fehler
// ausgeloest, wenn es von einer Truhe ein Mapping kriegt, welches nicht
// identisch (!) mit dem data[uid] ist.
// liefert 0 im Fehlerfall!
int StoreData(string uid, mapping tmp) {

  if (clonep(ME)) return 0;

  // Aber nur dann, wenn die auch von einer truhe abgerufen wird und keinem
  // beliebigen anderen Objekt oder wenn ein EM setzt.
  if (extern_call())
  {
    if (!objectp(previous_object()))
      return 0;
    if (blueprint(previous_object()) != ME 
        && load_name(previous_object()) != __FILE__[..<3]
        && !ACCESS)
      return 0;
  }
  if (!stringp(uid) || !mappingp(tmp))
    return(0);

  // tmp muss auf _dasselbe_ Mapping zeigen wie data[uid]. Wenn das nicht der
  // Fall ist, ist was schiefgelaufen. Jedenfalls wird dann hier nen Fehler
  // ausgeloest.
  if (tmp != data[uid])
  {
//    if(program_time(previous_object()) < 1400525694)
//      data[uid]=tmp;
//    else
      raise_error("StoreData() gerufen und Daten sind nicht identisch "
          "mit den bereits bekannten.\n");
  }

  // Absichtlich keine Kopie, damit sich alle Truhen das Mapping teilen.
  //data[uid]=tmp;

  // Savefile muss natuerlich geschrieben werden, fuer den naechsten Reboot.
  if (find_call_out(#'save_me)==-1)
      call_out(#'save_me,10); // Speichervorgaenge ggf. sammeln (upd -ar ...)
  return(1);
}

// Maintainer ueber Truhenvorschlaege informieren
void reset() {

  if (clonep() || !sizeof(vorschlaege)) {
    // ohne Vorschlaege ist auch kein reset noetig.
    set_next_reset(-1);
    return;
  }
  set_next_reset(12000); // alle 3-4h reicht.
  foreach(string uid: MAINTAINER) {
    object pl=find_player(uid);
    if (objectp(pl) && query_idle(pl) < 1800)
      tell_object(pl,BS("Es gibt neue Objektvorschlaege fuer die "
        "Autoloadertruhe. Bitt schau da doch bei Gelegenheit mal drueber."));
  }
}


// *************************************************************************

// **************** SONSTIGES **********************************************

// *seufz*
// secure_level() aus der simul_efun ist hier momentan nicht brauchbar, weil
// dort auch p/seher/moebel/autoloadertruhe in der Callerkette steht und das
// ein levle von 0 hat. *seufz*
nomask private int my_secure_level() {
  int *level;
  //kette der Caller durchlaufen, den niedrigsten Level in der Kette
  //zurueckgeben. Zerstoerte Objekte (Selbstzerstoerer) fuehren zur Rueckgabe
  //von 0.
  //caller_stack(1) fuegt dem Rueckgabearray this_interactive() hinzu bzw. 0,
  //wenn es keinen Interactive gibt. Die 0 fuehrt dann wie bei zerstoerten
  //Objekten zur Rueckgabe von 0, was gewuenscht ist, da es hier einen
  //INteractive geben muss.
  level=map(caller_stack(1),function int (object caller)
      {if (objectp(caller))
        return(query_wiz_level(geteuid(caller)));
       return(0); // kein Objekt da, 0.
      } );
  return(min(level)); //den kleinsten Wert im Array zurueckgeben (ggf. 0)
}


// debugkram
mixed _query_content() {
  //deep_copy, damit nicht jemand einfach so an den Daten rumbasteln kann.
  return(deep_copy(autoloader));
}

mixed _query_owner() {
  return(uuid);
}

int DeleteData(string uid) {
  if (clonep(ME)) return 0;
  if (!stringp(uid) || !sizeof(uid)) return -1;
  if (!ACCESS) return -2;
  //if (!ARCH_SECURITY) return -2;
  m_delete(data,uid);
  save_me();
  return(1);
}

mixed testfun() {return "bin da\n";}

