blob: 5bb76f1e806a238295f6b582ac6b09d6f27d030f [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
Zesstra6b5ac892019-11-26 21:28:16 +01008//#pragma pedantic
MG Mud User88f12472016-06-24 23:31:02 +02009#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 **************
Bugfix86a40cb2022-09-22 13:34:51 +020051private varargs int update_issuelist(int lmodus);
MG Mud User88f12472016-06-24 23:31:02 +020052private void get_uids();
Bugfix74112842019-05-28 19:06:33 +020053private struct fullissue_s get_issue(string arg);
54private struct fullissue_s|struct fullissue_s* get_issues(string arg);
MG Mud User88f12472016-06-24 23:31:02 +020055
56// irgendeinen Fehler oder Warnung anzeigen.
57private int show_entry(struct fullissue_s issue)
58{
59 if (!issue) return 0;
60
bugfixd94d0932020-04-08 11:27:13 +020061 string txt=({string})ERRORD->format_error(issue, 0);
MG Mud User88f12472016-06-24 23:31:02 +020062
63 if (!stringp(txt) || !sizeof(txt))
64 return 0;
65
66 tell_object(PL,txt+"\n");
67 return 1;
68}
69
70protected int _feingabe_fertig(string arg) {
71
72 if (arg == "j")
73 {
74 if (!feingabe[F_MSG])
75 {
76 tell_object(PL,
77 "Also, eine Fehlerbeschreibung solltest Du schon eingeben! Abgebrochen.\n");
78 }
79 else
80 {
Vaniondb7851b2020-03-10 21:52:34 +010081 string hashkey = ({string})ERRORD->LogReportedError(feingabe);
MG Mud User88f12472016-06-24 23:31:02 +020082 tell_object(PL, sprintf(
83 "Vielen Dank! Die ID des eingegebenen Fehlers lautet: %s\n",
84 hashkey || "N/A"));
85 }
86 }
87 else
88 {
89 tell_object(PL, "Fehlereingabe abgebrochen.\n");
90 }
91
92 feingabe = 0;
93
94 return 1;
95}
96
97public int CmdFehlerEingabe(string arg) {
Arathorn2e77c0a2016-08-27 14:37:47 +020098 object|string target;
MG Mud User88f12472016-06-24 23:31:02 +020099
100 if (feingabe)
101 {
Arathorn2e77c0a2016-08-27 14:37:47 +0200102 tell_object(PL, "Du gibst doch bereits einen Fehler ein!\n");
MG Mud User88f12472016-06-24 23:31:02 +0200103 return 1;
104 }
105 feingabe = ([]);
106
107 if (arg)
108 {
109 target = present(arg);
110 if (!target)
111 target = find_object(arg); // vielleicht direkt angegeben?
Arathorn2e77c0a2016-08-27 14:37:47 +0200112 // Vielleicht gibt es ja eine Datei, die so heisst?
113 if (!target && file_size(arg) >= 0)
114 target = arg;
MG Mud User88f12472016-06-24 23:31:02 +0200115 }
116 // wenn nix gefunden, Environment des Magiers nehmen.
117 if (!target)
Arathorn2e77c0a2016-08-27 14:37:47 +0200118 {
119 tell_object(PL, break_string("Kein Objekt und keine Datei "
120 "angegeben, Fehler wird fuer den Raum eingetragen.",78));
MG Mud User88f12472016-06-24 23:31:02 +0200121 target = environment(environment());
Arathorn2e77c0a2016-08-27 14:37:47 +0200122 }
MG Mud User88f12472016-06-24 23:31:02 +0200123
124 feingabe[F_OBJ] = target;
125
126 tell_object(PL, break_string(sprintf(
127 "Du beginnst einen Fehlereintrag fuer das Objekt: %O\n", target),78));
128
129 input_to(function void (string str)
130 {
131 if (sizeof(str)) feingabe[F_MSG] = str;
132 }, INPUT_PROMPT, "Fehlerbeschreibung eingeben:\n");
133
134 input_to(function void (string str)
135 {
136 if (sizeof(str)) feingabe[F_PROG] = str;
137 else feingabe[F_PROG] = "unbekannt";
138 }, INPUT_PROMPT|INPUT_APPEND,
139 "Programm eingeben, in dem der Fehler auftritt (falls bekannt):\n");
140
141 input_to(function void (string str)
142 {
143 if (sizeof(str)) feingabe[F_LINE] = to_int(str);
144 tell_object(PL,break_string(sprintf(
145 "Du hast die folgenden Daten eingegeben:\n"
146 "Objekt: %O\n"
147 "Fehlerbeschreibung: %s\n"
148 "Programm: %s\n"
149 "Zeilennr.: %d\n",
150 feingabe[F_OBJ], feingabe[F_MSG] || "", feingabe[F_PROG],
151 feingabe[F_LINE]), 78, "", BS_LEAVE_MY_LFS));
152 }, INPUT_PROMPT|INPUT_APPEND,
153 "Zeilennr. eingeben, in der der Fehler auftritt (falls bekannt):\n");
154
155 input_to(#'_feingabe_fertig,
156 INPUT_PROMPT|INPUT_APPEND, "Eingaben korrekt? (j/n)\n");
157
158 return 1;
159}
160
161public int CmdFehlerZeigen(string arg)
162{
Bugfix74112842019-05-28 19:06:33 +0200163 struct fullissue_s|struct fullissue_s* issues=get_issues(arg);
MG Mud User88f12472016-06-24 23:31:02 +0200164 notify_fail("Einen Eintrag mit dieser ID gibt es nicht!\n");
165
Bugfix74112842019-05-28 19:06:33 +0200166 if (structp(issues))
MG Mud User88f12472016-06-24 23:31:02 +0200167 {
Bugfix74112842019-05-28 19:06:33 +0200168 show_entry(issues);
MG Mud User88f12472016-06-24 23:31:02 +0200169 // letzten Fehler merken.
Bugfix74112842019-05-28 19:06:33 +0200170 lfehler = issues->id;
MG Mud User88f12472016-06-24 23:31:02 +0200171 return 1;
172 }
MG Mud User88f12472016-06-24 23:31:02 +0200173 else if (pointerp(issues))
174 {
Bugfix74112842019-05-28 19:06:33 +0200175 foreach(struct fullissue_s issue : issues)
MG Mud User88f12472016-06-24 23:31:02 +0200176 {
177 show_entry(issue);
178 }
179 return 1;
180 }
181
182 notify_fail("Keine Eintraege fuer diesen Dateinamen/diese ID gefunden.\n");
183 return 0;
184}
185
186// Loescht alle Fehler und Warnungen eines Objekts (soweit per modus
187// ausgewaehlt). Entscheidend ist der _Loadname_!
Bugfix85764d72021-08-24 10:15:59 +0200188private int DeleteErrorsForLoadname(string loadname, string note)
MG Mud User88f12472016-06-24 23:31:02 +0200189{
190 int sum_deleted;
191 // Bei == 0 wird sonst alles geloescht. ;-)
192 if (!loadname)
193 return 0;
194
195 foreach(int m: ALL_ERR_TYPES)
196 {
197 if (!(m & modus))
198 continue;
bugfixd94d0932020-04-08 11:27:13 +0200199 < <int|string>* >* list = ({< <int|string>* >*})ERRORD->QueryIssueListByLoadname(loadname,m);
MG Mud User88f12472016-06-24 23:31:02 +0200200 if (pointerp(list))
201 {
202 foreach(<int|string>* row : list)
203 {
Bugfix85764d72021-08-24 10:15:59 +0200204 if (({int})ERRORD->ToggleDeleteError(row[0], note) == 1)
MG Mud User88f12472016-06-24 23:31:02 +0200205 {
206 tell_object(PL,
207 row[0] + " als geloescht markiert.\n");
208 }
209 }
210 sum_deleted+=sizeof(list);
211 }
212 }
213 return sum_deleted;
214}
215
216public int CmdFehlerLoeschen(string arg)
217{
218 int issueid;
Bugfix1fab1332021-09-06 12:22:20 +0200219 string note;
Vaniondb7851b2020-03-10 21:52:34 +0100220 arg = ({string})this_player()->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200221
222 if (stringp(arg) && sizeof(arg))
Bugfix1fab1332021-09-06 12:22:20 +0200223 {
MG Mud User88f12472016-06-24 23:31:02 +0200224 issueid = to_int(arg);
Bugfix1fab1332021-09-06 12:22:20 +0200225 // Fuehrende Leerzeichen entfernen, um ID und Notiz zuverlaessig trennen zu
226 // koennen.
227 arg = trim(arg, TRIM_LEFT);
228 // Alles ab dem zweiten Wort sollte eine Notiz sein.
229 int spacepos = strstr(arg, " ");
230 if(spacepos != -1)
231 {
232 note = arg[spacepos + 1 ..];
233 arg = arg[.. spacepos - 1];
234 }
235 }
MG Mud User88f12472016-06-24 23:31:02 +0200236 else
237 issueid = lfehler;
238
239 notify_fail("Einen Eintrag mit dieser ID/diesem Loadname gibt es nicht!\n");
240
Bugfix85764d72021-08-24 10:15:59 +0200241 int res = ({int})ERRORD->ToggleDeleteError(issueid, note);
MG Mud User88f12472016-06-24 23:31:02 +0200242 if (res == 1)
243 {
244 tell_object(PL,
245 "Fehler/Warnung wurde zum Loeschen markiert und wird in Kuerze "
246 "geloescht.\n");
247 lfehler = issueid;
248 return 1;
249 }
250 else if (res==0)
251 {
252 tell_object(PL,"Loeschmarkierung wurde entfernt.\n");
253 lfehler = issueid;
254 return 1;
255 }
256 else if (res < -1)
257 {
258 tell_object(PL, "Irgendwas ist beim Loeschen schiefgegangen. "
259 "Keine Schreibrechte?\n");
260 lfehler = issueid;
261 return 1;
262 }
263 // res war == -1 -> Fehler nicht gefunden. Vielleicht ist es nen Loadname
Bugfix85764d72021-08-24 10:15:59 +0200264 return DeleteErrorsForLoadname(arg, note);
MG Mud User88f12472016-06-24 23:31:02 +0200265}
266
267public int CmdRefresh(string arg) {
268 reset();
269 tell_object(PL,"Fehlerdaten wurden neu eingelesen.\n");
270 return 1;
271}
272
Bugfix67091cb2022-09-22 15:57:31 +0200273#define NO_FALLBACK 1
274#define NO_COMBINED_TYPES 2
275private int select_modus(string arg, int flags = 0) {
MG Mud User88f12472016-06-24 23:31:02 +0200276 int lmodus;
277 switch(arg) {
278 case "alles":
279 case "alle":
Bugfix67091cb2022-09-22 15:57:31 +0200280 if(flags & NO_COMBINED_TYPES)
281 {
282 lmodus = 0;
283 }
284 else
285 {
286 lmodus = T_RTERROR | T_RTWARN | T_CTERROR | T_CTWARN | T_REPORTED_ERR
287 | T_REPORTED_IDEA | T_REPORTED_TYPO | T_REPORTED_MD |
288 T_REPORTED_SYNTAX;
289 }
MG Mud User88f12472016-06-24 23:31:02 +0200290 break;
291 case "fehler":
292 case "error":
293 case "errors":
Bugfix67091cb2022-09-22 15:57:31 +0200294 if(flags & NO_COMBINED_TYPES)
295 {
296 lmodus = 0;
297 }
298 else
299 {
300 lmodus=T_RTERROR | T_CTERROR | T_REPORTED_ERR;
301 }
MG Mud User88f12472016-06-24 23:31:02 +0200302 break;
303 case "warnungen":
304 case "warnung":
305 case "warning":
306 case "warnings":
Bugfix67091cb2022-09-22 15:57:31 +0200307 if(flags & NO_COMBINED_TYPES)
308 {
309 lmodus = 0;
310 }
311 else
312 {
313 lmodus=T_RTWARN | T_CTWARN;
314 }
MG Mud User88f12472016-06-24 23:31:02 +0200315 break;
316 case "laufzeitfehler":
317 lmodus=T_RTERROR;
318 break;
319 case "ladezeitfehler":
320 lmodus=T_CTERROR;
321 break;
322 case "fehlerhinweis":
323 case "fehlerhinweise":
324 case "hinweise":
325 lmodus=T_REPORTED_ERR;
326 break;
327 case "ideen":
328 case "idee":
329 lmodus=T_REPORTED_IDEA;
330 break;
331 case "md":
332 lmodus=T_REPORTED_MD;
333 break;
334 case "typo":
335 case "typos":
336 lmodus=T_REPORTED_TYPO;
337 break;
Bugfixa75344d2017-06-16 14:04:48 +0200338 case "syntax":
339 case "syntaxhinweis":
340 case "syntaxhinweise":
341 lmodus=T_REPORTED_SYNTAX;
342 break;
MG Mud User88f12472016-06-24 23:31:02 +0200343 case "laufzeitwarnungen":
344 case "runtimewarnings":
345 lmodus=T_RTWARN;
346 break;
347 case "ladezeitwarnungen":
348 case "compiletimewarnings":
349 lmodus=T_CTWARN;
350 break;
351 default:
Bugfix67091cb2022-09-22 15:57:31 +0200352 if(flags & NO_FALLBACK)
353 {
354 lmodus = 0;
355 }
356 else
357 {
358 lmodus=modus;
359 }
MG Mud User88f12472016-06-24 23:31:02 +0200360 }
361 return lmodus;
362}
363
364private string * errorlabel(int t)
365{
366 switch(t) {
367 case T_RTERROR:
368 return ({"Laufzeitfehler","Laufzeitfehler","Dieser Laufzeitfehler"});
369 case T_REPORTED_ERR:
370 return ({"Fehlerhinweis","Fehlerhinweise","Dieser Fehlerhinweis"});
371 case T_REPORTED_IDEA:
372 return ({"Idee","Ideen","Diese Idee"});
373 case T_REPORTED_MD:
374 return ({"fehlende Detail","fehlende Details","Dieses fehlende Detail"});
375 case T_REPORTED_TYPO:
376 return ({"Typo","Typos","Dieser Typo"});
Bugfixa75344d2017-06-16 14:04:48 +0200377 case T_REPORTED_SYNTAX:
378 return ({"Syntaxhinweis","Syntaxhinweise","Dieser Syntaxhinweis"});
MG Mud User88f12472016-06-24 23:31:02 +0200379 case T_RTWARN:
380 return ({"Laufzeitwarnung","Laufzeitwarnungen","Diese Laufzeitwarnung"});
381 case T_CTWARN:
382 return ({"Ladezeitwarnung", "Ladezeitwarnungen","Diese Ladezeitwarnung"});
383 case T_CTERROR:
384 return ({"Ladezeitfehler","Ladezeitfehler","Dieser Ladezeitfehler"});
385 }
386 raise_error("Unkannter Fehlertyp: "+t+"\n");
MG Mud User88f12472016-06-24 23:31:02 +0200387}
388
389public int CmdFehlerListe(string arg) {
390 string txt;
391 //string *luids;
392 int lmodus; // modus fuer diese Liste
393 mapping fehlerbackup;
394
395 if (stringp(arg) && sizeof(arg))
396 {
397 lmodus=select_modus(arg);
398 if (lmodus != modus)
399 {
400 fehlerbackup=issuelist; // Fehlerliste von 'modus' aufheben
Bugfix86a40cb2022-09-22 13:34:51 +0200401 update_issuelist(lmodus); // neue Fehlerliste holen
MG Mud User88f12472016-06-24 23:31:02 +0200402 }
403 }
404 else
405 lmodus=modus;
406/*
407 if (!fehlerzahl)
408 {
409 txt="Fuer Deine UIDs sind keine Fehler/Warnungen bekannt. :-)\n";
410 tell_object(PL,txt);
411 return 1;
412 }
413*/
414 foreach(int typ, mapping typemap : issuelist)
415 {
416 if (!(typ & lmodus))
417 continue; // Type nicht gewaehlt.
418 txt="";
419 if (!sizeof(typemap)) {
420 tell_object(PL,
421 "Es sind keine " + errorlabel(typ)[1] + "Deiner UIDs bekannt. :-)");
422 continue;
423 }
424 foreach(string uid, < <int|string>* >* list : typemap)
425 {
426 if (!sizeof(list)) continue;
427 if (filterstatus && member(filteruids, uid) > -1) continue;
428 //txt+=sprintf("%s:\n", uid);
429 foreach(<int|string>* row : list)
430 {
431 txt+=sprintf("%:6d | %:40-s | %:26-s\n",
432 row[0], row[1], row[2]);
433 }
434 }
435 if (txt && sizeof(txt))
436 {
437 txt = sprintf("\nFuer Deine UIDs sind folgende %s bekannt (Filter: %s):\n"
438 "%:6|s | %:40|s | %s\n",
439 errorlabel(typ)[1], (filterstatus ? "an" : "aus"),
440 "ID", "Loadname", "UID")
441 + txt;
442 tell_object(PL, txt);
443 }
444 else
445 {
446 tell_object(PL, sprintf(
447 "\nFuer Deine UIDs sind keine %s bekannt (Filter: %s):\n",
448 errorlabel(typ)[1], (filterstatus ? "an" : "aus")));
449 }
450 }
451
452 if (mappingp(fehlerbackup) && modus!=lmodus)
453 issuelist=fehlerbackup; // fehlerliste fuer 'modus' restaurieren
454 return 1;
455}
456
457public int CmdFilter(string arg) {
458
Vaniondb7851b2020-03-10 21:52:34 +0100459 arg=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200460
461 if (!stringp(arg) || !sizeof(arg)) {
462 tell_object(PL,break_string(
463 "Momentan interessieren Dich folgende UIDs nicht"
464 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
465 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
466 return 1;
467 }
468
469 if (arg=="keine") {
470 filteruids=({});
471 filterstatus=1;
472 tell_object(PL,break_string(
473 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
474 "Fehler berichten. Momentan hast Du keine UIDs ausgeblendet. "
475 "(Filter an)",78));
476 }
477 else if (arg=="alle") {
478 filterstatus=1;
479 filteruids=uids;
480 tell_object(PL,break_string(
481 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
482 "Fehler berichten. Du blendest momentan alle UIDs aus. "
483 "(Filter an)",78));
484 }
485 else if (arg=="aus") {
486 filterstatus=0;
487 tell_object(PL,break_string(
488 "Dein Fehlerteufel wird Dir nun wieder alle Fehler berichten. ",
489 78));
490 }
491 else if (arg=="an" || arg=="ein") {
492 filterstatus=1;
493 tell_object(PL,break_string(
494 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
495 "Fehler berichten.",78));
496 }
497 else {
498 foreach(string uid: explode(arg," ")-({""})) {
499 if (sizeof(uid)>1 && uid[0]=='+') {
500 if (member(filteruids,uid[1..])==-1)
501 filteruids+=({uid[1..]});
502 }
503 else if (sizeof(uid)>1 && uid[0]=='-') {
504 filteruids-=({uid[1..]});
505 }
506 else {
507 if (member(filteruids,uid)==-1)
508 filteruids+=({uid});
509 else
510 filteruids-=({uid});
511 }
512 }
513 }
514
515 tell_object(PL,break_string(
516 "Momentan interessieren Dich folgende UIDs nicht"
517 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
518 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
519
520 return 1;
521}
522
523public int CmdMonitor(string arg) {
524
Vaniondb7851b2020-03-10 21:52:34 +0100525 arg=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200526
527 if (!stringp(arg) || !sizeof(arg)) {
528 tell_object(PL,break_string(
529 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
530 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
531 +"\n", 78,"",BS_LEAVE_MY_LFS));
532 return 1;
533 }
534
535 if (arg=="keine") {
536 monitoruids=({});
537 xmonitoruids=({});
538 tell_object(PL,break_string(
539 "Dein Fehlerteufel wird Dir nun nur noch "
540 "Fehler Deiner eigenen UIDs berichten.",78));
541 return 1;
542 }
543 else {
544 foreach(string uid: explode(arg," ")-({""})) {
545 if (sizeof(uid)>1 && uid[0]=='+') {
546 if (member(monitoruids,uid[1..])==-1)
547 monitoruids+=({uid[1..]});
548 }
549 else if (sizeof(uid)>1 && uid[0]=='-') {
550 monitoruids-=({uid[1..]});
551 }
552 else {
553 if (member(monitoruids,uid)==-1)
554 monitoruids+=({uid});
555 else
556 monitoruids-=({uid});
557 }
558 }
559 }
560 get_uids();
561 tell_object(PL,break_string(
562 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
563 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
564 +"\n", 78,"",BS_LEAVE_MY_LFS));
565
566 return 1;
567}
568
569public int CmdModus(string arg) {
MG Mud User88f12472016-06-24 23:31:02 +0200570 // Argument verwursten
571 if (stringp(arg) && sizeof(arg)) {
572 modus = select_modus(arg);
573 reset(); // neue Fehlerliste holen
574 }
575 // aktuelle Einstellung ausgeben.
576 string *modstr=({});
577 if (modus & T_RTERROR)
578 modstr+=({"Fehler (Laufzeit)"});
579 if (modus & T_RTWARN)
580 modstr+=({"Warnungen (Laufzeit)"});
581 if (modus & T_CTERROR)
582 modstr+=({"Fehler (Ladezeit)"});
583 if (modus & T_CTWARN)
584 modstr+=({"Warnungen (Ladezeit)"});
585 if (modus & T_REPORTED_ERR)
586 modstr+=({"Fehlerhinweise"});
587 if (modus & T_REPORTED_IDEA)
588 modstr+=({"Idee"});
589 if (modus & T_REPORTED_MD)
590 modstr+=({"fehlende Details"});
591 if (modus & T_REPORTED_TYPO)
592 modstr+=({"Typo"});
Bugfixa75344d2017-06-16 14:04:48 +0200593 if(modus&T_REPORTED_SYNTAX)
594 modstr+=({"Syntaxhinweise"});
MG Mud User88f12472016-06-24 23:31:02 +0200595
596 tell_object(PL, break_string(
597 "Dein Fehlerteufel wird Dir nun ueber aufgetretene "
598 +CountUp(modstr)+" Bericht erstatten.",78));
599 return(1);
600}
601
602int CmdAddNote(string str) {
603 string *arr;
604
605 notify_fail("Bitte eine ID und einen Text angeben!\n");
606 if(!objectp(TI))
607 return 0;
608
Vaniondb7851b2020-03-10 21:52:34 +0100609 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200610 if (!stringp(str) || !sizeof(str))
611 return 0;
612
613 arr=explode(str," ")-({""});
614 if (sizeof(arr)<2)
615 return 0;
616 int issueid = to_int(arr[0]);
617
618 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne ID
619
Vaniondb7851b2020-03-10 21:52:34 +0100620 switch(({int})ERRORD->AddNote(issueid,str))
MG Mud User88f12472016-06-24 23:31:02 +0200621 {
622 case -1:
623 tell_object(PL,
624 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
625 return 1;
626 case -3:
627 return 0; //offenbar keine Notiz angegeben.
628 }
629 // letzten Fehler merken.
630 lfehler = issueid;
631
632 tell_object(PL,
633 sprintf("Deine Notiz wurde zu %d hinzugefuegt.\n",
634 issueid));
635 return 1;
636}
637
638int CmdFix(string str)
639{
640 string *arr;
641 int fixing, res;
642
643 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
644 if(!objectp(TI))
645 return 0;
646
Vaniondb7851b2020-03-10 21:52:34 +0100647 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200648 if (!stringp(str) || !sizeof(str))
649 return 0;
650
651 arr=explode(str," ")-({""});
652 if (!sizeof(arr))
653 return 0;
654
655 int issueid=to_int(arr[0]);
656 if (sizeof(arr)>1)
657 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
658 else str=0;
659
660 if (query_verb()=="ffix" || query_verb()=="fehlerfix")
661 {
662 fixing=1;
Vaniondb7851b2020-03-10 21:52:34 +0100663 res = ({int})ERRORD->ResolveIssue(issueid, str);
MG Mud User88f12472016-06-24 23:31:02 +0200664 }
665 else
666 {
Vaniondb7851b2020-03-10 21:52:34 +0100667 res = ({int})ERRORD->ReOpenIssue(issueid, str);
MG Mud User88f12472016-06-24 23:31:02 +0200668 }
669
670 if (res==-1)
671 {
672 tell_object(PL,
673 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
674 }
675 else if (res==-10)
676 {
677 tell_object(PL,
678 "Du hast leider keinen Schreibzugriff diesen Fehler.\n"
679 "Aber vielleicht moechtest Du mit fnotiz eine Notiz anhaengen?\n");
680 }
681 else if (res==-3)
682 {
683 if (fixing)
684 tell_object(PL,"Dieser Fehler ist bereits gefixt.\n");
685 else
686 tell_object(PL,"Dieser Fehler ist noch nicht gefixt.\n");
687 }
688 else if (res==1)
689 {
690 tell_object(PL,
691 sprintf("Fehler %d als gefixt markiert.\n",issueid));
692 }
693 else if (res==0)
694 {
695 tell_object(PL,
696 sprintf("Fehler %d als nicht gefixt markiert.\n",issueid));
697 }
698 // letzten Fehler merken.
699 lfehler = issueid;
700
701 return 1;
702}
703
704int CmdLock(string str) {
705 string *arr;
706 int locking;
707 int res;
708
709 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
710 if(!objectp(TI))
711 return 0;
712
Vaniondb7851b2020-03-10 21:52:34 +0100713 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200714 if (!stringp(str) || !sizeof(str))
715 return 0;
716
717 arr=explode(str," ")-({""});
718 if (!sizeof(arr))
719 return 0;
720
721 int issueid=to_int(arr[0]);
722 if (sizeof(arr)>1)
723 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
724 else str=0;
725
726 if (query_verb()=="flock" || query_verb()=="fehlerlock")
727 {
728 locking=1;
Vaniondb7851b2020-03-10 21:52:34 +0100729 res=({int})ERRORD->LockIssue(issueid,str);
MG Mud User88f12472016-06-24 23:31:02 +0200730 }
731 else
732 {
Vaniondb7851b2020-03-10 21:52:34 +0100733 res=({int})ERRORD->UnlockIssue(issueid,str);
MG Mud User88f12472016-06-24 23:31:02 +0200734 }
735
736 if (res==-1)
737 {
738 tell_object(PL,
739 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
740 }
741 else if (res==-10)
742 {
743 tell_object(PL,
744 "Du hast leider keinen Schreibzugriff diesen Fehler.\n");
745 }
746 else if (res==-3)
747 {
748 if (locking)
749 tell_object(PL,
750 "Dieser Fehler ist bereits vor autom. Loeschen geschuetzt.\n");
751 else
752 tell_object(PL,
753 "Dieser Fehler ist bereits zum autom. Loeschen freigegeben.\n");
754 }
755 else if (res==-2)
756 {
757 tell_object(PL,
758 "Dieser Fehler ist bereits gefixt und wird bald geloescht.\n");
759 }
760 else if (res==1)
761 {
762 tell_object(PL,
763 sprintf("Fehler %d vor autom. Loeschen geschuetzt.\n",issueid));
764 }
765 else if (res==0)
766 {
767 tell_object(PL,
768 sprintf("Fehler %d zum autom. Loeschen freigegeben.\n",issueid));
769 }
770 // letzten Fehler merken.
771 lfehler = issueid;
772
773 return 1;
774}
775
776int CmdReassign(string str) {
777
778 notify_fail("Bitte eine ID, die neue UID und ggf. eine Notiz angeben!\n");
779 if(!objectp(TI))
780 return 0;
781
Vaniondb7851b2020-03-10 21:52:34 +0100782 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200783 if (!stringp(str) || !sizeof(str))
784 return 0;
785
786 string *arr=explode(str," ")-({""});
787 if (sizeof(arr)<2)
788 return 0;
789 int issueid=to_int(arr[0]);
790 string newuid=arr[1];
791
792 //text wiederherstellen, aber ohne Key und UID
793 if (sizeof(arr) > 2)
794 str = implode(arr[2..]," ");
795 else
796 str = 0;
797
Vaniondb7851b2020-03-10 21:52:34 +0100798 switch(({int})ERRORD->ReassignIssue(issueid, newuid, str))
MG Mud User88f12472016-06-24 23:31:02 +0200799 {
800 case -1:
801 tell_object(PL,
802 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
803 return(1);
804 case -10:
805 tell_object(PL,
806 sprintf("Du hast keine Schreibrechte auf Fehler %d\n",issueid));
807 return 1;
808 case -2:
809 return(0); //offenbar keine neue uid angegeben. (kann nicht)
810 case -3:
811 tell_object(PL,break_string(
812 "Alte == Neue UID ist irgendwie unsinnig...",78));
813 return 1;
814 }
815 // letzten Fehler merken.
816 lfehler = issueid;
817
818 tell_object(PL,break_string(
819 sprintf("Der Fehler der ID %d wurde an die UID %s "
820 "uebertragen.\n", issueid, newuid),78));
821 return 1;
822}
823
Bugfix994aef02019-05-28 19:58:21 +0200824int CmdFehlerDirectory(string arg)
825{
826 struct fullissue_s issue=get_issue(arg);
827 if(!structp(issue))
828 {
829 PL->ReceiveMsg(
830 "Kein Eintrag mit dieser ID gefunden.",
831 MT_NOTIFICATION);
832 }
833 else
834 {
835 string path=issue->loadname||issue->obj;
836 if(!stringp(path) || !sizeof(path))
837 {
838 PL->ReceiveMsg(
839 "Kein Pfad zu dieser ID verfuegbar.",
840 MT_NOTIFICATION);
841 }
842 else
843 {
844 path=implode(explode(path,"/")[..<2],"/");
845 PL->SetProp(P_CURRENTDIR,path);
846 PL->ReceiveMsg(
847 "Aktuelles Verzeichnis ist jetzt: "+path,
848 MT_NOTIFICATION);
849 }
850 }
851 return 1;
852 }
853
Bugfix67091cb2022-09-22 15:57:31 +0200854public int CmdFehlerAendere(string arg)
855{
856 string note;
857 arg = ({string})PL->_unparsed_args(0);
858
859 notify_fail("Bitte ID, Typ und optional einen Kommentar angeben.\n");
860
861 if(!sizeof(arg)) return 0;
862 // Fuehrende Leerzeichen entfernen, um ID, Typ und Notiz zuverlaessig
863 // trennen zu koennen.
864 arg = trim(arg, TRIM_LEFT);
865 string* words = explode(arg, " ");
866 if(sizeof(words) < 2) return 0;
867 arg = words[0];
868 // Alles ab dem dritten Wort sollte eine Notiz sein.
869 if(sizeof(words) > 2)
870 {
871 note = implode(words[2..], " ");
872 }
873
874 struct fullissue_s issue = get_issue(arg);
875
876 if(!structp(issue))
877 {
878 notify_fail("Kein Fehler mit dieser ID gefunden.\n");
879 return 0;
880 }
881
882 int type = select_modus(words[1], NO_FALLBACK | NO_COMBINED_TYPES);
883 if(!type)
884 {
885 notify_fail("Fehlertyp nicht bekannt.\n");
886 return 0;
887 }
888
889 if(!(type in CHANGEABLE_TYPES) || !(issue->type in CHANGEABLE_TYPES))
890 {
891 ({int})PL->ReceiveMsg(
892 "Fehlertyp nicht aenderbar.\n",
893 MT_NOTIFICATION);
894 return 1;
895 }
896
897 if(({int})ERRORD->ChangeType(issue->id, type, issue->type, note) == 1)
898 {
899 string* type_name = ({string*})ERRORD->print_type(type);
900 ({int})PL->ReceiveMsg(
901 "Fehlertyp von " + issue->id + " auf " + type_name[0] + " geaendert.",
902 MT_NOTIFICATION);
903 }
904 else
905 {
906 ({int})PL->ReceiveMsg(
907 "Aendern nicht moeglich. Keine Schreibrechte?",
908 MT_NOTIFICATION);
909 }
910 return 1;
911}
912
MG Mud User88f12472016-06-24 23:31:02 +0200913// ************** public 'internal' functions **************
914public string QueryOwner() {return owner;}
915public mixed QueryIssueList() {return issuelist;}
916
Zesstraff356512018-08-27 20:20:36 +0200917protected void create() {
MG Mud User88f12472016-06-24 23:31:02 +0200918 if (!clonep(ME))
919 return;
920 ::create();
921
922 SetProp(P_SHORT,"Der Fehlerteufel");
923 SetProp(P_LONG,break_string(
924 "Dein Fehlerteufel soll Dir helfen, Informationen "
925 "ueber aufgetretene Fehler zu erhalten. Hierzu fragt er die "
926 "in \"Deinen\" UIDs aufgetretenen Fehler und deren Details vom "
927 "Fehlerspeicher der Mudlib ab. Folgende Kommandos kennt er:",78)
928 +"fehlerabfrage <id> - Fragt Details ueber Fehler mit der ID ab.\n"
929 "fehlerloeschen <id> - Fehler zum Loeschen markieren.\n"
930 "fehlerliste - Fehlerliste der eigenen UIDs anzeigen\n"
931 "fehlerrefresh - Fehlerdaten und UIDs neu einlesen\n"
932 "fehlerfilter - UIDs fuer den Filter angeben (s. manpage!)\n"
933 "fehlermodus - Fehler oder Warnungen ausgeben? (s. manpage)\n"
934 "fehlermonitor - zus. UIDs beobachten (s. manpage)\n"
935 "fnotiz <id> <note> - eine Notiz anhaengen\n"
936 "flock <id> <note> - Fehler vor autom. Loeschen schuetzen\n"
937 "funlock <id> <note> - Fehler zum autom. Loeschen freigeben\n"
938 "ffix <id> <note> - Fehler als gefixt kennzeichnen\n"
939 "funfix <id> <note> - gefixten Fehler als nicht-gefixt markieren\n"
Bugfix994aef02019-05-28 19:58:21 +0200940 "fdir <id> - in das Verzeichnis des fehlerhaften Objekts "
941 "wechseln\n"
MG Mud User88f12472016-06-24 23:31:02 +0200942 "fuebertrage <id> <newuid> <note>\n"
943 " - Fehler an die UID uebertragen\n"
Bugfix67091cb2022-09-22 15:57:31 +0200944 "faendere <id> <newtype> <note>\n"
945 " - Fehlertyp aendern\n"
MG Mud User88f12472016-06-24 23:31:02 +0200946 );
947 SetProp(P_NAME,"Fehlerteufel");
948 SetProp(P_GENDER,MALE);
949 SetProp(P_WEIGHT,0);
950 SetProp(P_VALUE,0);
951 SetProp(P_SIZE,10);
952 SetProp(P_NODROP,"Den Fehlerteufel behaelst Du lieber bei Dir.\n");
953 SetProp(P_NEVERDROP,1);
954
955 AddId( ({"fehlerteufel","teufel"}) );
956
957 AddCmd(({"fehlerabfrage","fabfrage"}), "CmdFehlerZeigen" );
958 AddCmd(({"fehlerloeschen","floeschen"}), "CmdFehlerLoeschen");
959 AddCmd(({"fehlerliste","fliste", "fehleruebersicht","fuebersicht"}),
960 "CmdFehlerListe");
961 AddCmd(({"fehlerrefresh","frefresh"}),"CmdRefresh");
962 AddCmd(({"fehlerfilter","ffilter"}),"CmdFilter");
963 AddCmd(({"fehlermodus","fmodus"}),"CmdModus");
964 AddCmd(({"fehlermonitor","fmonitor"}),"CmdMonitor");
965 AddCmd(({"fehlernotiz","fnotiz"}),"CmdAddNote");
966 AddCmd(({"fehlerlock","flock","fehlerunlock","funlock"}),
967 "CmdLock");
968 AddCmd(({"fehlerfix","ffix","fehlerunfix","funfix"}),
969 "CmdFix");
970 AddCmd(({"fehleruebertrage","fuebertrage"}),"CmdReassign");
971 AddCmd(({"fehlereingabe", "feingabe"}), "CmdFehlerEingabe");
Bugfix994aef02019-05-28 19:58:21 +0200972 AddCmd(({"fehlerdir","fdir"}),"CmdFehlerDirectory");
Bugfix67091cb2022-09-22 15:57:31 +0200973 AddCmd(({"fehleraendere", "faendere"}), "CmdFehlerAendere");
MG Mud User88f12472016-06-24 23:31:02 +0200974}
975
Zesstraff356512018-08-27 20:20:36 +0200976public varargs void init(object origin)
MG Mud User88f12472016-06-24 23:31:02 +0200977{
978 if (find_call_out("remove") != -1) return;
979
980 // pruefung auf env nicht noetig, move geht nur in ein env und ohne env
981 // auch kein init().
982 if ( !query_once_interactive(environment()) ||
983 !IS_LEARNER(environment())) {
984 // in interactive, aber kein magier -> direkt weg.
985 call_out("remove",0,1);
986 return;
987 }
988 else if (!sizeof(owner))
989 // Env ist Interactiv und Magier (sonst waer man oben rausgeflogen)
990 owner=getuid(environment());
991 else if (owner!=getuid(environment())) {
992 //ok, nicht der Eigentuemer, direkt weg.
993 call_out("remove",0);
994 return;
995 }
996 SetProp(P_EXTRA_LOOK,break_string(
bugfixd94d0932020-04-08 11:27:13 +0200997 "Auf "+({string})environment()->Name(WESSEN)
998 +" Schulter sitzt ein kleiner "
MG Mud User88f12472016-06-24 23:31:02 +0200999 "Fehlerteufel, der "
bugfixd94d0932020-04-08 11:27:13 +02001000 +({string})environment()->QueryPronoun(WEM)
MG Mud User88f12472016-06-24 23:31:02 +02001001 +" immer wieder etwas ins Ohr fluestert.",78));
1002
1003 call_out("reset",1);
1004
1005 ::init();
1006}
1007
1008public mixed Configure(mixed data)
1009{
1010 if (!data)
1011 {
1012 return (["filteruids":filteruids,
1013 "filterstatus":filterstatus,
1014 "modus":modus,
1015 "monitoruids":monitoruids,
1016 "fehlerzahl": fehlerzahl]);
1017 }
1018 else if (mappingp(data))
1019 {
1020 if (member(data,"filteruids") && pointerp(data["filteruids"]))
1021 filteruids=data["filteruids"];
1022 if (member(data,"filterstatus") && intp(data["filterstatus"]))
1023 filterstatus=data["filterstatus"];
1024 if (member(data,"modus") && intp(data["modus"]))
1025 modus=data["modus"];
1026 if (member(data,"monitoruids") && pointerp(data["monitoruids"]))
1027 monitoruids=data["monitoruids"];
1028 if (member(data,"fehlerzahl") && intp(data["fehlerzahl"]))
1029 fehlerzahl=data["fehlerzahl"];
1030 return 1;
1031 }
1032 return 0;
1033}
1034
1035mapping _query_autoloadobj()
1036{
1037 return Configure(0);
1038}
1039
1040mapping _set_autoloadobj(mixed data)
1041{
1042 Configure(data);
1043 return _query_autoloadobj();
1044}
1045
1046
1047void reset()
1048{
1049 get_uids();
Bugfix86a40cb2022-09-22 13:34:51 +02001050 int neuefehlerzahl=update_issuelist();
MG Mud User88f12472016-06-24 23:31:02 +02001051
1052 if (fehlerzahl < neuefehlerzahl)
1053 tell_object(environment(ME), break_string(
1054 "Deine Fehlerliste ist soeben laenger geworden.",78,
1055 "Dein Fehlerteufel teilt Dir mit: "));
1056 else if (fehlerzahl > neuefehlerzahl)
1057 tell_object(environment(ME), break_string(
1058 "Deine Fehlerliste ist soeben kuerzer geworden.",78,
1059 "Dein Fehlerteufel teilt Dir mit: "));
1060 fehlerzahl = neuefehlerzahl;
1061}
1062
1063// ******** private functions *********************
1064private void get_uids()
1065{
Vaniondb7851b2020-03-10 21:52:34 +01001066 uids=({string *})master()->QueryUIDsForWizard(owner);
MG Mud User88f12472016-06-24 23:31:02 +02001067 xmonitoruids=({});
1068 if (sizeof(monitoruids))
1069 {
1070 closure cl=symbol_function("QueryUIDAlias", master());
1071 foreach(string uid: monitoruids) {
Vaniondb7851b2020-03-10 21:52:34 +01001072 xmonitoruids += ({string*})funcall(cl, uid);
MG Mud User88f12472016-06-24 23:31:02 +02001073 }
1074 }
1075}
1076
1077/* Holt sich aus dem ErrorD die Liste ungeloeschter und ungefixter Fehler fuer
1078 * fuer die UIDs des Magier fuer alle Typen
1079 */
Bugfix86a40cb2022-09-22 13:34:51 +02001080private varargs int update_issuelist(int lmodus)
MG Mud User88f12472016-06-24 23:31:02 +02001081{
1082 int count;
1083
1084 if (!lmodus)
1085 lmodus=modus;
1086
1087 issuelist=m_allocate(sizeof(ALL_ERR_TYPES),1);
1088
1089 foreach(int type: ALL_ERR_TYPES)
1090 {
1091 if (type & lmodus)
1092 {
1093 //DEBUG(sprintf("Type: %d\n",type));
1094 foreach(string uid : uids + xmonitoruids)
1095 {
1096 //DEBUG(sprintf("Type: %d, UID: %s\n",type,uid));
1097 < <int|string>* >* list =
Vaniondb7851b2020-03-10 21:52:34 +01001098 ({< <int|string>* >*})ERRORD->QueryIssueList(type,uid);
MG Mud User88f12472016-06-24 23:31:02 +02001099 count += sizeof(list);
1100
1101 if (!member(issuelist, type))
1102 issuelist += ([ type: ([ uid: list ]) ]);
1103 else if (!member(issuelist[type], uid))
1104 issuelist[type] += ([uid: list ]);
1105 }
1106 }
1107 }
Bugfix74112842019-05-28 19:06:33 +02001108
MG Mud User88f12472016-06-24 23:31:02 +02001109 return count;
1110}
1111
Bugfix74112842019-05-28 19:06:33 +02001112private struct fullissue_s get_issue(string arg)
1113{
1114 int issueid;
1115 struct fullissue_s issue;
1116
1117 if (stringp(arg) && sizeof(arg))
1118 {
1119 arg = trim(arg, TRIM_BOTH);
1120 issueid = to_int(arg);
1121 }
1122 else
1123 {
1124 issueid = lfehler;
1125 arg = to_string(issueid);
1126 }
1127
1128 // Wurde ein Hash uebergeben, ist issueid 0 und arg der Hash.
1129 // Wurde eine ID oder nichts uebergeben, ist issueid die ID als int und
1130 // arg die ID als string.
1131 if (to_string(issueid) == arg)
Vaniondb7851b2020-03-10 21:52:34 +01001132 issue = ({struct fullissue_s})ERRORD->QueryIssueByID(issueid);
Bugfix74112842019-05-28 19:06:33 +02001133 else
Vaniondb7851b2020-03-10 21:52:34 +01001134 issue = ({struct fullissue_s})ERRORD->QueryIssueByHash(arg);
Bugfix74112842019-05-28 19:06:33 +02001135 return issue;
1136}
1137
1138private struct fullissue_s|struct fullissue_s* get_issues(string arg)
1139{
bugfixd94d0932020-04-08 11:27:13 +02001140 arg=({string})PL->_unparsed_args();
Bugfix74112842019-05-28 19:06:33 +02001141 struct fullissue_s|struct fullissue_s* issues;
Bugfixe1949592019-09-16 20:41:54 +02001142
1143 // Erstmal schauen, ob arg eine ID ist.
1144 issues=get_issue(arg);
1145 // Wenn nicht, dann ist es wohl ein Pfad.
1146 if(!structp(issues))
Bugfix74112842019-05-28 19:06:33 +02001147 {
Bugfixe1949592019-09-16 20:41:54 +02001148 // Mit einem / am Anfang ist der Pfad vermutlich komplett, ansonsten
1149 // wird im aktuellen Verzeichnis gesucht.
1150 if(sizeof(arg) && arg[0] != '/')
1151 {
bugfixd94d0932020-04-08 11:27:13 +02001152 arg=({string})PL->QueryProp(P_CURRENTDIR)+"/"+arg;
Bugfixe1949592019-09-16 20:41:54 +02001153 }
Bugfix74112842019-05-28 19:06:33 +02001154 issues=({});
1155 foreach(int m: ALL_ERR_TYPES)
1156 {
1157 if (!(m & modus))
1158 continue;
1159 struct fullissue_s *tmp =
Vaniondb7851b2020-03-10 21:52:34 +01001160 ({struct fullissue_s *})ERRORD->QueryIssuesByFile(arg, m);
Bugfix74112842019-05-28 19:06:33 +02001161 if (tmp)
1162 issues+=tmp;
1163 }
1164 if (!sizeof(issues))
1165 issues=0;
1166 }
Bugfix74112842019-05-28 19:06:33 +02001167
1168 return issues;
1169}