Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/secure/shadowmaster.c b/secure/shadowmaster.c
new file mode 100644
index 0000000..e1fd51d
--- /dev/null
+++ b/secure/shadowmaster.c
@@ -0,0 +1,262 @@
+// MorgenGrauen MUDlib
+/** \file /secure/shadowmaster.c
+* Objekt, welches eine Liste mit aktiven Shadows hat.
+* Die simul_efun shadow() meldet das beschattende Objekt hier an. Nuetzlich,
+* damit man als Magier endlich mal rauskriegen kann, welche Shadows es
+* eigentlich gibt.
+* \author Zesstra
+* \date 07.08.2009
+* \version $Id$
+*/
+/* Changelog:
+*/
+#pragma strong_types
+#pragma no_clone
+#pragma no_inherit
+#pragma no_shadow
+#pragma pedantic
+
+#include <defines.h>
+#include <wizlevels.h>
+
+#define HOME(x) (__PATH__(0)+x)
+
+/** shadows ist ein mapping, welches alle Schatten und ihre Opfer enthaelt.
+ *
+ * Struktur: Schatten als Schluessel (object) und Beschatteter (object) als
+ * Wert.
+*/
+private mapping shadows = ([]);
+
+#ifndef DEBUG
+#define DEBUG(x) if (find_player("zesstra"))\
+ tell_object(find_player("zesstra"),\
+ "SMDBG: "+x+"\n")
+#endif
+
+#define MEMORY "/secure/memory"
+
+#define SHADOW_OK 1
+#define SHADOW_ACCESS_DENIED -1
+#define SHADOW_EXISTS -2
+#define SHADOW_UNKNOWN -3
+
+protected void create() {
+ mixed tmp;
+ seteuid(getuid());
+ if (mappingp(tmp=MEMORY->Load("Schatten"))) {
+ shadows = tmp;
+ DEBUG("Daten aus MEMORY geladen.\n");
+ }
+ else {
+ DEBUG("Keine Daten in MEMORY vorhanden - reinitialisiere.\n");
+ if (MEMORY->Save("Schatten", shadows) != 1)
+ raise_error("Konnte Daten nicht im Memory ablegen.\n");
+ }
+}
+
+/** Liefert einen String mit allen Schatten und beschatteten Objekten zurueck.
+ * @return string - Liste von Schatten und Opfern
+ */
+public void DumpShadows() {
+ if (extern_call() && !ELDER_SECURITY ) return 0;
+
+ string res = "";
+ foreach(object schatten, object opfer: shadows)
+ if (schatten && opfer)
+ res += sprintf("%O -> %O\n",schatten,opfer);
+
+ printf("Folgende Shadows sind bekannt: \n\n%s\n", res);
+}
+
+/** Findet zu einem beschatteten Objekt den zugehoerigen Schatten.
+ @param[in] object - ein beschattetes Objekt.
+ @return object - Den Schatten oder 0.
+ @sa FindShadowsObject(), QueryObject(), QueryInfo()
+*/
+public object FindShadow(object opfer) {
+ if (!objectp(opfer))
+ return 0;
+
+ foreach(object schatten, object victim: shadows) {
+ if (opfer == victim)
+ // Schatten gefunden.
+ return schatten;
+ }
+ return 0;
+}
+
+/** Findet zu einem Schatten das beschattete Objekt.
+ @param[in] object - ein beschattendes Objekt.
+ @return object - Das beschattete Objekt oder 0.
+ @sa FindShadow(), QueryObject(), QueryInfo()
+*/
+public object FindShadowedObject(object schatten) {
+ return shadows[schatten];
+}
+
+/** Gibt Schatten und Beschatteten zurueck, falls ob eines von beiden ist.
+ Ist ob ein Schatten oder ein beschattetes Objekt, wird ein Array aus
+ Objekten geliefert. Hierbei werden ggf. alle Objekte in der
+ Beschattungshierarchie geliefert, von der ob Bestandteil ist.
+ @param[in] object - ein Objekt.
+ @return object* - ({a, b, c, d}) oder 0.
+ @sa FindShadow(), FindShadowedObject, QueryInfo()
+*/
+public object* QueryObject(object ob) {
+
+ if (!objectp(ob)) return 0;
+
+ object *res = ({ob});
+ object sh = FindShadow(ob);
+
+ while(sh) {
+ // es gibt einen Schatten, also Kette nach oben verfolgen.
+ res = ({sh}) + res;
+ sh = FindShadow(sh);
+ }
+
+ object vic = FindShadowedObject(ob);
+ while(vic) {
+ // es gibt ein beschattetes Objekt, Kette nach unten verfolgen.
+ res = res + ({vic});
+ vic = FindShadowedObject(vic);
+ }
+
+ if (sizeof(res) < 2) {
+ // Offenbar wird ob weder beschattet noch beschattet selber.
+ // Moeglicherweise wurde jedoch durch wilde Zerstoerung die Hierarchie
+ // getrennt. Falls ob nen Schatten ist, laesst sich das reparieren. Falls
+ // ob beschattet wird, hilft eigentlich nur ein reset(). Den moechte ich
+ // hier aber nicht machen, weils u.U. teuer sein koennte.
+ if (query_shadowing(ob)) {
+ shadows[ob] = query_shadowing(ob);
+ // nochmal.
+ return QueryObject(ob);
+ }
+ // scheinbar nicht.
+ return 0;
+ }
+
+ return res;
+}
+
+/** Gibt einen String mit Infos ueber ob zurueck.
+ Ist ob ein beschattetes Objekt oder ein Schatten, wird ein beschreibender
+ String zurueckgeliefert (schatten -> beschattetes Objekt). Hierbei wird ggf.
+ die gesamte Beschattungshierarchie angegeben (a -> b -> c -> d).
+ @param[in] object - ein Objekt.
+ @return string - String mit Infos ueber ob.
+ @sa FindShadow(), FindShadowedObject(), QueryObject()
+*/
+public string QueryInfo(object ob) {
+ object *shs = QueryObject(ob);
+ if (!shs) return 0;
+
+ return CountUp(map(shs, #'object_name), " -> ", " -> ");
+}
+
+/** Registriert einen Schatten und sein Opfer.
+ Registriert den Schatten und sein Opfer. Sollte ausschliesslich durch die
+ simul_efun oder spare_simul_fun gerufen werden.
+ @sa UnregisterShadow()
+*/
+public int RegisterShadow(object schatten) {
+ object opfer;
+
+ //DEBUG(sprintf("[%O] %O\n", schatten, caller_stack()));
+
+ // Irgendein Sicherheitscheck ist eigentlich nicht noetig hier, da das Opfer
+ // ohnehin per efun ermittelt wird und kein Eintrag erfolgt, wenn kein
+ // beschattetes Objekt zu finden ist.
+
+ // das von schatten beschattete Objekt ermitteln
+ if (objectp(opfer=query_shadowing(schatten))) {
+ if (shadows[schatten] == opfer)
+ return SHADOW_EXISTS;
+
+ // Neueintrag oder ggf. auch Aendern.
+ shadows[schatten] = opfer;
+ //DEBUG(DumpShadows());
+ return SHADOW_OK;
+ }
+ return SHADOW_ACCESS_DENIED;
+}
+
+/** Traegt einen Schatten wieder aus.
+ Der Schatten wird wieder ausgetragen. Sollte ausschliesslich durch die
+ simul_efun oder spare_simul_fun gerufen werden.
+ Werden Schatten oder beschattete Objekte zerstoert ohne vorher die
+ Schattierung zu beenden, fuehrt dies zu Inkonsistenzen und zerbrochenen
+ Beschattungshierarchien.
+ @sa RegisterShadow(), UnregisterOpfer()
+*/
+public int UnregisterShadow(object caller) {
+ object schatten, opfer;
+
+ // Ein Sicherheitscheck fuer den Aufruf ist eigentlich nicht noetig, da ein
+ // Eintrag nur entfernt wird, wenn die Beschattung nachweislich beendet
+ // wurde.
+
+ //DEBUG(sprintf("[%O] %O\n", caller, caller_stack()));
+ if (!objectp(caller)) return SHADOW_UNKNOWN;
+
+ // Schatten und beschatteten aus den lokalen Daten ermitteln.
+ if (member(shadows, caller)) {
+ schatten = caller;
+ opfer = shadows[schatten];
+ }
+ else if (objectp(schatten = FindShadow(caller))) {
+ opfer = caller;
+ }
+ // wenn nicht bekannt, ist jetzt eh Ende.
+ if (!schatten) return SHADOW_UNKNOWN;
+
+ //DEBUG(sprintf("%O -> %O (%O, %O)\n",
+ // schatten, opfer, caller, query_shadowing(schatten)));
+
+ // Schattierung wirklich beendet? Wenn nicht -> Ende
+ if (opfer && query_shadowing(schatten) == opfer)
+ return SHADOW_ACCESS_DENIED;
+
+ // war schatten in einer Beschattungshierarchie?
+ object up = FindShadow(schatten);
+ if (up && query_shadowing(up) == opfer) {
+ shadows[up] = opfer; // Kette neu verlinken
+ }
+
+ // jetzt kann geloescht werden.
+ m_delete(shadows,schatten);
+ return SHADOW_OK;
+}
+
+public int ResetAll() {
+ if (!ARCH_SECURITY) return SHADOW_ACCESS_DENIED;
+
+ DEBUG("ResetAll() called.\n");
+
+ shadows = ([]);
+
+ if (MEMORY->Save("Schatten", shadows) != 1)
+ raise_error("Konnte Daten nicht im Memory ablegen.\n");
+
+ return SHADOW_OK;
+}
+
+/** Raeumt die Daten ueber die Schatten auf.
+ Zerstoeren sich beschattete Objekte, werden die Schatten nicht
+ ausgetragen, daher wird das von zeit zu zeit hier gemacht.
+*/
+public void reset() {
+ foreach(object schatten, object opfer: shadows) {
+ if (!objectp(opfer)) {
+ // war schatten evtl. in einer Hierarchie und beschattet jetzt was
+ // anderes?
+ if (query_shadowing(schatten))
+ shadows[schatten] = query_shadowing(schatten);
+ else
+ m_delete(shadows, schatten);
+ }
+ }
+}
+