Erweiterung der Dokumentation zum Channeld
Change-Id: I8f9e4860a4097b0cba2db49f5d8cba0eb4e7599a
diff --git a/doc/wiz/channel-supervisor b/doc/wiz/channel-supervisor
new file mode 100644
index 0000000..816bf24
--- /dev/null
+++ b/doc/wiz/channel-supervisor
@@ -0,0 +1,78 @@
+Supervisoren fuer Ebenen
+************************
+
+ Die Supervisoren (im Folgenden kurz SV) von Ebenen werden vom channeld
+ gefragt, ob ein Objekt eine bestimmte Aktion auf einer bestimmten Ebenen
+ ausfuehren darf, z.B. Betreten einer Ebene oder Senden auf einer Ebene.
+ Die SVs sind selbst ebenfalls immer Zuhoerer auf der Ebene.
+
+ Wird ein SV zerstoert, wird im Normalfall ein neuer SV aus dem Kreise der
+ aktuellen Zuhoerer bestimmt, ueblicherweise das am laengsten zuhoerende
+ Objekt.
+
+ Betritt ein Objekt, das eine Ebene erschaffen hat (der erste Supervisor),
+ eine Ebene nach Verlassen erneut, uebernimmt es automatisch die SV-Rolle
+ wieder, sofern das Objekt *kein* Spieler oder Magier ist.
+
+
+Erstellen von Supervisoren
+==========================
+
+ Im einfachsten Fall wird /std/channel_supervisor geerbt, ein Name
+ konfiguriert und das systemweite Init-File fuer Ebenen eingelesen.
+ Anschliessend erhaelt man das Standardverhalten, was im Init-File
+ konfiguriert ist. Ein Beispiel hierfuer findet sich
+ /doc/beispiele/ebenen/supervisor.c.
+
+ Man kann die SV-Funktionalitaet in einem bestehenden Objekt ergaenzen,
+ indem man /std/channel_supervisor zusaetzlich erbt. Hierbei ist zu
+ beachten, dass channel_supervisor.c selbst bereits die Funktionen name()
+ und Name() definiert und dort (undekliniert) den Namen zurueckgibt, der
+ per ch_set_sv_name() eingestellt wurde.
+
+ Wenn also das erbende Objekt deklinierte Namen ausgeben soll oder
+ einen anderen Namen als den SV-Namen, muss im erbenden Objekt name()
+ ueberschrieben werden. Dabei ist zu beachten, dass die ueberschreibende
+ Funktion explizit das Objekt angeben muss, in dem das geerbte name()
+ gerufen werden soll, d.h. beispielsweise return thing::name(); statt
+ nur ::name();
+
+ Alternativ kann man die Inherit-Reihenfolge geeignet waehlen, so dass
+ channel_supervisor::name() schon dadurch ueberschrieben wird.
+ Ein Beispiel hierfuer steht in /doc/beispiele/ebenen/supervisor-thing.c.
+
+ Will man einen SV fuer eine Ebene konfigurieren, die keine Standardebene
+ ist, kann man ein eigenes Init-File einlesen (Format siehe Manpage
+ "channeld.init"). In diesem Fall ist aber zu beachten, dass man
+ durch Aufruf von CHMASTER->new() selber Sorge dafuer tragen muss, dass
+ die Ebene erstellt wird.
+ (Eine Standardebene ist eine Ebene, die in der globalen
+ Konfigurationsdatei /p/daemon/channeld.init aufgefuehrt ist und daher
+ vom Channeld automatisch erzeugt wird.)
+
+ Will man einen SV mit einem gaenzlich anderen Verhalten bauen, so ist
+ auch das moeglich, indem man die lfun
+
+ public int ch_check_access(string ch, object user, string cmd)
+
+ ueberschreibt. Diese wird vom channeld im SV gerufen. Gibt sie eine 1
+ zurueck, darf das Objekt <user> auf der Ebene <ch> die Aktion <cmd>
+ ausfuehren. Anderenfalls muss 0 zurueckgeben werden. <cmd> ist hierbei
+ eines der in /p/daemon/channel.h definierten Kommandos.
+
+ Die Ebene <ch> wird immer kleingeschrieben uebergeben. Auch wenn der
+ Name Spielern case-sensitiv angezeigt wird, kann es keine zwei Ebenen
+ geben, welche sich nur in Gross-/Kleinschreibung unterscheiden und intern
+ erfolgt die Verwaltung *immer* kleingeschrieben - dies gilt auch fuer die
+ Rechtepruefung.
+
+
+Siehe auch:
+-----------
+
+ Ebenen: channels
+ Init-File: channeld.init
+ Beispiele: /doc/beispiele/ebenen/supervisor.c
+ /doc/beispiele/ebenen/supervisor-thing.c
+ lfuns: ch_read_init_file()
+ ch_set_sv_name()
diff --git a/doc/wiz/channeld.init b/doc/wiz/channeld.init
new file mode 100644
index 0000000..22e2491
--- /dev/null
+++ b/doc/wiz/channeld.init
@@ -0,0 +1,81 @@
+Initialisierung der Ebenen
+--------------------------
+
+ Standardmaessig wird die Ebenenliste im Morgengrauen ueber die Datei
+ /p/daemon/channeld.init erzeugt. Diese wird vom channeld eingelesen und
+ aus den Angaben die Ebenenkonfiguration vorgenommen.
+
+ Im Homemud wird stattdessen die Datei /p/daemon/channeld.init.testmud
+ verwendet, die viele Standardebenen nicht enthaelt, weil in einem
+ "nackten" Homemud die meisten Ebenenbesitzer nicht existieren und daher
+ das Laden des channeld zu Fehlern fuehren wuerde.
+
+ Die Zugriffsrechte fuer die Ebenen werden von einem sogenannten
+ Supervisor (SV) verwaltet und durchgesetzt. Der channeld fragt den fuer
+ eine Ebene zustaendigen Supervisor, ob die angeforderte Aktion erlaubt
+ ist. Im Fall des channeld uebernitmm das Objekt /p/daemon/channel-sv
+ diese Aufgabe.
+
+ Jeder Supervisor liest die Rechte-Konfiguration aus der Init-Datei ein.
+ Standardmaessig ist dies die globale Datei, man kann aber auch eigene
+ festlegen.
+
+
+Struktur des Init-Files
+-----------------------
+
+ Das Init-File hat folgenden Aufbau:
+
+ <name>:<recv>:<send>:<accessflags>:<channelflags>:<desc>:<supervisor>
+
+ z.B.
+
+ abgilde: 0: 0: 0: 0:Fuer Abenteurer:/gilden/abenteurer
+ Tod: 0:-1: 0: 1:Wer stirbt wann?:/room/death/death_room
+
+ Fuer SVs sind nur die Felder <name>, <recv>, <send> und <accessflags>
+ relevant. Das vordefinierte ch_check_access() entscheidet wie folgt
+ anhand der Angaben:
+
+ Verlassen (C_LEAVE) ist so gut wie immer erlaubt, siehe man channels. Die
+ anderen Aktionen sind in zwei Gruppen eingeteilt:
+
+ 1) RECV. Die Aktionen dieser Gruppe sind Suchen (C_FIND), Auflisten
+ (C_LIST) und Betreten (C_JOIN).
+ 2) SEND. Die Aktion dieser Gruppe ist zur Zeit nur Senden (C_SEND).
+
+ Aktionen werden zugelassen, wenn Spieler-/Magierlevel mindestens die fuer
+ die jeweilige Aktionsgruppe RECV oder SEND festgelegte Stufe ist.
+
+ Enthaelt <accessflags> das Flag CH_ACCESS_WIZARD, handelt es sich um eine
+ Magierebene, und die Magierstufe des Spielers muss mindestens die
+ Mindeststufe der Ebene sein. Ansonsten wird gegen den Spielerlevel
+ geprueft.
+ Enthaelt <accessflags> das Flag CH_ACCESS_NOGUEST, darf die Ebene nicht
+ von Gaesten benutzt werden (weder Empfangen noch Senden).
+
+ Wenn RECV_LVL oder SEND_LVL auf -1 gesetzt ist, sind die Aktionen der
+ jeweiligen Gruppen komplett geblockt.
+
+
+Hinweise:
+---------
+
+ Im Initfile sollten nur Blueprints als SVs verwendet werden -
+ aber im Allgemeinen koennen SVs auch Clones sein!
+
+ Das Initfile fuer Homemuds heisst /p/daemon/channeld.init.testmud. In
+ dieser Datei sind nicht alle Standardebenen vorkonfiguriert, die es im
+ echten Morgengrauen gibt.
+
+
+Siehe auch:
+-----------
+
+ Konzepte: channels
+ Beispiele: /doc/beispiele/ebenen/supervisor.c
+ /doc/beispiele/ebenen/supervisor-thing.c
+ /doc/beispiele/ebenen/supervisor.txt
+ lfun: ch_read_init_file()
+ ch_set_sv_name()
+
diff --git a/doc/wiz/channels b/doc/wiz/channels
new file mode 100644
index 0000000..6c7af32
--- /dev/null
+++ b/doc/wiz/channels
@@ -0,0 +1,170 @@
+
+Der Ebenenverwalter channeld.
+-----------------------------
+
+Alle noetigen Defines sind in /p/daemon/channel.h definiert. Wenn man den
+channeld verwenden will, bitte dieses inkludieren.
+
+Typischer Aufruf: CHMASTER->join("Abenteuer", this_object());
+
+
+Oeffentliche Funktionen
+------------------------
+
+Zuerst die wohl am haeufigsten verwendeten Funktionen, beitreten, senden,
+verlassen.
+
+public int join(string chname, object joining)
+
+ Objekt <joining> betritt Ebene <chname>. Dies wird zugelassen, wenn es
+ die Berechtigung hat und noch nicht Mitglied ist.
+ (Man kann einer Ebene nicht zweimal beitreten.)
+ Wenn <joining> der urspruengliche Ersteller der Ebene ist, wird er
+ automatisch zum neuen Supervisor (SV).
+ Rueckgabewert: 0 bei Erfolg, E_ACCESS_DENIED (-1) sonst.
+ Hinweis: Das Objekt <joining> muss einen string bei Aufruf von name()
+ zurueckgeben.
+
+
+public varargs int send(string chname, object sender, string msg, int type)
+
+ Nachricht <msg> vom Typ <type> mit Absender <pl> auf der Ebene <chname>
+ posten, sofern <pl> dort senden darf.
+ <type> ist einer der Nachrichtentypen aus "channel.h":
+ MSG_SAY 0 normale Nachricht
+ MSG_EMOTE 1 Emote
+ MSG_GEMOTE 2 Genitiv-Emote
+
+ Die Nachricht <msg> wird an die Funktion ChannelMessage() in den Ebenen-
+ Mitgliedern uebergeben und von dieser ausgegeben.
+
+ Rueckgabewerte:
+ 0 Nachricht erfolgreich gesendet
+ E_ACCESS_DENIED -1 Zugriff verweigert
+ E_NOT_MEMBER -3 Objekt <sender> hat die Ebene nicht betreten
+ E_EMPTY_MESSAGE -4 Die Nachricht hatte keinen Inhalt
+
+
+public int leave(string chname, object leaving)
+
+ Objekt <leaving> verlaesst Ebene <chname>.
+ Wenn danach kein Zuhoerer mehr auf der Ebene ist, loest sie sich auf.
+
+ Zugriffsrechte werden dabei ueberprueft, obwohl es normalerweise keinen
+ Grund geben duerfte, das Verlassen einer Ebene zu verbieten. Es ist
+ allerdings technisch durchaus moeglich, dem Objekt <leaving> das
+ Verlassen zu verweigern, z.B. auf Grund eines Banns.
+ Rueckgabewerte:
+ 0 erfolgreich verlassen
+ E_ACCESS_DENIED -1 Zugriff verweigert
+ E_NOT_MEMBER -2 Objekt <leaving> war gar nicht Mitglied
+
+
+public varargs int new(string ch_name, object owner, string|closure desc,
+ int channel_flags)
+
+ Erstellt eine neue Ebene <ch_name> mit <owner> als Ebenenbesitzer. Wird
+ auch vom channeld selbst verwendet, um die in channeld.init definierten
+ Ebenen zu erzeugen. Inaktive Ebenen werden ebenfalls ueber new()
+ reaktiviert, mitsamt ihrer bestehenden History.
+
+ <ch_name> Darf nicht 0 oder leer sein. Zur Anzeige wird der Name in der
+ angegebenen Schreibweise verwendet, fuer interne Zwecke wird
+ aber immer der kleingeschriebene Name genutzt. Das gilt auch
+ fuer die Pruefung von Zugriffsrechten.
+ <desc> Kann die statische Beschreibung der Ebene sein oder eine
+ Closure, die dynamisch aktualisierte Infos ausgibt.
+ <owner> Besitzer des Channels, Supervisor (SV) genannt.
+ Sollte eine Funktion ch_check_access() definieren, die gerufen
+ wird, wenn eine Ebenenaktion vom Typ join/leave/send/list/users
+ eingeht.
+ <channel_flags>
+
+ Rueckgabewerte:
+ 0 Ebene erfolgreich erstellt.
+ E_ACCESS_DENIED -1
+ - Channelname existiert schon
+ - Maximalzahl Channels erreicht
+ - Channelname war Unsinn (leer oder 0)
+ - keine Beschreibung angegeben, und es existiert auch keine passende
+ inaktive Ebene
+ - kein Supervisor (SV) angegeben
+ - angegebener Supervisor darf keine Ebenen erstellen (Bann, oder
+ verbotener Name)
+ - bei Reaktivierung einer inaktiven Ebene wird ein neuer Supervisor
+ angegeben, aber die Ebene war mit unveraenderlichem Supervisor
+ (CHF_FIXED_SUPERVISOR) initialisiert worden; ein neuer Supervisor
+ wird dann abgelehnt, damit die Kontrolle ueber die Ebene nicht von
+ anderen Objekten uebernommen werden kann.
+
+ Fuer die Erstellung und Funktionsweise von Supervisor-Objekten wird
+ auf
+
+
+public int|mapping list(object pl)
+
+ Gibt ein Mapping mit allen Ebenen aus, die das Objekt <pl> lesen kann,
+ oder den Fehlercode E_ACCESS_DENIED (-1).
+ Struktur des Mappings:
+ ([ string chname, ({object* members, closure access_cl, string desc,
+ object supervisor, string ch_name }) ])
+
+
+public string|string* find(string chname, object pl)
+
+ Ebene suchen, deren Name <chname> enthaelt, und auf der Objekt <pl>
+ senden darf.
+ Rueckgabewerte:
+ - den gefundenen Namen als String
+ - String-Array, wenn es mehrere Treffer gibt
+ - 0, wenn es keinen Treffer gibt
+
+
+public int|<int|string>** history(string chname, object pl)
+
+ Ebenen-History abfragen. Objekt <pl> muss berechtigt sein, dem Channel
+ <chname> beizutreten.
+ Rueckgabewert: E_ACCESS_DENIED (-1) bei fehlender Berechtigung, ansonsten
+ ({string channelname, string sender, string msg, int msg_type})
+
+
+public int transfer_ownership(string chname, object new_owner)
+
+ Aendert den Ersteller/Besitzer der Ebene.
+ Achtung: das ist nicht das gleiche wie der aktuelle Supervisor (SV)!
+ Nur der aktuelle Besitzer, Supervisor oder EM+ darf die Ebene
+ verschenken.
+
+
+public int change_channel_flags(string chname, int newflags)
+
+ Aendert die Zugriffsflags der Ebene. Hierbei handelt es sich nicht um die
+ Stufenlimits fuer join() oder send().
+ Nur der aktuelle Supervisor (SV), der Ersteller, oder EM+ duerfen die
+ Flags aendern.
+ Die moeglichen Flags sind die, die auch in channeld.init verwendet werden
+ und in /p/daemon/channel.h definiert sind:
+ CHF_FIXED_SUPERVISOR 1 kein Wechsel des Supervisor erlaubt
+
+ Folgende Flags werden nur in Supervisor-Objekten verwendet:
+ CH_ACCESS_WIZARD 1 reine Magierebene
+ CH_ACCESS_NOGUEST 2 keine Gaeste erlaubt
+
+
+Funktionen fuer Erzmagierkommandos:
+
+public int remove_channel(string chname, object pl)
+ Wird aus der Shell gerufen, fuer das Erzmagier-Kommando "kill".
+
+public int clear_history(string chname)
+ Wird aus der Shell aufgerufen, fuer das Erzmagier-Kommando "clear".
+
+
+Siehe auch:
+-----------
+
+ Init-Datei: channeld.init
+ Supervisor: channel-supervisor
+ Beispiele: /doc/beispiele/ebenen/supervisor.c
+ /doc/beispiele/ebenen/supervisor-thing.c
+