blob: a35fec1caae1a6635ce62933b9f9ee3a57cf23d6 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/* /obj/toostels/fehlerteufel.c
2 Fehlerteufel - Magiertool zur Abfrage des Fehler-Daemons der Mudlib
3 Autor: Zesstra
4 Changelog:
5*/
6
7#pragma strict_types
8#pragma pedantic
9#pragma range_check
10#pragma no_shadow
11#pragma no_inherit
12
13inherit "/std/secure_thing";
14inherit "/secure/errord-structs";
15
16#include <defines.h>
17#include <wizlevels.h>
18#include <properties.h>
19#include <moving.h>
20#include <errord.h>
21#include <config.h>
22#include <debug_info.h>
23#include <input_to.h>
24#include <strings.h>
25
26#define TI this_interactive()
27
28#define DEBUG(x) if (funcall(symbol_function('find_player),"zesstra"))\
29 tell_object(funcall(symbol_function('find_player),"zesstra"),\
30 "EDBG: "+x+"\n")
31
32// variables
33private string owner; // UID vom Eigentuemer
34private string *uids=({}); // UIDs, auf die man schreibrechte hat
35private string *filteruids=({}); // wenn nicht-leer, nur diese UIDs zeigen
36private string *monitoruids=({}); // diese UIDs in die Liste einschliessen
37private int filterstatus=0; // Filter an oder aus?
38private mapping issuelist = ([]);
39/* ([ type1: ([uid1: <issuelist>, uid2: <issuelist> ]),
40 type2: ... ])
41 <issuelist> ist ein < <int|string>* >* vom ErrorD */
42
43//Welche Art von Fehler anzeigen?
44private int modus=T_RTERROR | T_RTWARN | T_REPORTED_ERR;
45private string *xmonitoruids = ({}); // expanded Monitor-UIDs
46private int lfehler; // letzter 'benutzter' Fehler.
47private int fehlerzahl; // fehlerzahl im letzten Reset.
48private mapping feingabe; // gerade eingegebener Fehler
49
50// ************** private functions **************
51private varargs int get_issuelist(int lmodus);
52private void get_uids();
53
54// irgendeinen Fehler oder Warnung anzeigen.
55private int show_entry(struct fullissue_s issue)
56{
57 if (!issue) return 0;
58
59 string txt=ERRORD->format_error(issue, 0);
60
61 if (!stringp(txt) || !sizeof(txt))
62 return 0;
63
64 tell_object(PL,txt+"\n");
65 return 1;
66}
67
68protected int _feingabe_fertig(string arg) {
69
70 if (arg == "j")
71 {
72 if (!feingabe[F_MSG])
73 {
74 tell_object(PL,
75 "Also, eine Fehlerbeschreibung solltest Du schon eingeben! Abgebrochen.\n");
76 }
77 else
78 {
79 string hashkey = (string)ERRORD->LogReportedError(feingabe);
80 tell_object(PL, sprintf(
81 "Vielen Dank! Die ID des eingegebenen Fehlers lautet: %s\n",
82 hashkey || "N/A"));
83 }
84 }
85 else
86 {
87 tell_object(PL, "Fehlereingabe abgebrochen.\n");
88 }
89
90 feingabe = 0;
91
92 return 1;
93}
94
95public int CmdFehlerEingabe(string arg) {
96 object target;
97
98 if (feingabe)
99 {
100 tell_object(PL, "Du gibts doch bereits einen Fehler ein!\n");
101 return 1;
102 }
103 feingabe = ([]);
104
105 if (arg)
106 {
107 target = present(arg);
108 if (!target)
109 target = find_object(arg); // vielleicht direkt angegeben?
110 }
111 // wenn nix gefunden, Environment des Magiers nehmen.
112 if (!target)
113 target = environment(environment());
114
115 feingabe[F_OBJ] = target;
116
117 tell_object(PL, break_string(sprintf(
118 "Du beginnst einen Fehlereintrag fuer das Objekt: %O\n", target),78));
119
120 input_to(function void (string str)
121 {
122 if (sizeof(str)) feingabe[F_MSG] = str;
123 }, INPUT_PROMPT, "Fehlerbeschreibung eingeben:\n");
124
125 input_to(function void (string str)
126 {
127 if (sizeof(str)) feingabe[F_PROG] = str;
128 else feingabe[F_PROG] = "unbekannt";
129 }, INPUT_PROMPT|INPUT_APPEND,
130 "Programm eingeben, in dem der Fehler auftritt (falls bekannt):\n");
131
132 input_to(function void (string str)
133 {
134 if (sizeof(str)) feingabe[F_LINE] = to_int(str);
135 tell_object(PL,break_string(sprintf(
136 "Du hast die folgenden Daten eingegeben:\n"
137 "Objekt: %O\n"
138 "Fehlerbeschreibung: %s\n"
139 "Programm: %s\n"
140 "Zeilennr.: %d\n",
141 feingabe[F_OBJ], feingabe[F_MSG] || "", feingabe[F_PROG],
142 feingabe[F_LINE]), 78, "", BS_LEAVE_MY_LFS));
143 }, INPUT_PROMPT|INPUT_APPEND,
144 "Zeilennr. eingeben, in der der Fehler auftritt (falls bekannt):\n");
145
146 input_to(#'_feingabe_fertig,
147 INPUT_PROMPT|INPUT_APPEND, "Eingaben korrekt? (j/n)\n");
148
149 return 1;
150}
151
152public int CmdFehlerZeigen(string arg)
153{
154 int issueid;
155
156 if (stringp(arg) && sizeof(arg))
157 {
158 arg = trim(arg, TRIM_BOTH);
159 issueid = to_int(arg);
160 }
161 else
162 {
163 issueid = lfehler;
164 arg = to_string(issueid);
165 }
166 notify_fail("Einen Eintrag mit dieser ID gibt es nicht!\n");
167
168 // Mit einem / am Anfang ist arg wohl ein Filename, wenn to_string(issueid)
169 // == arg wird die Issueid von oben genommen.
170 struct fullissue_s issue;
171 struct fullissue_s *issues;
172 if (arg[0] == '/')
173 {
174 issues=({});
175 foreach(int m: ALL_ERR_TYPES)
176 {
177 if (!(m & modus))
178 continue;
179 struct fullissue_s *tmp =
180 (struct fullissue_s *)ERRORD->QueryIssuesByFile(arg, m);
181 if (tmp)
182 issues+=tmp;
183 }
184 if (!sizeof(issues))
185 issues=0;
186 }
187 else if (to_string(issueid) == arg)
188 issue = (struct fullissue_s)ERRORD->QueryIssueByID(issueid);
189 else
190 issue = (struct fullissue_s)ERRORD->QueryIssueByHash(arg);
191
192 if (structp(issue))
193 {
194 show_entry(issue);
195 // letzten Fehler merken.
196 lfehler = issueid;
197 return 1;
198 }
199 // Wenn das nicht erfolgreich ist, ist das Argument evtl. ein Objekt-,
200 // Programm- oder Ladename. In dem Fall alle von denen anzeigen, die passen
201 // hierbei wird der Typ NICHT beruecksichtigt.
202 else if (pointerp(issues))
203 {
204 foreach(issue : issues)
205 {
206 show_entry(issue);
207 }
208 return 1;
209 }
210
211 notify_fail("Keine Eintraege fuer diesen Dateinamen/diese ID gefunden.\n");
212 return 0;
213}
214
215// Loescht alle Fehler und Warnungen eines Objekts (soweit per modus
216// ausgewaehlt). Entscheidend ist der _Loadname_!
217private int DeleteErrorsForLoadname(string loadname)
218{
219 int sum_deleted;
220 // Bei == 0 wird sonst alles geloescht. ;-)
221 if (!loadname)
222 return 0;
223
224 foreach(int m: ALL_ERR_TYPES)
225 {
226 if (!(m & modus))
227 continue;
228 < <int|string>* >* list = ERRORD->QueryIssueListByLoadname(loadname,m);
229 if (pointerp(list))
230 {
231 foreach(<int|string>* row : list)
232 {
233 if ((int)ERRORD->ToggleDeleteError(row[0]) == 1)
234 {
235 tell_object(PL,
236 row[0] + " als geloescht markiert.\n");
237 }
238 }
239 sum_deleted+=sizeof(list);
240 }
241 }
242 return sum_deleted;
243}
244
245public int CmdFehlerLoeschen(string arg)
246{
247 int issueid;
248 arg = (string)this_player()->_unparsed_args(0);
249
250 if (stringp(arg) && sizeof(arg))
251 issueid = to_int(arg);
252 else
253 issueid = lfehler;
254
255 notify_fail("Einen Eintrag mit dieser ID/diesem Loadname gibt es nicht!\n");
256
257 int res = (int)ERRORD->ToggleDeleteError(issueid);
258 if (res == 1)
259 {
260 tell_object(PL,
261 "Fehler/Warnung wurde zum Loeschen markiert und wird in Kuerze "
262 "geloescht.\n");
263 lfehler = issueid;
264 return 1;
265 }
266 else if (res==0)
267 {
268 tell_object(PL,"Loeschmarkierung wurde entfernt.\n");
269 lfehler = issueid;
270 return 1;
271 }
272 else if (res < -1)
273 {
274 tell_object(PL, "Irgendwas ist beim Loeschen schiefgegangen. "
275 "Keine Schreibrechte?\n");
276 lfehler = issueid;
277 return 1;
278 }
279 // res war == -1 -> Fehler nicht gefunden. Vielleicht ist es nen Loadname
280 return DeleteErrorsForLoadname(arg);
281}
282
283public int CmdRefresh(string arg) {
284 reset();
285 tell_object(PL,"Fehlerdaten wurden neu eingelesen.\n");
286 return 1;
287}
288
289private int select_modus(string arg) {
290 int lmodus;
291 switch(arg) {
292 case "alles":
293 case "alle":
294 lmodus = T_RTERROR | T_RTWARN | T_CTERROR | T_CTWARN | T_REPORTED_ERR
295 | T_REPORTED_IDEA | T_REPORTED_TYPO | T_REPORTED_MD;
296 break;
297 case "fehler":
298 case "error":
299 case "errors":
300 lmodus=T_RTERROR | T_CTERROR | T_REPORTED_ERR;
301 break;
302 case "warnungen":
303 case "warnung":
304 case "warning":
305 case "warnings":
306 lmodus=T_RTWARN | T_CTWARN;
307 break;
308 case "laufzeitfehler":
309 lmodus=T_RTERROR;
310 break;
311 case "ladezeitfehler":
312 lmodus=T_CTERROR;
313 break;
314 case "fehlerhinweis":
315 case "fehlerhinweise":
316 case "hinweise":
317 lmodus=T_REPORTED_ERR;
318 break;
319 case "ideen":
320 case "idee":
321 lmodus=T_REPORTED_IDEA;
322 break;
323 case "md":
324 lmodus=T_REPORTED_MD;
325 break;
326 case "typo":
327 case "typos":
328 lmodus=T_REPORTED_TYPO;
329 break;
330 case "laufzeitwarnungen":
331 case "runtimewarnings":
332 lmodus=T_RTWARN;
333 break;
334 case "ladezeitwarnungen":
335 case "compiletimewarnings":
336 lmodus=T_CTWARN;
337 break;
338 default:
339 lmodus=modus;
340 }
341 return lmodus;
342}
343
344private string * errorlabel(int t)
345{
346 switch(t) {
347 case T_RTERROR:
348 return ({"Laufzeitfehler","Laufzeitfehler","Dieser Laufzeitfehler"});
349 case T_REPORTED_ERR:
350 return ({"Fehlerhinweis","Fehlerhinweise","Dieser Fehlerhinweis"});
351 case T_REPORTED_IDEA:
352 return ({"Idee","Ideen","Diese Idee"});
353 case T_REPORTED_MD:
354 return ({"fehlende Detail","fehlende Details","Dieses fehlende Detail"});
355 case T_REPORTED_TYPO:
356 return ({"Typo","Typos","Dieser Typo"});
357 case T_RTWARN:
358 return ({"Laufzeitwarnung","Laufzeitwarnungen","Diese Laufzeitwarnung"});
359 case T_CTWARN:
360 return ({"Ladezeitwarnung", "Ladezeitwarnungen","Diese Ladezeitwarnung"});
361 case T_CTERROR:
362 return ({"Ladezeitfehler","Ladezeitfehler","Dieser Ladezeitfehler"});
363 }
364 raise_error("Unkannter Fehlertyp: "+t+"\n");
365 return 0;
366}
367
368public int CmdFehlerListe(string arg) {
369 string txt;
370 //string *luids;
371 int lmodus; // modus fuer diese Liste
372 mapping fehlerbackup;
373
374 if (stringp(arg) && sizeof(arg))
375 {
376 lmodus=select_modus(arg);
377 if (lmodus != modus)
378 {
379 fehlerbackup=issuelist; // Fehlerliste von 'modus' aufheben
380 get_issuelist(lmodus); // neue Fehlerliste holen
381 }
382 }
383 else
384 lmodus=modus;
385/*
386 if (!fehlerzahl)
387 {
388 txt="Fuer Deine UIDs sind keine Fehler/Warnungen bekannt. :-)\n";
389 tell_object(PL,txt);
390 return 1;
391 }
392*/
393 foreach(int typ, mapping typemap : issuelist)
394 {
395 if (!(typ & lmodus))
396 continue; // Type nicht gewaehlt.
397 txt="";
398 if (!sizeof(typemap)) {
399 tell_object(PL,
400 "Es sind keine " + errorlabel(typ)[1] + "Deiner UIDs bekannt. :-)");
401 continue;
402 }
403 foreach(string uid, < <int|string>* >* list : typemap)
404 {
405 if (!sizeof(list)) continue;
406 if (filterstatus && member(filteruids, uid) > -1) continue;
407 //txt+=sprintf("%s:\n", uid);
408 foreach(<int|string>* row : list)
409 {
410 txt+=sprintf("%:6d | %:40-s | %:26-s\n",
411 row[0], row[1], row[2]);
412 }
413 }
414 if (txt && sizeof(txt))
415 {
416 txt = sprintf("\nFuer Deine UIDs sind folgende %s bekannt (Filter: %s):\n"
417 "%:6|s | %:40|s | %s\n",
418 errorlabel(typ)[1], (filterstatus ? "an" : "aus"),
419 "ID", "Loadname", "UID")
420 + txt;
421 tell_object(PL, txt);
422 }
423 else
424 {
425 tell_object(PL, sprintf(
426 "\nFuer Deine UIDs sind keine %s bekannt (Filter: %s):\n",
427 errorlabel(typ)[1], (filterstatus ? "an" : "aus")));
428 }
429 }
430
431 if (mappingp(fehlerbackup) && modus!=lmodus)
432 issuelist=fehlerbackup; // fehlerliste fuer 'modus' restaurieren
433 return 1;
434}
435
436public int CmdFilter(string arg) {
437
438 arg=(string)PL->_unparsed_args(0);
439
440 if (!stringp(arg) || !sizeof(arg)) {
441 tell_object(PL,break_string(
442 "Momentan interessieren Dich folgende UIDs nicht"
443 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
444 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
445 return 1;
446 }
447
448 if (arg=="keine") {
449 filteruids=({});
450 filterstatus=1;
451 tell_object(PL,break_string(
452 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
453 "Fehler berichten. Momentan hast Du keine UIDs ausgeblendet. "
454 "(Filter an)",78));
455 }
456 else if (arg=="alle") {
457 filterstatus=1;
458 filteruids=uids;
459 tell_object(PL,break_string(
460 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
461 "Fehler berichten. Du blendest momentan alle UIDs aus. "
462 "(Filter an)",78));
463 }
464 else if (arg=="aus") {
465 filterstatus=0;
466 tell_object(PL,break_string(
467 "Dein Fehlerteufel wird Dir nun wieder alle Fehler berichten. ",
468 78));
469 }
470 else if (arg=="an" || arg=="ein") {
471 filterstatus=1;
472 tell_object(PL,break_string(
473 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
474 "Fehler berichten.",78));
475 }
476 else {
477 foreach(string uid: explode(arg," ")-({""})) {
478 if (sizeof(uid)>1 && uid[0]=='+') {
479 if (member(filteruids,uid[1..])==-1)
480 filteruids+=({uid[1..]});
481 }
482 else if (sizeof(uid)>1 && uid[0]=='-') {
483 filteruids-=({uid[1..]});
484 }
485 else {
486 if (member(filteruids,uid)==-1)
487 filteruids+=({uid});
488 else
489 filteruids-=({uid});
490 }
491 }
492 }
493
494 tell_object(PL,break_string(
495 "Momentan interessieren Dich folgende UIDs nicht"
496 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
497 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
498
499 return 1;
500}
501
502public int CmdMonitor(string arg) {
503
504 arg=(string)PL->_unparsed_args(0);
505
506 if (!stringp(arg) || !sizeof(arg)) {
507 tell_object(PL,break_string(
508 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
509 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
510 +"\n", 78,"",BS_LEAVE_MY_LFS));
511 return 1;
512 }
513
514 if (arg=="keine") {
515 monitoruids=({});
516 xmonitoruids=({});
517 tell_object(PL,break_string(
518 "Dein Fehlerteufel wird Dir nun nur noch "
519 "Fehler Deiner eigenen UIDs berichten.",78));
520 return 1;
521 }
522 else {
523 foreach(string uid: explode(arg," ")-({""})) {
524 if (sizeof(uid)>1 && uid[0]=='+') {
525 if (member(monitoruids,uid[1..])==-1)
526 monitoruids+=({uid[1..]});
527 }
528 else if (sizeof(uid)>1 && uid[0]=='-') {
529 monitoruids-=({uid[1..]});
530 }
531 else {
532 if (member(monitoruids,uid)==-1)
533 monitoruids+=({uid});
534 else
535 monitoruids-=({uid});
536 }
537 }
538 }
539 get_uids();
540 tell_object(PL,break_string(
541 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
542 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
543 +"\n", 78,"",BS_LEAVE_MY_LFS));
544
545 return 1;
546}
547
548public int CmdModus(string arg) {
549 string txt;
550
551 // Argument verwursten
552 if (stringp(arg) && sizeof(arg)) {
553 modus = select_modus(arg);
554 reset(); // neue Fehlerliste holen
555 }
556 // aktuelle Einstellung ausgeben.
557 string *modstr=({});
558 if (modus & T_RTERROR)
559 modstr+=({"Fehler (Laufzeit)"});
560 if (modus & T_RTWARN)
561 modstr+=({"Warnungen (Laufzeit)"});
562 if (modus & T_CTERROR)
563 modstr+=({"Fehler (Ladezeit)"});
564 if (modus & T_CTWARN)
565 modstr+=({"Warnungen (Ladezeit)"});
566 if (modus & T_REPORTED_ERR)
567 modstr+=({"Fehlerhinweise"});
568 if (modus & T_REPORTED_IDEA)
569 modstr+=({"Idee"});
570 if (modus & T_REPORTED_MD)
571 modstr+=({"fehlende Details"});
572 if (modus & T_REPORTED_TYPO)
573 modstr+=({"Typo"});
574
575 tell_object(PL, break_string(
576 "Dein Fehlerteufel wird Dir nun ueber aufgetretene "
577 +CountUp(modstr)+" Bericht erstatten.",78));
578 return(1);
579}
580
581int CmdAddNote(string str) {
582 string *arr;
583
584 notify_fail("Bitte eine ID und einen Text angeben!\n");
585 if(!objectp(TI))
586 return 0;
587
588 str=(string)PL->_unparsed_args(0);
589 if (!stringp(str) || !sizeof(str))
590 return 0;
591
592 arr=explode(str," ")-({""});
593 if (sizeof(arr)<2)
594 return 0;
595 int issueid = to_int(arr[0]);
596
597 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne ID
598
599 switch((int)ERRORD->AddNote(issueid,str))
600 {
601 case -1:
602 tell_object(PL,
603 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
604 return 1;
605 case -3:
606 return 0; //offenbar keine Notiz angegeben.
607 }
608 // letzten Fehler merken.
609 lfehler = issueid;
610
611 tell_object(PL,
612 sprintf("Deine Notiz wurde zu %d hinzugefuegt.\n",
613 issueid));
614 return 1;
615}
616
617int CmdFix(string str)
618{
619 string *arr;
620 int fixing, res;
621
622 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
623 if(!objectp(TI))
624 return 0;
625
626 str=(string)PL->_unparsed_args(0);
627 if (!stringp(str) || !sizeof(str))
628 return 0;
629
630 arr=explode(str," ")-({""});
631 if (!sizeof(arr))
632 return 0;
633
634 int issueid=to_int(arr[0]);
635 if (sizeof(arr)>1)
636 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
637 else str=0;
638
639 if (query_verb()=="ffix" || query_verb()=="fehlerfix")
640 {
641 fixing=1;
642 res = (int)ERRORD->ResolveIssue(issueid, str);
643 }
644 else
645 {
646 res = (int)ERRORD->ReOpenIssue(issueid, str);
647 }
648
649 if (res==-1)
650 {
651 tell_object(PL,
652 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
653 }
654 else if (res==-10)
655 {
656 tell_object(PL,
657 "Du hast leider keinen Schreibzugriff diesen Fehler.\n"
658 "Aber vielleicht moechtest Du mit fnotiz eine Notiz anhaengen?\n");
659 }
660 else if (res==-3)
661 {
662 if (fixing)
663 tell_object(PL,"Dieser Fehler ist bereits gefixt.\n");
664 else
665 tell_object(PL,"Dieser Fehler ist noch nicht gefixt.\n");
666 }
667 else if (res==1)
668 {
669 tell_object(PL,
670 sprintf("Fehler %d als gefixt markiert.\n",issueid));
671 }
672 else if (res==0)
673 {
674 tell_object(PL,
675 sprintf("Fehler %d als nicht gefixt markiert.\n",issueid));
676 }
677 // letzten Fehler merken.
678 lfehler = issueid;
679
680 return 1;
681}
682
683int CmdLock(string str) {
684 string *arr;
685 int locking;
686 int res;
687
688 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
689 if(!objectp(TI))
690 return 0;
691
692 str=(string)PL->_unparsed_args(0);
693 if (!stringp(str) || !sizeof(str))
694 return 0;
695
696 arr=explode(str," ")-({""});
697 if (!sizeof(arr))
698 return 0;
699
700 int issueid=to_int(arr[0]);
701 if (sizeof(arr)>1)
702 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
703 else str=0;
704
705 if (query_verb()=="flock" || query_verb()=="fehlerlock")
706 {
707 locking=1;
708 res=(int)ERRORD->LockIssue(issueid,str);
709 }
710 else
711 {
712 res=(int)ERRORD->UnlockIssue(issueid,str);
713 }
714
715 if (res==-1)
716 {
717 tell_object(PL,
718 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
719 }
720 else if (res==-10)
721 {
722 tell_object(PL,
723 "Du hast leider keinen Schreibzugriff diesen Fehler.\n");
724 }
725 else if (res==-3)
726 {
727 if (locking)
728 tell_object(PL,
729 "Dieser Fehler ist bereits vor autom. Loeschen geschuetzt.\n");
730 else
731 tell_object(PL,
732 "Dieser Fehler ist bereits zum autom. Loeschen freigegeben.\n");
733 }
734 else if (res==-2)
735 {
736 tell_object(PL,
737 "Dieser Fehler ist bereits gefixt und wird bald geloescht.\n");
738 }
739 else if (res==1)
740 {
741 tell_object(PL,
742 sprintf("Fehler %d vor autom. Loeschen geschuetzt.\n",issueid));
743 }
744 else if (res==0)
745 {
746 tell_object(PL,
747 sprintf("Fehler %d zum autom. Loeschen freigegeben.\n",issueid));
748 }
749 // letzten Fehler merken.
750 lfehler = issueid;
751
752 return 1;
753}
754
755int CmdReassign(string str) {
756
757 notify_fail("Bitte eine ID, die neue UID und ggf. eine Notiz angeben!\n");
758 if(!objectp(TI))
759 return 0;
760
761 str=(string)PL->_unparsed_args(0);
762 if (!stringp(str) || !sizeof(str))
763 return 0;
764
765 string *arr=explode(str," ")-({""});
766 if (sizeof(arr)<2)
767 return 0;
768 int issueid=to_int(arr[0]);
769 string newuid=arr[1];
770
771 //text wiederherstellen, aber ohne Key und UID
772 if (sizeof(arr) > 2)
773 str = implode(arr[2..]," ");
774 else
775 str = 0;
776
777 switch((int)ERRORD->ReassignIssue(issueid, newuid, str))
778 {
779 case -1:
780 tell_object(PL,
781 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
782 return(1);
783 case -10:
784 tell_object(PL,
785 sprintf("Du hast keine Schreibrechte auf Fehler %d\n",issueid));
786 return 1;
787 case -2:
788 return(0); //offenbar keine neue uid angegeben. (kann nicht)
789 case -3:
790 tell_object(PL,break_string(
791 "Alte == Neue UID ist irgendwie unsinnig...",78));
792 return 1;
793 }
794 // letzten Fehler merken.
795 lfehler = issueid;
796
797 tell_object(PL,break_string(
798 sprintf("Der Fehler der ID %d wurde an die UID %s "
799 "uebertragen.\n", issueid, newuid),78));
800 return 1;
801}
802
803// ************** public 'internal' functions **************
804public string QueryOwner() {return owner;}
805public mixed QueryIssueList() {return issuelist;}
806
807void create() {
808 if (!clonep(ME))
809 return;
810 ::create();
811
812 SetProp(P_SHORT,"Der Fehlerteufel");
813 SetProp(P_LONG,break_string(
814 "Dein Fehlerteufel soll Dir helfen, Informationen "
815 "ueber aufgetretene Fehler zu erhalten. Hierzu fragt er die "
816 "in \"Deinen\" UIDs aufgetretenen Fehler und deren Details vom "
817 "Fehlerspeicher der Mudlib ab. Folgende Kommandos kennt er:",78)
818 +"fehlerabfrage <id> - Fragt Details ueber Fehler mit der ID ab.\n"
819 "fehlerloeschen <id> - Fehler zum Loeschen markieren.\n"
820 "fehlerliste - Fehlerliste der eigenen UIDs anzeigen\n"
821 "fehlerrefresh - Fehlerdaten und UIDs neu einlesen\n"
822 "fehlerfilter - UIDs fuer den Filter angeben (s. manpage!)\n"
823 "fehlermodus - Fehler oder Warnungen ausgeben? (s. manpage)\n"
824 "fehlermonitor - zus. UIDs beobachten (s. manpage)\n"
825 "fnotiz <id> <note> - eine Notiz anhaengen\n"
826 "flock <id> <note> - Fehler vor autom. Loeschen schuetzen\n"
827 "funlock <id> <note> - Fehler zum autom. Loeschen freigeben\n"
828 "ffix <id> <note> - Fehler als gefixt kennzeichnen\n"
829 "funfix <id> <note> - gefixten Fehler als nicht-gefixt markieren\n"
830 "fuebertrage <id> <newuid> <note>\n"
831 " - Fehler an die UID uebertragen\n"
832 );
833 SetProp(P_NAME,"Fehlerteufel");
834 SetProp(P_GENDER,MALE);
835 SetProp(P_WEIGHT,0);
836 SetProp(P_VALUE,0);
837 SetProp(P_SIZE,10);
838 SetProp(P_NODROP,"Den Fehlerteufel behaelst Du lieber bei Dir.\n");
839 SetProp(P_NEVERDROP,1);
840
841 AddId( ({"fehlerteufel","teufel"}) );
842
843 AddCmd(({"fehlerabfrage","fabfrage"}), "CmdFehlerZeigen" );
844 AddCmd(({"fehlerloeschen","floeschen"}), "CmdFehlerLoeschen");
845 AddCmd(({"fehlerliste","fliste", "fehleruebersicht","fuebersicht"}),
846 "CmdFehlerListe");
847 AddCmd(({"fehlerrefresh","frefresh"}),"CmdRefresh");
848 AddCmd(({"fehlerfilter","ffilter"}),"CmdFilter");
849 AddCmd(({"fehlermodus","fmodus"}),"CmdModus");
850 AddCmd(({"fehlermonitor","fmonitor"}),"CmdMonitor");
851 AddCmd(({"fehlernotiz","fnotiz"}),"CmdAddNote");
852 AddCmd(({"fehlerlock","flock","fehlerunlock","funlock"}),
853 "CmdLock");
854 AddCmd(({"fehlerfix","ffix","fehlerunfix","funfix"}),
855 "CmdFix");
856 AddCmd(({"fehleruebertrage","fuebertrage"}),"CmdReassign");
857 AddCmd(({"fehlereingabe", "feingabe"}), "CmdFehlerEingabe");
858}
859
860void init()
861{
862 if (find_call_out("remove") != -1) return;
863
864 // pruefung auf env nicht noetig, move geht nur in ein env und ohne env
865 // auch kein init().
866 if ( !query_once_interactive(environment()) ||
867 !IS_LEARNER(environment())) {
868 // in interactive, aber kein magier -> direkt weg.
869 call_out("remove",0,1);
870 return;
871 }
872 else if (!sizeof(owner))
873 // Env ist Interactiv und Magier (sonst waer man oben rausgeflogen)
874 owner=getuid(environment());
875 else if (owner!=getuid(environment())) {
876 //ok, nicht der Eigentuemer, direkt weg.
877 call_out("remove",0);
878 return;
879 }
880 SetProp(P_EXTRA_LOOK,break_string(
881 "Auf "+environment()->Name(WESSEN)+" Schulter sitzt ein kleiner "
882 "Fehlerteufel, der "
883 +environment()->QueryPronoun(WEM)
884 +" immer wieder etwas ins Ohr fluestert.",78));
885
886 call_out("reset",1);
887
888 ::init();
889}
890
891public mixed Configure(mixed data)
892{
893 if (!data)
894 {
895 return (["filteruids":filteruids,
896 "filterstatus":filterstatus,
897 "modus":modus,
898 "monitoruids":monitoruids,
899 "fehlerzahl": fehlerzahl]);
900 }
901 else if (mappingp(data))
902 {
903 if (member(data,"filteruids") && pointerp(data["filteruids"]))
904 filteruids=data["filteruids"];
905 if (member(data,"filterstatus") && intp(data["filterstatus"]))
906 filterstatus=data["filterstatus"];
907 if (member(data,"modus") && intp(data["modus"]))
908 modus=data["modus"];
909 if (member(data,"monitoruids") && pointerp(data["monitoruids"]))
910 monitoruids=data["monitoruids"];
911 if (member(data,"fehlerzahl") && intp(data["fehlerzahl"]))
912 fehlerzahl=data["fehlerzahl"];
913 return 1;
914 }
915 return 0;
916}
917
918mapping _query_autoloadobj()
919{
920 return Configure(0);
921}
922
923mapping _set_autoloadobj(mixed data)
924{
925 Configure(data);
926 return _query_autoloadobj();
927}
928
929
930void reset()
931{
932 get_uids();
933 int neuefehlerzahl=get_issuelist();
934
935 if (fehlerzahl < neuefehlerzahl)
936 tell_object(environment(ME), break_string(
937 "Deine Fehlerliste ist soeben laenger geworden.",78,
938 "Dein Fehlerteufel teilt Dir mit: "));
939 else if (fehlerzahl > neuefehlerzahl)
940 tell_object(environment(ME), break_string(
941 "Deine Fehlerliste ist soeben kuerzer geworden.",78,
942 "Dein Fehlerteufel teilt Dir mit: "));
943 fehlerzahl = neuefehlerzahl;
944}
945
946// ******** private functions *********************
947private void get_uids()
948{
949 uids=(string *)master()->QueryUIDsForWizard(owner);
950 xmonitoruids=({});
951 if (sizeof(monitoruids))
952 {
953 closure cl=symbol_function("QueryUIDAlias", master());
954 foreach(string uid: monitoruids) {
955 xmonitoruids += (string*)funcall(cl, uid);
956 }
957 }
958}
959
960/* Holt sich aus dem ErrorD die Liste ungeloeschter und ungefixter Fehler fuer
961 * fuer die UIDs des Magier fuer alle Typen
962 */
963private varargs int get_issuelist(int lmodus)
964{
965 int count;
966
967 if (!lmodus)
968 lmodus=modus;
969
970 issuelist=m_allocate(sizeof(ALL_ERR_TYPES),1);
971
972 foreach(int type: ALL_ERR_TYPES)
973 {
974 if (type & lmodus)
975 {
976 //DEBUG(sprintf("Type: %d\n",type));
977 foreach(string uid : uids + xmonitoruids)
978 {
979 //DEBUG(sprintf("Type: %d, UID: %s\n",type,uid));
980 < <int|string>* >* list =
981 (< <int|string>* >*)ERRORD->QueryIssueList(type,uid);
982 count += sizeof(list);
983
984 if (!member(issuelist, type))
985 issuelist += ([ type: ([ uid: list ]) ]);
986 else if (!member(issuelist[type], uid))
987 issuelist[type] += ([uid: list ]);
988 }
989 }
990 }
991 return count;
992}
993