Vorbereitungen Empfang TMs, wenn offline.

Wenn ein Spieler/Magier auch in Abwesenheit TMs empfangen koennen
will, kann das Spielerobjekt beim zentralen KOBOLD (/secure/kobold)
ein "Vault" deponieren.
Ist die Empfaengerin eines TMs nicht anwesend (und auch kein anderes
Lebewesen mit dem Namen), fragt das Spielerobjekt, ob der KOBOLD
ein passendes Vault hat. Wenn ja, wird das TM dort abgelegt,
aehnlich bei beim konventionellen Kobold.

Die Vaults sind LWOs, auf welche Spielerobjekte und der KOBOLD eine
Referenz haben. Wenn das Spielerobjekt neu erzeugt wird, fragt es
beim KOBOLD, ob ein Vault existiert und bekommt ggf. eine Referenz.
Es kann dann die gespeicherten Nachrichten aus dem Vault abrufen.

Dieser Commit erzeugt das Grundgeruest von KOBOLD und der Vaults
und ermoeglicht das Speichern von Nachrichten dort.
Die tatsaechliche Moeglichkeit des Deponierens des Vaults im
KOBOLD folgt spaeter.

Change-Id: I56604858a38482c8f9844b9f371d9fb6950bf1f9
diff --git a/secure/kobold.c b/secure/kobold.c
new file mode 100644
index 0000000..b1be5aa
--- /dev/null
+++ b/secure/kobold.c
@@ -0,0 +1,103 @@
+// The Manager Kobold who supervises storage of the comm vaults for players
+//
+// no retrieval of messages by this object. Player objects retrieve their LWO
+// (Kobold-Vault) from here. The Vaults only release messages to their
+// corresponding player object
+
+#pragma strict_types,rtt_checks
+
+#include "/sys/player/comm.h"
+
+mapping vaults = ([]);
+
+protected void create()
+{
+  // TODO: Speichern in MEMORY
+}
+
+// Einlagern von Vaults durch Spieler
+public int DepositVault(lwobject "/std/player/comm_vault" vault)
+{
+    if (query_once_interactive(previous_object())) {
+        vaults[getuid(previous_object())] = vault;
+        return 1;
+    }
+    return 0;
+}
+
+// Abrufen eines Pointers auf den Vault eines Spielers
+// Natuerlich *nur* durch den Spieler mit der richtigen UUID selber.
+public lwobject "/std/player/comm_vault" RetrieveVault()
+{
+    if (query_once_interactive(previous_object()))
+    {
+        lwobject "/std/player/comm_vault" vault = vaults[getuid(previous_object())];
+        // Und noch pruefen, ob auch die UUID uebereinstimmt - es soll kein
+        // neu angelegter Spieler das Vault von einem aelteren bekommen.
+        if (vault &&
+            ({string})vault.uuid() == getuuid(previous_object()))
+            return vault;
+    }
+    return 0;
+}
+
+// Pointer auf nen Vault vergessen.
+// Im Erfolgsfall wird das Vault zurueckgeben.
+// Aufruf *nur* durch den Spieler mit der richtigen UUID selber.
+public lwobject "/std/player/comm_vault" ForgetVault()
+{
+    if (query_once_interactive(previous_object()))
+    {
+        lwobject "/std/player/comm_vault" vault = vaults[getuid(previous_object())];
+        // Und noch pruefen, ob auch die UUID uebereinstimmt - es soll kein
+        // neu angelegter Spieler das Vault von einem aelteren bekommen.
+        if (({string})vault.uuid() == getuuid(previous_object()))
+        {
+            m_delete(vaults, getuid(previous_object()));
+            return vault;
+        }
+    }
+    return 0;
+}
+
+// Prueft, ob es ein Vault fuer Spieler gibt, deren UID mit <pluid> beginnen.
+// gibt im Erfolgsfall die vollstaendige UID zurueck.
+// 0, wenn keine gefunden
+// -1 wenn es mehrere in Frage kommende UIDs gibt.
+// (match_living()-inspiriert)
+public string|int find_player(string pluid)
+{
+    string uid;
+    if (pluid in vaults)
+        return pluid;  // das war einfach...
+    else
+    {
+        // Wir muessen leider alle Vaults absuchen
+        foreach(string u : vaults) {
+            if (strstr(u, pluid) == 0)
+            {
+                // wenn pluid nicht eindeutig ist und mehrere UIDs in Frage
+                // kommen, wird -1 zurueckgeben.
+                if (!uid)
+                    uid = u;
+                else
+                    return -1;
+            }
+        }
+    }
+    return uid;
+}
+
+public varargs int DepositMsg(string pluid, string msg, int msg_type,
+                              string msg_action, string msg_prefix,
+                              object origin = previous_object())
+{
+    if (!query_once_interactive(previous_object()))
+        return MSG_FAILED;
+    lwobject "/std/player/comm_vault" vault = vaults[pluid];
+    if (!vault)
+        return MSG_FAILED;
+
+    return ({int})vault.store_msg(msg, msg_type, msg_action, msg_prefix, origin);
+}
+