Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/doc/beispiele/master/opferstockmaster.c b/doc/beispiele/master/opferstockmaster.c
new file mode 100644
index 0000000..33a081f
--- /dev/null
+++ b/doc/beispiele/master/opferstockmaster.c
@@ -0,0 +1,120 @@
+/*
+ * Beispieldatei fuer einen einfachen Master, der Spielerdaten auch
+ * ueber reboots, resets und updates hinweg speichert, und gleichzeitg
+ * dafuer sorgt, dass die Datenmengen nicht immer groesser werden.
+ *
+ * By: Rumata@MorgenGrauen 3/99
+ *
+ */
+
+// Von diesem Objekt gibt es keine Clones, sondern nur die Blueprint.
+// Das Konstrukt if( clonep(ME) ) destruct(this_object()); ist dadurch
+// obsolet.
+#pragma no_clone
+
+#include <properties.h>
+#include <defines.h>
+
+// Ort, an dem die Daten gespeichert werden koennen. Die Endung .o
+// wird vom System angehaengt.
+#define SAVEFILE "/doc/beispiele/master/opferstocklog"
+
+// Dieses ist der Klient, der diesen Master benutzt. Dieser Wert wird
+// in diesem Programm zwar nicht benutzt, steht hier aber, damit man
+// weiss, wofuer dieser Master gut ist.
+#define CLIENT "/doc/beispiele/master/opferstock"
+
+// Es braucht kein Objekt inheritet werden, da wir keinerlei Spiel-
+// Funktionitaet brauchen. Der Master kann nicht genommen, bewegt oder
+// sonstwie innherlab des Muds benutzt werden. Insbesondere sollen
+// im savefile zum Master keine Properties oder so auftauchen.
+// inhert "/std/thing";
+
+// Um diese Daten geht es.
+// Das Mapping speichert zu jedem Spieler, wann das letzte Mal durch einen
+// der Klienten das Alignment geaendert wurde. Alte Daten werden bei
+// Gelegenheit geloescht.
+mapping data;
+
+void purge();
+
+void create() {
+
+ // Damit Schreibzugriff auf Savefile moeglich.
+ seteuid(getuid());
+
+ if( restore_object( SAVEFILE ) ) {
+ purge();
+ } else {
+ data = ([]);
+ save_object( SAVEFILE ); // Damit Savefile und Daten immer synchron sind.
+ }
+}
+
+// Diese Funktion testet einen einzelnen Eintrag, ob er veraltet ist.
+// (ist nicht Jahr 2038-fest :-)
+int notExpired( string name, int date ) {
+ return time() - date < 86400;
+}
+
+// Das Mapping untersuchen, ob Eintraege vorhanden sind, die nicht
+// mehr benoetigt werden.
+// (In diesem Fall sind das Eintraege, die aelter als einen Tag sind.)
+// Es reicht uns, diese Funktion einmal pro reboot auszufuehren. Bei
+// anderen Anwendungen koennte das natuerlich haeufiger noetig sein.
+void purge() {
+ data = filter_indices( data, #'notExpired );
+ save_object( SAVEFILE );
+}
+
+// Diese Funktion ist die eingetliche Funktion, die "gemastert" werden
+// soll, also für mehrere Opferstoecke gemeinsam benutzt wird.
+// Der Opferstock uebergibt das Spielerobjekt und die gewuenschte
+// Alignmentaenderung, als Ergebnis wird 1 geliefert, wenn eine Aenderung
+// vorgenommen wurde (0 sonst) und das Alignment des Spielers entsprechend
+// gesetzt.
+int addAlignment( object player, int align ) {
+ int newAlign;
+ string name;
+
+ /*
+ // Falls man verhindern will, dass nur der Klient auf die Daten zugreift,
+ // kann man hier noch Abfragen einbauen, typischerweise sieht das dann so
+ // aus:
+ if( object_name(previous_object())[0..xxx] != CLIENT ) return -1;
+ // oder
+ if( geteuid(previous_object()) != geteuid() ) return -1;
+ // etc. etc.
+ */
+
+ name = geteuid(player);
+
+ // Nur eine Aenderung pro Tag.
+ // Wir benutzen hier, dass data[name] == 0 ist, falls data den Namen nicht
+ // enthaelt!
+ if( notExpired( name, data[name] ) ) return 0;
+
+ // Daten setzen und speichern.
+ data[name] = time();
+ save_object( SAVEFILE );
+
+ // Maximale Aenderung: 200
+ if( align < -200 ) align = -200;
+ if( align > 200 ) align = 200;
+
+ newAlign = player->QueryProp( P_ALIGN ) + align;
+
+ // Kappung bei +-1000
+ if( newAlign < -1000 ) newAlign = -1000;
+ if( newAlign > 1000 ) newAlign = 1000;
+
+ player->SetProp( P_ALIGN, newAlign );
+ return 1;
+}
+
+// Schlussbemerkung:
+//
+// Gewitzte Programmierer koennten den Klient und den Master in einer
+// Datei zusammen ablegen. Die Blueprint wird als Master, die Clones werden
+// als Klienten benutzt. Ich habe das hier bewusst anders gemacht und empfehle
+// das auch als Vorbild, weil so der Code wesentlich besser zu verstehen ist.