Playerdata-Objekt fuer ROOT-Objekte
Da ROOT-Objekte nicht via den BACKBONEID-Mechanismus
ihre UID exportieren, konnten diese den bestehen
/obj/playerdata nicht nutzt (es hat keine ROOT-ID,
sondern die BACKBONEID bekommen).
Daher gibt es jetzt ein Objekt dafuer unter /secure/,
welches die ROOT-ID bekommt und nur von ROOT-Objekten
genutzt werden kann.
Das Objekt unter /obj/ ist funktionsidentisch, bekommt
aber aufgrund des Speicherortes in /obj/ beim Erzeugen
die UID des Erzeugers. Es kann dann von Objekten mit der
UID des Erzeugers benutzt werden.
Change-Id: Ieff3352da60b32459430fa761dbb57517691370a
diff --git a/obj/playerdata.c b/obj/playerdata.c
index a3c9c29..c4353ec 100644
--- a/obj/playerdata.c
+++ b/obj/playerdata.c
@@ -1,105 +1,26 @@
-// Dieses Ding kriegt die UID vom Clonenden.
-// Spielerladen duerfen nur Objekte, welche die gleiche UID wie der Cloner
-// (also dieses Objekt) haben.
-// Abfragen kann es nur das Objekt, welches den Spieler geladen hat.
+// Dieses Ding kann ein Spieler-Savefile laden, um dort Daten via
+// Query/QueryProp abzufragen. Sollte das Spielerobjekt existieren, wird
+// stattdessen dort gefragt.
-#pragma no_inherit,no_shadow
+// Das Objekt ist funktionsidentisch zum gleichnamigen Objekt unter /secure/,
+// bekommt hier aufgrund des Speicherortes (/obj/) beim Clonen/Laden
+// aber die UID vom Clonenden/Ladenden. (Ausser es ist ein ROOT-Objekt,
+// dieses exportieren ihre UID nicht. Dann ist die UID von diesem Objekt die
+// Backbone-ID STD).
+
+// Spielerladen duerfen nur Objekte, welche die gleiche UID wie dieses Objekt
+// (damit also der Erzeuger) haben.
+// Daten abfragen darf nur das Objekt, welches den Spieler auch geladen hat.
+// Damit ist sichergestellt, dass Zugriffsrechte beachtet werden.
+
+#pragma no_inherit, no_shadow
#pragma strong_types,save_types,rtt_checks
-#include <config.h>
-#include <wizlevels.h>
-
-inherit "/std/thing/properties";
-
-object|string pl;
-object user;
+inherit "/secure/playerdata";
protected void create()
{
::create();
- seteuid(getuid());
- set_next_reset(300);
-}
-
-public int ReleasePlayer()
-{
- pl = 0;
- user = 0;
- return 1;
-}
-
-public int LoadPlayer(string name)
-{
- // Es duerfen nur Objekte mit der gleichen UID wie wir diesen Clone
- // benutzen! Ansonsten koennten z.B. nicht-ROOT-Objekte einen von einem
- // ROOT-Objekt erzeugten Clone hiervon nutzen und alles lesen...
- if (!previous_object()
- || getuid(previous_object()) != getuid(this_object()))
- return 0;
- if (query_wiz_level(getuid(previous_object())) < WIZARD_LVL)
- return 0;
-
- mixed userinfo=MASTER->get_userinfo(name);
- if (!pointerp(userinfo))
- return 0;
- // Wenn es das Spielerobjekt gibt, ist alles gut, dann fragen wir einfach
- // das.
- pl = find_player(name) || find_netdead(name);
- if (!pl)
- {
- // wenn nicht: Savefile einlesen.
- restore_object(SAVEPATH + name[0..0] + "/" + name);
- pl = name;
- }
- user = previous_object();
- set_next_reset(300);
- return 1;
-}
-
-public varargs mixed Query( string name, int Type )
-{
- if (!user || user != previous_object())
- return 0;
-
- if (objectp(pl))
- return pl->Query(name,Type);
- else if (stringp(pl))
- return ::Query(name, Type);
- return 0;
-}
-
-public varargs mixed QueryProp( string name )
-{
- if (!user || user != previous_object())
- return 0;
-
- if (objectp(pl))
- return pl->QueryProp(name);
- else if (stringp(pl))
- return ::QueryProp(name);
- return 0;
-}
-
-
-// kein Schreibzugriff
-public varargs mixed Set( string name, mixed Value, int Type, int extern )
-{
- return 0;
-}
-
-public void reset()
-{
- if (clonep(this_object()))
- destruct(this_object());
-}
-
-public int clean_up(int ref)
-{
- if (clonep(this_object())
- || ref <= 1 )
- {
- destruct(this_object());
- }
- return 1;
+ replace_program();
}
diff --git a/secure/playerdata.c b/secure/playerdata.c
new file mode 100644
index 0000000..d01e9bb
--- /dev/null
+++ b/secure/playerdata.c
@@ -0,0 +1,113 @@
+// Dieses Ding kann ein Spieler-Savefile laden, um dort Daten via
+// Query/QueryProp abzufragen. Sollte das Spielerobjekt existieren, wird
+// stattdessen dort gefragt.
+
+// Das Objekt hier bekommt aufgrund des Speicherortes (/secure/) die UID ROOT
+// und darf folglich alles lesen.
+
+// Spielerladen duerfen aber nur Objekte, welche die gleiche UID wie dieses
+// Objekt (damit also in diesem Fall ROOT) haben.
+// Daten abfragen darf nur das Objekt, welches den Spieler auch geladen hat.
+// Damit ist sichergestellt, dass nur ROOT-Objekt ueber *dieses* Objekt (was
+// ja ueberall lesen kann) Daten abfragen koennen.
+
+#pragma no_shadow
+#pragma strong_types,save_types,rtt_checks
+
+#include <config.h>
+#include <wizlevels.h>
+
+inherit "/std/thing/properties";
+
+object|string pl;
+object user;
+
+protected void create()
+{
+ ::create();
+ seteuid(getuid());
+ set_next_reset(300);
+}
+
+public int ReleasePlayer()
+{
+ pl = 0;
+ user = 0;
+ return 1;
+}
+
+public int LoadPlayer(string name)
+{
+ // Es duerfen nur Objekte mit der gleichen UID wie wir diesen Clone
+ // benutzen! Ansonsten koennten z.B. nicht-ROOT-Objekte einen von einem
+ // ROOT-Objekt erzeugten Clone hiervon nutzen und alles lesen...
+ if (!previous_object()
+ || getuid(previous_object()) != getuid(this_object()))
+ return 0;
+ if (query_wiz_level(getuid(previous_object())) < WIZARD_LVL)
+ return 0;
+
+ mixed userinfo=MASTER->get_userinfo(name);
+ if (!pointerp(userinfo))
+ return 0;
+ // Wenn es das Spielerobjekt gibt, ist alles gut, dann fragen wir einfach
+ // das.
+ pl = find_player(name) || find_netdead(name);
+ if (!pl)
+ {
+ // wenn nicht: Savefile einlesen.
+ restore_object(SAVEPATH + name[0..0] + "/" + name);
+ pl = name;
+ }
+ user = previous_object();
+ set_next_reset(300);
+ return 1;
+}
+
+public varargs mixed Query( string name, int Type )
+{
+ if (!user || user != previous_object())
+ return 0;
+
+ if (objectp(pl))
+ return pl->Query(name,Type);
+ else if (stringp(pl))
+ return ::Query(name, Type);
+ return 0;
+}
+
+public varargs mixed QueryProp( string name )
+{
+ if (!user || user != previous_object())
+ return 0;
+
+ if (objectp(pl))
+ return pl->QueryProp(name);
+ else if (stringp(pl))
+ return ::QueryProp(name);
+ return 0;
+}
+
+
+// kein Schreibzugriff
+public varargs mixed Set( string name, mixed Value, int Type, int extern )
+{
+ return 0;
+}
+
+public void reset()
+{
+ if (clonep(this_object()))
+ destruct(this_object());
+}
+
+public int clean_up(int ref)
+{
+ if (clonep(this_object())
+ || ref <= 1 )
+ {
+ destruct(this_object());
+ }
+ return 1;
+}
+