Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/obj/tools/fehlerteufel.c b/obj/tools/fehlerteufel.c
new file mode 100644
index 0000000..a35fec1
--- /dev/null
+++ b/obj/tools/fehlerteufel.c
@@ -0,0 +1,993 @@
+/* /obj/toostels/fehlerteufel.c
+ Fehlerteufel - Magiertool zur Abfrage des Fehler-Daemons der Mudlib
+ Autor: Zesstra
+ Changelog:
+*/
+
+#pragma strict_types
+#pragma pedantic
+#pragma range_check
+#pragma no_shadow
+#pragma no_inherit
+
+inherit "/std/secure_thing";
+inherit "/secure/errord-structs";
+
+#include <defines.h>
+#include <wizlevels.h>
+#include <properties.h>
+#include <moving.h>
+#include <errord.h>
+#include <config.h>
+#include <debug_info.h>
+#include <input_to.h>
+#include <strings.h>
+
+#define TI this_interactive()
+
+#define DEBUG(x) if (funcall(symbol_function('find_player),"zesstra"))\
+ tell_object(funcall(symbol_function('find_player),"zesstra"),\
+ "EDBG: "+x+"\n")
+
+// variables
+private string owner; // UID vom Eigentuemer
+private string *uids=({}); // UIDs, auf die man schreibrechte hat
+private string *filteruids=({}); // wenn nicht-leer, nur diese UIDs zeigen
+private string *monitoruids=({}); // diese UIDs in die Liste einschliessen
+private int filterstatus=0; // Filter an oder aus?
+private mapping issuelist = ([]);
+/* ([ type1: ([uid1: <issuelist>, uid2: <issuelist> ]),
+ type2: ... ])
+ <issuelist> ist ein < <int|string>* >* vom ErrorD */
+
+//Welche Art von Fehler anzeigen?
+private int modus=T_RTERROR | T_RTWARN | T_REPORTED_ERR;
+private string *xmonitoruids = ({}); // expanded Monitor-UIDs
+private int lfehler; // letzter 'benutzter' Fehler.
+private int fehlerzahl; // fehlerzahl im letzten Reset.
+private mapping feingabe; // gerade eingegebener Fehler
+
+// ************** private functions **************
+private varargs int get_issuelist(int lmodus);
+private void get_uids();
+
+// irgendeinen Fehler oder Warnung anzeigen.
+private int show_entry(struct fullissue_s issue)
+{
+ if (!issue) return 0;
+
+ string txt=ERRORD->format_error(issue, 0);
+
+ if (!stringp(txt) || !sizeof(txt))
+ return 0;
+
+ tell_object(PL,txt+"\n");
+ return 1;
+}
+
+protected int _feingabe_fertig(string arg) {
+
+ if (arg == "j")
+ {
+ if (!feingabe[F_MSG])
+ {
+ tell_object(PL,
+ "Also, eine Fehlerbeschreibung solltest Du schon eingeben! Abgebrochen.\n");
+ }
+ else
+ {
+ string hashkey = (string)ERRORD->LogReportedError(feingabe);
+ tell_object(PL, sprintf(
+ "Vielen Dank! Die ID des eingegebenen Fehlers lautet: %s\n",
+ hashkey || "N/A"));
+ }
+ }
+ else
+ {
+ tell_object(PL, "Fehlereingabe abgebrochen.\n");
+ }
+
+ feingabe = 0;
+
+ return 1;
+}
+
+public int CmdFehlerEingabe(string arg) {
+ object target;
+
+ if (feingabe)
+ {
+ tell_object(PL, "Du gibts doch bereits einen Fehler ein!\n");
+ return 1;
+ }
+ feingabe = ([]);
+
+ if (arg)
+ {
+ target = present(arg);
+ if (!target)
+ target = find_object(arg); // vielleicht direkt angegeben?
+ }
+ // wenn nix gefunden, Environment des Magiers nehmen.
+ if (!target)
+ target = environment(environment());
+
+ feingabe[F_OBJ] = target;
+
+ tell_object(PL, break_string(sprintf(
+ "Du beginnst einen Fehlereintrag fuer das Objekt: %O\n", target),78));
+
+ input_to(function void (string str)
+ {
+ if (sizeof(str)) feingabe[F_MSG] = str;
+ }, INPUT_PROMPT, "Fehlerbeschreibung eingeben:\n");
+
+ input_to(function void (string str)
+ {
+ if (sizeof(str)) feingabe[F_PROG] = str;
+ else feingabe[F_PROG] = "unbekannt";
+ }, INPUT_PROMPT|INPUT_APPEND,
+ "Programm eingeben, in dem der Fehler auftritt (falls bekannt):\n");
+
+ input_to(function void (string str)
+ {
+ if (sizeof(str)) feingabe[F_LINE] = to_int(str);
+ tell_object(PL,break_string(sprintf(
+ "Du hast die folgenden Daten eingegeben:\n"
+ "Objekt: %O\n"
+ "Fehlerbeschreibung: %s\n"
+ "Programm: %s\n"
+ "Zeilennr.: %d\n",
+ feingabe[F_OBJ], feingabe[F_MSG] || "", feingabe[F_PROG],
+ feingabe[F_LINE]), 78, "", BS_LEAVE_MY_LFS));
+ }, INPUT_PROMPT|INPUT_APPEND,
+ "Zeilennr. eingeben, in der der Fehler auftritt (falls bekannt):\n");
+
+ input_to(#'_feingabe_fertig,
+ INPUT_PROMPT|INPUT_APPEND, "Eingaben korrekt? (j/n)\n");
+
+ return 1;
+}
+
+public int CmdFehlerZeigen(string arg)
+{
+ int issueid;
+
+ if (stringp(arg) && sizeof(arg))
+ {
+ arg = trim(arg, TRIM_BOTH);
+ issueid = to_int(arg);
+ }
+ else
+ {
+ issueid = lfehler;
+ arg = to_string(issueid);
+ }
+ notify_fail("Einen Eintrag mit dieser ID gibt es nicht!\n");
+
+ // Mit einem / am Anfang ist arg wohl ein Filename, wenn to_string(issueid)
+ // == arg wird die Issueid von oben genommen.
+ struct fullissue_s issue;
+ struct fullissue_s *issues;
+ if (arg[0] == '/')
+ {
+ issues=({});
+ foreach(int m: ALL_ERR_TYPES)
+ {
+ if (!(m & modus))
+ continue;
+ struct fullissue_s *tmp =
+ (struct fullissue_s *)ERRORD->QueryIssuesByFile(arg, m);
+ if (tmp)
+ issues+=tmp;
+ }
+ if (!sizeof(issues))
+ issues=0;
+ }
+ else if (to_string(issueid) == arg)
+ issue = (struct fullissue_s)ERRORD->QueryIssueByID(issueid);
+ else
+ issue = (struct fullissue_s)ERRORD->QueryIssueByHash(arg);
+
+ if (structp(issue))
+ {
+ show_entry(issue);
+ // letzten Fehler merken.
+ lfehler = issueid;
+ return 1;
+ }
+ // Wenn das nicht erfolgreich ist, ist das Argument evtl. ein Objekt-,
+ // Programm- oder Ladename. In dem Fall alle von denen anzeigen, die passen
+ // hierbei wird der Typ NICHT beruecksichtigt.
+ else if (pointerp(issues))
+ {
+ foreach(issue : issues)
+ {
+ show_entry(issue);
+ }
+ return 1;
+ }
+
+ notify_fail("Keine Eintraege fuer diesen Dateinamen/diese ID gefunden.\n");
+ return 0;
+}
+
+// Loescht alle Fehler und Warnungen eines Objekts (soweit per modus
+// ausgewaehlt). Entscheidend ist der _Loadname_!
+private int DeleteErrorsForLoadname(string loadname)
+{
+ int sum_deleted;
+ // Bei == 0 wird sonst alles geloescht. ;-)
+ if (!loadname)
+ return 0;
+
+ foreach(int m: ALL_ERR_TYPES)
+ {
+ if (!(m & modus))
+ continue;
+ < <int|string>* >* list = ERRORD->QueryIssueListByLoadname(loadname,m);
+ if (pointerp(list))
+ {
+ foreach(<int|string>* row : list)
+ {
+ if ((int)ERRORD->ToggleDeleteError(row[0]) == 1)
+ {
+ tell_object(PL,
+ row[0] + " als geloescht markiert.\n");
+ }
+ }
+ sum_deleted+=sizeof(list);
+ }
+ }
+ return sum_deleted;
+}
+
+public int CmdFehlerLoeschen(string arg)
+{
+ int issueid;
+ arg = (string)this_player()->_unparsed_args(0);
+
+ if (stringp(arg) && sizeof(arg))
+ issueid = to_int(arg);
+ else
+ issueid = lfehler;
+
+ notify_fail("Einen Eintrag mit dieser ID/diesem Loadname gibt es nicht!\n");
+
+ int res = (int)ERRORD->ToggleDeleteError(issueid);
+ if (res == 1)
+ {
+ tell_object(PL,
+ "Fehler/Warnung wurde zum Loeschen markiert und wird in Kuerze "
+ "geloescht.\n");
+ lfehler = issueid;
+ return 1;
+ }
+ else if (res==0)
+ {
+ tell_object(PL,"Loeschmarkierung wurde entfernt.\n");
+ lfehler = issueid;
+ return 1;
+ }
+ else if (res < -1)
+ {
+ tell_object(PL, "Irgendwas ist beim Loeschen schiefgegangen. "
+ "Keine Schreibrechte?\n");
+ lfehler = issueid;
+ return 1;
+ }
+ // res war == -1 -> Fehler nicht gefunden. Vielleicht ist es nen Loadname
+ return DeleteErrorsForLoadname(arg);
+}
+
+public int CmdRefresh(string arg) {
+ reset();
+ tell_object(PL,"Fehlerdaten wurden neu eingelesen.\n");
+ return 1;
+}
+
+private int select_modus(string arg) {
+ int lmodus;
+ switch(arg) {
+ case "alles":
+ case "alle":
+ lmodus = T_RTERROR | T_RTWARN | T_CTERROR | T_CTWARN | T_REPORTED_ERR
+ | T_REPORTED_IDEA | T_REPORTED_TYPO | T_REPORTED_MD;
+ break;
+ case "fehler":
+ case "error":
+ case "errors":
+ lmodus=T_RTERROR | T_CTERROR | T_REPORTED_ERR;
+ break;
+ case "warnungen":
+ case "warnung":
+ case "warning":
+ case "warnings":
+ lmodus=T_RTWARN | T_CTWARN;
+ break;
+ case "laufzeitfehler":
+ lmodus=T_RTERROR;
+ break;
+ case "ladezeitfehler":
+ lmodus=T_CTERROR;
+ break;
+ case "fehlerhinweis":
+ case "fehlerhinweise":
+ case "hinweise":
+ lmodus=T_REPORTED_ERR;
+ break;
+ case "ideen":
+ case "idee":
+ lmodus=T_REPORTED_IDEA;
+ break;
+ case "md":
+ lmodus=T_REPORTED_MD;
+ break;
+ case "typo":
+ case "typos":
+ lmodus=T_REPORTED_TYPO;
+ break;
+ case "laufzeitwarnungen":
+ case "runtimewarnings":
+ lmodus=T_RTWARN;
+ break;
+ case "ladezeitwarnungen":
+ case "compiletimewarnings":
+ lmodus=T_CTWARN;
+ break;
+ default:
+ lmodus=modus;
+ }
+ return lmodus;
+}
+
+private string * errorlabel(int t)
+{
+ switch(t) {
+ case T_RTERROR:
+ return ({"Laufzeitfehler","Laufzeitfehler","Dieser Laufzeitfehler"});
+ case T_REPORTED_ERR:
+ return ({"Fehlerhinweis","Fehlerhinweise","Dieser Fehlerhinweis"});
+ case T_REPORTED_IDEA:
+ return ({"Idee","Ideen","Diese Idee"});
+ case T_REPORTED_MD:
+ return ({"fehlende Detail","fehlende Details","Dieses fehlende Detail"});
+ case T_REPORTED_TYPO:
+ return ({"Typo","Typos","Dieser Typo"});
+ case T_RTWARN:
+ return ({"Laufzeitwarnung","Laufzeitwarnungen","Diese Laufzeitwarnung"});
+ case T_CTWARN:
+ return ({"Ladezeitwarnung", "Ladezeitwarnungen","Diese Ladezeitwarnung"});
+ case T_CTERROR:
+ return ({"Ladezeitfehler","Ladezeitfehler","Dieser Ladezeitfehler"});
+ }
+ raise_error("Unkannter Fehlertyp: "+t+"\n");
+ return 0;
+}
+
+public int CmdFehlerListe(string arg) {
+ string txt;
+ //string *luids;
+ int lmodus; // modus fuer diese Liste
+ mapping fehlerbackup;
+
+ if (stringp(arg) && sizeof(arg))
+ {
+ lmodus=select_modus(arg);
+ if (lmodus != modus)
+ {
+ fehlerbackup=issuelist; // Fehlerliste von 'modus' aufheben
+ get_issuelist(lmodus); // neue Fehlerliste holen
+ }
+ }
+ else
+ lmodus=modus;
+/*
+ if (!fehlerzahl)
+ {
+ txt="Fuer Deine UIDs sind keine Fehler/Warnungen bekannt. :-)\n";
+ tell_object(PL,txt);
+ return 1;
+ }
+*/
+ foreach(int typ, mapping typemap : issuelist)
+ {
+ if (!(typ & lmodus))
+ continue; // Type nicht gewaehlt.
+ txt="";
+ if (!sizeof(typemap)) {
+ tell_object(PL,
+ "Es sind keine " + errorlabel(typ)[1] + "Deiner UIDs bekannt. :-)");
+ continue;
+ }
+ foreach(string uid, < <int|string>* >* list : typemap)
+ {
+ if (!sizeof(list)) continue;
+ if (filterstatus && member(filteruids, uid) > -1) continue;
+ //txt+=sprintf("%s:\n", uid);
+ foreach(<int|string>* row : list)
+ {
+ txt+=sprintf("%:6d | %:40-s | %:26-s\n",
+ row[0], row[1], row[2]);
+ }
+ }
+ if (txt && sizeof(txt))
+ {
+ txt = sprintf("\nFuer Deine UIDs sind folgende %s bekannt (Filter: %s):\n"
+ "%:6|s | %:40|s | %s\n",
+ errorlabel(typ)[1], (filterstatus ? "an" : "aus"),
+ "ID", "Loadname", "UID")
+ + txt;
+ tell_object(PL, txt);
+ }
+ else
+ {
+ tell_object(PL, sprintf(
+ "\nFuer Deine UIDs sind keine %s bekannt (Filter: %s):\n",
+ errorlabel(typ)[1], (filterstatus ? "an" : "aus")));
+ }
+ }
+
+ if (mappingp(fehlerbackup) && modus!=lmodus)
+ issuelist=fehlerbackup; // fehlerliste fuer 'modus' restaurieren
+ return 1;
+}
+
+public int CmdFilter(string arg) {
+
+ arg=(string)PL->_unparsed_args(0);
+
+ if (!stringp(arg) || !sizeof(arg)) {
+ tell_object(PL,break_string(
+ "Momentan interessieren Dich folgende UIDs nicht"
+ +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
+ +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
+ return 1;
+ }
+
+ if (arg=="keine") {
+ filteruids=({});
+ filterstatus=1;
+ tell_object(PL,break_string(
+ "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
+ "Fehler berichten. Momentan hast Du keine UIDs ausgeblendet. "
+ "(Filter an)",78));
+ }
+ else if (arg=="alle") {
+ filterstatus=1;
+ filteruids=uids;
+ tell_object(PL,break_string(
+ "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
+ "Fehler berichten. Du blendest momentan alle UIDs aus. "
+ "(Filter an)",78));
+ }
+ else if (arg=="aus") {
+ filterstatus=0;
+ tell_object(PL,break_string(
+ "Dein Fehlerteufel wird Dir nun wieder alle Fehler berichten. ",
+ 78));
+ }
+ else if (arg=="an" || arg=="ein") {
+ filterstatus=1;
+ tell_object(PL,break_string(
+ "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
+ "Fehler berichten.",78));
+ }
+ else {
+ foreach(string uid: explode(arg," ")-({""})) {
+ if (sizeof(uid)>1 && uid[0]=='+') {
+ if (member(filteruids,uid[1..])==-1)
+ filteruids+=({uid[1..]});
+ }
+ else if (sizeof(uid)>1 && uid[0]=='-') {
+ filteruids-=({uid[1..]});
+ }
+ else {
+ if (member(filteruids,uid)==-1)
+ filteruids+=({uid});
+ else
+ filteruids-=({uid});
+ }
+ }
+ }
+
+ tell_object(PL,break_string(
+ "Momentan interessieren Dich folgende UIDs nicht"
+ +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
+ +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
+
+ return 1;
+}
+
+public int CmdMonitor(string arg) {
+
+ arg=(string)PL->_unparsed_args(0);
+
+ if (!stringp(arg) || !sizeof(arg)) {
+ tell_object(PL,break_string(
+ "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
+ +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
+ +"\n", 78,"",BS_LEAVE_MY_LFS));
+ return 1;
+ }
+
+ if (arg=="keine") {
+ monitoruids=({});
+ xmonitoruids=({});
+ tell_object(PL,break_string(
+ "Dein Fehlerteufel wird Dir nun nur noch "
+ "Fehler Deiner eigenen UIDs berichten.",78));
+ return 1;
+ }
+ else {
+ foreach(string uid: explode(arg," ")-({""})) {
+ if (sizeof(uid)>1 && uid[0]=='+') {
+ if (member(monitoruids,uid[1..])==-1)
+ monitoruids+=({uid[1..]});
+ }
+ else if (sizeof(uid)>1 && uid[0]=='-') {
+ monitoruids-=({uid[1..]});
+ }
+ else {
+ if (member(monitoruids,uid)==-1)
+ monitoruids+=({uid});
+ else
+ monitoruids-=({uid});
+ }
+ }
+ }
+ get_uids();
+ tell_object(PL,break_string(
+ "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
+ +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
+ +"\n", 78,"",BS_LEAVE_MY_LFS));
+
+ return 1;
+}
+
+public int CmdModus(string arg) {
+ string txt;
+
+ // Argument verwursten
+ if (stringp(arg) && sizeof(arg)) {
+ modus = select_modus(arg);
+ reset(); // neue Fehlerliste holen
+ }
+ // aktuelle Einstellung ausgeben.
+ string *modstr=({});
+ if (modus & T_RTERROR)
+ modstr+=({"Fehler (Laufzeit)"});
+ if (modus & T_RTWARN)
+ modstr+=({"Warnungen (Laufzeit)"});
+ if (modus & T_CTERROR)
+ modstr+=({"Fehler (Ladezeit)"});
+ if (modus & T_CTWARN)
+ modstr+=({"Warnungen (Ladezeit)"});
+ if (modus & T_REPORTED_ERR)
+ modstr+=({"Fehlerhinweise"});
+ if (modus & T_REPORTED_IDEA)
+ modstr+=({"Idee"});
+ if (modus & T_REPORTED_MD)
+ modstr+=({"fehlende Details"});
+ if (modus & T_REPORTED_TYPO)
+ modstr+=({"Typo"});
+
+ tell_object(PL, break_string(
+ "Dein Fehlerteufel wird Dir nun ueber aufgetretene "
+ +CountUp(modstr)+" Bericht erstatten.",78));
+ return(1);
+}
+
+int CmdAddNote(string str) {
+ string *arr;
+
+ notify_fail("Bitte eine ID und einen Text angeben!\n");
+ if(!objectp(TI))
+ return 0;
+
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return 0;
+
+ arr=explode(str," ")-({""});
+ if (sizeof(arr)<2)
+ return 0;
+ int issueid = to_int(arr[0]);
+
+ str=implode(arr[1..]," "); //text wiederherstellen, aber ohne ID
+
+ switch((int)ERRORD->AddNote(issueid,str))
+ {
+ case -1:
+ tell_object(PL,
+ sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
+ return 1;
+ case -3:
+ return 0; //offenbar keine Notiz angegeben.
+ }
+ // letzten Fehler merken.
+ lfehler = issueid;
+
+ tell_object(PL,
+ sprintf("Deine Notiz wurde zu %d hinzugefuegt.\n",
+ issueid));
+ return 1;
+}
+
+int CmdFix(string str)
+{
+ string *arr;
+ int fixing, res;
+
+ notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
+ if(!objectp(TI))
+ return 0;
+
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return 0;
+
+ arr=explode(str," ")-({""});
+ if (!sizeof(arr))
+ return 0;
+
+ int issueid=to_int(arr[0]);
+ if (sizeof(arr)>1)
+ str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
+ else str=0;
+
+ if (query_verb()=="ffix" || query_verb()=="fehlerfix")
+ {
+ fixing=1;
+ res = (int)ERRORD->ResolveIssue(issueid, str);
+ }
+ else
+ {
+ res = (int)ERRORD->ReOpenIssue(issueid, str);
+ }
+
+ if (res==-1)
+ {
+ tell_object(PL,
+ sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
+ }
+ else if (res==-10)
+ {
+ tell_object(PL,
+ "Du hast leider keinen Schreibzugriff diesen Fehler.\n"
+ "Aber vielleicht moechtest Du mit fnotiz eine Notiz anhaengen?\n");
+ }
+ else if (res==-3)
+ {
+ if (fixing)
+ tell_object(PL,"Dieser Fehler ist bereits gefixt.\n");
+ else
+ tell_object(PL,"Dieser Fehler ist noch nicht gefixt.\n");
+ }
+ else if (res==1)
+ {
+ tell_object(PL,
+ sprintf("Fehler %d als gefixt markiert.\n",issueid));
+ }
+ else if (res==0)
+ {
+ tell_object(PL,
+ sprintf("Fehler %d als nicht gefixt markiert.\n",issueid));
+ }
+ // letzten Fehler merken.
+ lfehler = issueid;
+
+ return 1;
+}
+
+int CmdLock(string str) {
+ string *arr;
+ int locking;
+ int res;
+
+ notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
+ if(!objectp(TI))
+ return 0;
+
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return 0;
+
+ arr=explode(str," ")-({""});
+ if (!sizeof(arr))
+ return 0;
+
+ int issueid=to_int(arr[0]);
+ if (sizeof(arr)>1)
+ str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
+ else str=0;
+
+ if (query_verb()=="flock" || query_verb()=="fehlerlock")
+ {
+ locking=1;
+ res=(int)ERRORD->LockIssue(issueid,str);
+ }
+ else
+ {
+ res=(int)ERRORD->UnlockIssue(issueid,str);
+ }
+
+ if (res==-1)
+ {
+ tell_object(PL,
+ sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
+ }
+ else if (res==-10)
+ {
+ tell_object(PL,
+ "Du hast leider keinen Schreibzugriff diesen Fehler.\n");
+ }
+ else if (res==-3)
+ {
+ if (locking)
+ tell_object(PL,
+ "Dieser Fehler ist bereits vor autom. Loeschen geschuetzt.\n");
+ else
+ tell_object(PL,
+ "Dieser Fehler ist bereits zum autom. Loeschen freigegeben.\n");
+ }
+ else if (res==-2)
+ {
+ tell_object(PL,
+ "Dieser Fehler ist bereits gefixt und wird bald geloescht.\n");
+ }
+ else if (res==1)
+ {
+ tell_object(PL,
+ sprintf("Fehler %d vor autom. Loeschen geschuetzt.\n",issueid));
+ }
+ else if (res==0)
+ {
+ tell_object(PL,
+ sprintf("Fehler %d zum autom. Loeschen freigegeben.\n",issueid));
+ }
+ // letzten Fehler merken.
+ lfehler = issueid;
+
+ return 1;
+}
+
+int CmdReassign(string str) {
+
+ notify_fail("Bitte eine ID, die neue UID und ggf. eine Notiz angeben!\n");
+ if(!objectp(TI))
+ return 0;
+
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return 0;
+
+ string *arr=explode(str," ")-({""});
+ if (sizeof(arr)<2)
+ return 0;
+ int issueid=to_int(arr[0]);
+ string newuid=arr[1];
+
+ //text wiederherstellen, aber ohne Key und UID
+ if (sizeof(arr) > 2)
+ str = implode(arr[2..]," ");
+ else
+ str = 0;
+
+ switch((int)ERRORD->ReassignIssue(issueid, newuid, str))
+ {
+ case -1:
+ tell_object(PL,
+ sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
+ return(1);
+ case -10:
+ tell_object(PL,
+ sprintf("Du hast keine Schreibrechte auf Fehler %d\n",issueid));
+ return 1;
+ case -2:
+ return(0); //offenbar keine neue uid angegeben. (kann nicht)
+ case -3:
+ tell_object(PL,break_string(
+ "Alte == Neue UID ist irgendwie unsinnig...",78));
+ return 1;
+ }
+ // letzten Fehler merken.
+ lfehler = issueid;
+
+ tell_object(PL,break_string(
+ sprintf("Der Fehler der ID %d wurde an die UID %s "
+ "uebertragen.\n", issueid, newuid),78));
+ return 1;
+}
+
+// ************** public 'internal' functions **************
+public string QueryOwner() {return owner;}
+public mixed QueryIssueList() {return issuelist;}
+
+void create() {
+ if (!clonep(ME))
+ return;
+ ::create();
+
+ SetProp(P_SHORT,"Der Fehlerteufel");
+ SetProp(P_LONG,break_string(
+ "Dein Fehlerteufel soll Dir helfen, Informationen "
+ "ueber aufgetretene Fehler zu erhalten. Hierzu fragt er die "
+ "in \"Deinen\" UIDs aufgetretenen Fehler und deren Details vom "
+ "Fehlerspeicher der Mudlib ab. Folgende Kommandos kennt er:",78)
+ +"fehlerabfrage <id> - Fragt Details ueber Fehler mit der ID ab.\n"
+ "fehlerloeschen <id> - Fehler zum Loeschen markieren.\n"
+ "fehlerliste - Fehlerliste der eigenen UIDs anzeigen\n"
+ "fehlerrefresh - Fehlerdaten und UIDs neu einlesen\n"
+ "fehlerfilter - UIDs fuer den Filter angeben (s. manpage!)\n"
+ "fehlermodus - Fehler oder Warnungen ausgeben? (s. manpage)\n"
+ "fehlermonitor - zus. UIDs beobachten (s. manpage)\n"
+ "fnotiz <id> <note> - eine Notiz anhaengen\n"
+ "flock <id> <note> - Fehler vor autom. Loeschen schuetzen\n"
+ "funlock <id> <note> - Fehler zum autom. Loeschen freigeben\n"
+ "ffix <id> <note> - Fehler als gefixt kennzeichnen\n"
+ "funfix <id> <note> - gefixten Fehler als nicht-gefixt markieren\n"
+ "fuebertrage <id> <newuid> <note>\n"
+ " - Fehler an die UID uebertragen\n"
+ );
+ SetProp(P_NAME,"Fehlerteufel");
+ SetProp(P_GENDER,MALE);
+ SetProp(P_WEIGHT,0);
+ SetProp(P_VALUE,0);
+ SetProp(P_SIZE,10);
+ SetProp(P_NODROP,"Den Fehlerteufel behaelst Du lieber bei Dir.\n");
+ SetProp(P_NEVERDROP,1);
+
+ AddId( ({"fehlerteufel","teufel"}) );
+
+ AddCmd(({"fehlerabfrage","fabfrage"}), "CmdFehlerZeigen" );
+ AddCmd(({"fehlerloeschen","floeschen"}), "CmdFehlerLoeschen");
+ AddCmd(({"fehlerliste","fliste", "fehleruebersicht","fuebersicht"}),
+ "CmdFehlerListe");
+ AddCmd(({"fehlerrefresh","frefresh"}),"CmdRefresh");
+ AddCmd(({"fehlerfilter","ffilter"}),"CmdFilter");
+ AddCmd(({"fehlermodus","fmodus"}),"CmdModus");
+ AddCmd(({"fehlermonitor","fmonitor"}),"CmdMonitor");
+ AddCmd(({"fehlernotiz","fnotiz"}),"CmdAddNote");
+ AddCmd(({"fehlerlock","flock","fehlerunlock","funlock"}),
+ "CmdLock");
+ AddCmd(({"fehlerfix","ffix","fehlerunfix","funfix"}),
+ "CmdFix");
+ AddCmd(({"fehleruebertrage","fuebertrage"}),"CmdReassign");
+ AddCmd(({"fehlereingabe", "feingabe"}), "CmdFehlerEingabe");
+}
+
+void init()
+{
+ if (find_call_out("remove") != -1) return;
+
+ // pruefung auf env nicht noetig, move geht nur in ein env und ohne env
+ // auch kein init().
+ if ( !query_once_interactive(environment()) ||
+ !IS_LEARNER(environment())) {
+ // in interactive, aber kein magier -> direkt weg.
+ call_out("remove",0,1);
+ return;
+ }
+ else if (!sizeof(owner))
+ // Env ist Interactiv und Magier (sonst waer man oben rausgeflogen)
+ owner=getuid(environment());
+ else if (owner!=getuid(environment())) {
+ //ok, nicht der Eigentuemer, direkt weg.
+ call_out("remove",0);
+ return;
+ }
+ SetProp(P_EXTRA_LOOK,break_string(
+ "Auf "+environment()->Name(WESSEN)+" Schulter sitzt ein kleiner "
+ "Fehlerteufel, der "
+ +environment()->QueryPronoun(WEM)
+ +" immer wieder etwas ins Ohr fluestert.",78));
+
+ call_out("reset",1);
+
+ ::init();
+}
+
+public mixed Configure(mixed data)
+{
+ if (!data)
+ {
+ return (["filteruids":filteruids,
+ "filterstatus":filterstatus,
+ "modus":modus,
+ "monitoruids":monitoruids,
+ "fehlerzahl": fehlerzahl]);
+ }
+ else if (mappingp(data))
+ {
+ if (member(data,"filteruids") && pointerp(data["filteruids"]))
+ filteruids=data["filteruids"];
+ if (member(data,"filterstatus") && intp(data["filterstatus"]))
+ filterstatus=data["filterstatus"];
+ if (member(data,"modus") && intp(data["modus"]))
+ modus=data["modus"];
+ if (member(data,"monitoruids") && pointerp(data["monitoruids"]))
+ monitoruids=data["monitoruids"];
+ if (member(data,"fehlerzahl") && intp(data["fehlerzahl"]))
+ fehlerzahl=data["fehlerzahl"];
+ return 1;
+ }
+ return 0;
+}
+
+mapping _query_autoloadobj()
+{
+ return Configure(0);
+}
+
+mapping _set_autoloadobj(mixed data)
+{
+ Configure(data);
+ return _query_autoloadobj();
+}
+
+
+void reset()
+{
+ get_uids();
+ int neuefehlerzahl=get_issuelist();
+
+ if (fehlerzahl < neuefehlerzahl)
+ tell_object(environment(ME), break_string(
+ "Deine Fehlerliste ist soeben laenger geworden.",78,
+ "Dein Fehlerteufel teilt Dir mit: "));
+ else if (fehlerzahl > neuefehlerzahl)
+ tell_object(environment(ME), break_string(
+ "Deine Fehlerliste ist soeben kuerzer geworden.",78,
+ "Dein Fehlerteufel teilt Dir mit: "));
+ fehlerzahl = neuefehlerzahl;
+}
+
+// ******** private functions *********************
+private void get_uids()
+{
+ uids=(string *)master()->QueryUIDsForWizard(owner);
+ xmonitoruids=({});
+ if (sizeof(monitoruids))
+ {
+ closure cl=symbol_function("QueryUIDAlias", master());
+ foreach(string uid: monitoruids) {
+ xmonitoruids += (string*)funcall(cl, uid);
+ }
+ }
+}
+
+/* Holt sich aus dem ErrorD die Liste ungeloeschter und ungefixter Fehler fuer
+ * fuer die UIDs des Magier fuer alle Typen
+ */
+private varargs int get_issuelist(int lmodus)
+{
+ int count;
+
+ if (!lmodus)
+ lmodus=modus;
+
+ issuelist=m_allocate(sizeof(ALL_ERR_TYPES),1);
+
+ foreach(int type: ALL_ERR_TYPES)
+ {
+ if (type & lmodus)
+ {
+ //DEBUG(sprintf("Type: %d\n",type));
+ foreach(string uid : uids + xmonitoruids)
+ {
+ //DEBUG(sprintf("Type: %d, UID: %s\n",type,uid));
+ < <int|string>* >* list =
+ (< <int|string>* >*)ERRORD->QueryIssueList(type,uid);
+ count += sizeof(list);
+
+ if (!member(issuelist, type))
+ issuelist += ([ type: ([ uid: list ]) ]);
+ else if (!member(issuelist[type], uid))
+ issuelist[type] += ([uid: list ]);
+ }
+ }
+ }
+ return count;
+}
+