blob: 706c28e8acf001ef511973afe71c3c768d0f7cf6 [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 **************
51private varargs int get_issuelist(int lmodus);
52private 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
273private int select_modus(string arg) {
274 int lmodus;
275 switch(arg) {
276 case "alles":
277 case "alle":
278 lmodus = T_RTERROR | T_RTWARN | T_CTERROR | T_CTWARN | T_REPORTED_ERR
Bugfixa75344d2017-06-16 14:04:48 +0200279 | T_REPORTED_IDEA | T_REPORTED_TYPO | T_REPORTED_MD |
280 T_REPORTED_SYNTAX;
MG Mud User88f12472016-06-24 23:31:02 +0200281 break;
282 case "fehler":
283 case "error":
284 case "errors":
285 lmodus=T_RTERROR | T_CTERROR | T_REPORTED_ERR;
286 break;
287 case "warnungen":
288 case "warnung":
289 case "warning":
290 case "warnings":
291 lmodus=T_RTWARN | T_CTWARN;
292 break;
293 case "laufzeitfehler":
294 lmodus=T_RTERROR;
295 break;
296 case "ladezeitfehler":
297 lmodus=T_CTERROR;
298 break;
299 case "fehlerhinweis":
300 case "fehlerhinweise":
301 case "hinweise":
302 lmodus=T_REPORTED_ERR;
303 break;
304 case "ideen":
305 case "idee":
306 lmodus=T_REPORTED_IDEA;
307 break;
308 case "md":
309 lmodus=T_REPORTED_MD;
310 break;
311 case "typo":
312 case "typos":
313 lmodus=T_REPORTED_TYPO;
314 break;
Bugfixa75344d2017-06-16 14:04:48 +0200315 case "syntax":
316 case "syntaxhinweis":
317 case "syntaxhinweise":
318 lmodus=T_REPORTED_SYNTAX;
319 break;
MG Mud User88f12472016-06-24 23:31:02 +0200320 case "laufzeitwarnungen":
321 case "runtimewarnings":
322 lmodus=T_RTWARN;
323 break;
324 case "ladezeitwarnungen":
325 case "compiletimewarnings":
326 lmodus=T_CTWARN;
327 break;
328 default:
329 lmodus=modus;
330 }
331 return lmodus;
332}
333
334private string * errorlabel(int t)
335{
336 switch(t) {
337 case T_RTERROR:
338 return ({"Laufzeitfehler","Laufzeitfehler","Dieser Laufzeitfehler"});
339 case T_REPORTED_ERR:
340 return ({"Fehlerhinweis","Fehlerhinweise","Dieser Fehlerhinweis"});
341 case T_REPORTED_IDEA:
342 return ({"Idee","Ideen","Diese Idee"});
343 case T_REPORTED_MD:
344 return ({"fehlende Detail","fehlende Details","Dieses fehlende Detail"});
345 case T_REPORTED_TYPO:
346 return ({"Typo","Typos","Dieser Typo"});
Bugfixa75344d2017-06-16 14:04:48 +0200347 case T_REPORTED_SYNTAX:
348 return ({"Syntaxhinweis","Syntaxhinweise","Dieser Syntaxhinweis"});
MG Mud User88f12472016-06-24 23:31:02 +0200349 case T_RTWARN:
350 return ({"Laufzeitwarnung","Laufzeitwarnungen","Diese Laufzeitwarnung"});
351 case T_CTWARN:
352 return ({"Ladezeitwarnung", "Ladezeitwarnungen","Diese Ladezeitwarnung"});
353 case T_CTERROR:
354 return ({"Ladezeitfehler","Ladezeitfehler","Dieser Ladezeitfehler"});
355 }
356 raise_error("Unkannter Fehlertyp: "+t+"\n");
MG Mud User88f12472016-06-24 23:31:02 +0200357}
358
359public int CmdFehlerListe(string arg) {
360 string txt;
361 //string *luids;
362 int lmodus; // modus fuer diese Liste
363 mapping fehlerbackup;
364
365 if (stringp(arg) && sizeof(arg))
366 {
367 lmodus=select_modus(arg);
368 if (lmodus != modus)
369 {
370 fehlerbackup=issuelist; // Fehlerliste von 'modus' aufheben
371 get_issuelist(lmodus); // neue Fehlerliste holen
372 }
373 }
374 else
375 lmodus=modus;
376/*
377 if (!fehlerzahl)
378 {
379 txt="Fuer Deine UIDs sind keine Fehler/Warnungen bekannt. :-)\n";
380 tell_object(PL,txt);
381 return 1;
382 }
383*/
384 foreach(int typ, mapping typemap : issuelist)
385 {
386 if (!(typ & lmodus))
387 continue; // Type nicht gewaehlt.
388 txt="";
389 if (!sizeof(typemap)) {
390 tell_object(PL,
391 "Es sind keine " + errorlabel(typ)[1] + "Deiner UIDs bekannt. :-)");
392 continue;
393 }
394 foreach(string uid, < <int|string>* >* list : typemap)
395 {
396 if (!sizeof(list)) continue;
397 if (filterstatus && member(filteruids, uid) > -1) continue;
398 //txt+=sprintf("%s:\n", uid);
399 foreach(<int|string>* row : list)
400 {
401 txt+=sprintf("%:6d | %:40-s | %:26-s\n",
402 row[0], row[1], row[2]);
403 }
404 }
405 if (txt && sizeof(txt))
406 {
407 txt = sprintf("\nFuer Deine UIDs sind folgende %s bekannt (Filter: %s):\n"
408 "%:6|s | %:40|s | %s\n",
409 errorlabel(typ)[1], (filterstatus ? "an" : "aus"),
410 "ID", "Loadname", "UID")
411 + txt;
412 tell_object(PL, txt);
413 }
414 else
415 {
416 tell_object(PL, sprintf(
417 "\nFuer Deine UIDs sind keine %s bekannt (Filter: %s):\n",
418 errorlabel(typ)[1], (filterstatus ? "an" : "aus")));
419 }
420 }
421
422 if (mappingp(fehlerbackup) && modus!=lmodus)
423 issuelist=fehlerbackup; // fehlerliste fuer 'modus' restaurieren
424 return 1;
425}
426
427public int CmdFilter(string arg) {
428
Vaniondb7851b2020-03-10 21:52:34 +0100429 arg=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200430
431 if (!stringp(arg) || !sizeof(arg)) {
432 tell_object(PL,break_string(
433 "Momentan interessieren Dich folgende UIDs nicht"
434 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
435 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
436 return 1;
437 }
438
439 if (arg=="keine") {
440 filteruids=({});
441 filterstatus=1;
442 tell_object(PL,break_string(
443 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
444 "Fehler berichten. Momentan hast Du keine UIDs ausgeblendet. "
445 "(Filter an)",78));
446 }
447 else if (arg=="alle") {
448 filterstatus=1;
449 filteruids=uids;
450 tell_object(PL,break_string(
451 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
452 "Fehler berichten. Du blendest momentan alle UIDs aus. "
453 "(Filter an)",78));
454 }
455 else if (arg=="aus") {
456 filterstatus=0;
457 tell_object(PL,break_string(
458 "Dein Fehlerteufel wird Dir nun wieder alle Fehler berichten. ",
459 78));
460 }
461 else if (arg=="an" || arg=="ein") {
462 filterstatus=1;
463 tell_object(PL,break_string(
464 "Dein Fehlerteufel wird Dir nun nur noch ausgewaehlte "
465 "Fehler berichten.",78));
466 }
467 else {
468 foreach(string uid: explode(arg," ")-({""})) {
469 if (sizeof(uid)>1 && uid[0]=='+') {
470 if (member(filteruids,uid[1..])==-1)
471 filteruids+=({uid[1..]});
472 }
473 else if (sizeof(uid)>1 && uid[0]=='-') {
474 filteruids-=({uid[1..]});
475 }
476 else {
477 if (member(filteruids,uid)==-1)
478 filteruids+=({uid});
479 else
480 filteruids-=({uid});
481 }
482 }
483 }
484
485 tell_object(PL,break_string(
486 "Momentan interessieren Dich folgende UIDs nicht"
487 +(filterstatus ? " (Filter an):\n" : " (Filter aus):\n")
488 +CountUp(filteruids)+"\n", 78,"",BS_LEAVE_MY_LFS));
489
490 return 1;
491}
492
493public int CmdMonitor(string arg) {
494
Vaniondb7851b2020-03-10 21:52:34 +0100495 arg=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200496
497 if (!stringp(arg) || !sizeof(arg)) {
498 tell_object(PL,break_string(
499 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
500 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
501 +"\n", 78,"",BS_LEAVE_MY_LFS));
502 return 1;
503 }
504
505 if (arg=="keine") {
506 monitoruids=({});
507 xmonitoruids=({});
508 tell_object(PL,break_string(
509 "Dein Fehlerteufel wird Dir nun nur noch "
510 "Fehler Deiner eigenen UIDs berichten.",78));
511 return 1;
512 }
513 else {
514 foreach(string uid: explode(arg," ")-({""})) {
515 if (sizeof(uid)>1 && uid[0]=='+') {
516 if (member(monitoruids,uid[1..])==-1)
517 monitoruids+=({uid[1..]});
518 }
519 else if (sizeof(uid)>1 && uid[0]=='-') {
520 monitoruids-=({uid[1..]});
521 }
522 else {
523 if (member(monitoruids,uid)==-1)
524 monitoruids+=({uid});
525 else
526 monitoruids-=({uid});
527 }
528 }
529 }
530 get_uids();
531 tell_object(PL,break_string(
532 "Momentan interessieren Dich folgende UIDs zusaetzlich zu Deinen: \n"
533 +(sizeof(monitoruids) ? CountUp(monitoruids) : "")
534 +"\n", 78,"",BS_LEAVE_MY_LFS));
535
536 return 1;
537}
538
539public int CmdModus(string arg) {
MG Mud User88f12472016-06-24 23:31:02 +0200540 // Argument verwursten
541 if (stringp(arg) && sizeof(arg)) {
542 modus = select_modus(arg);
543 reset(); // neue Fehlerliste holen
544 }
545 // aktuelle Einstellung ausgeben.
546 string *modstr=({});
547 if (modus & T_RTERROR)
548 modstr+=({"Fehler (Laufzeit)"});
549 if (modus & T_RTWARN)
550 modstr+=({"Warnungen (Laufzeit)"});
551 if (modus & T_CTERROR)
552 modstr+=({"Fehler (Ladezeit)"});
553 if (modus & T_CTWARN)
554 modstr+=({"Warnungen (Ladezeit)"});
555 if (modus & T_REPORTED_ERR)
556 modstr+=({"Fehlerhinweise"});
557 if (modus & T_REPORTED_IDEA)
558 modstr+=({"Idee"});
559 if (modus & T_REPORTED_MD)
560 modstr+=({"fehlende Details"});
561 if (modus & T_REPORTED_TYPO)
562 modstr+=({"Typo"});
Bugfixa75344d2017-06-16 14:04:48 +0200563 if(modus&T_REPORTED_SYNTAX)
564 modstr+=({"Syntaxhinweise"});
MG Mud User88f12472016-06-24 23:31:02 +0200565
566 tell_object(PL, break_string(
567 "Dein Fehlerteufel wird Dir nun ueber aufgetretene "
568 +CountUp(modstr)+" Bericht erstatten.",78));
569 return(1);
570}
571
572int CmdAddNote(string str) {
573 string *arr;
574
575 notify_fail("Bitte eine ID und einen Text angeben!\n");
576 if(!objectp(TI))
577 return 0;
578
Vaniondb7851b2020-03-10 21:52:34 +0100579 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200580 if (!stringp(str) || !sizeof(str))
581 return 0;
582
583 arr=explode(str," ")-({""});
584 if (sizeof(arr)<2)
585 return 0;
586 int issueid = to_int(arr[0]);
587
588 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne ID
589
Vaniondb7851b2020-03-10 21:52:34 +0100590 switch(({int})ERRORD->AddNote(issueid,str))
MG Mud User88f12472016-06-24 23:31:02 +0200591 {
592 case -1:
593 tell_object(PL,
594 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
595 return 1;
596 case -3:
597 return 0; //offenbar keine Notiz angegeben.
598 }
599 // letzten Fehler merken.
600 lfehler = issueid;
601
602 tell_object(PL,
603 sprintf("Deine Notiz wurde zu %d hinzugefuegt.\n",
604 issueid));
605 return 1;
606}
607
608int CmdFix(string str)
609{
610 string *arr;
611 int fixing, res;
612
613 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
614 if(!objectp(TI))
615 return 0;
616
Vaniondb7851b2020-03-10 21:52:34 +0100617 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200618 if (!stringp(str) || !sizeof(str))
619 return 0;
620
621 arr=explode(str," ")-({""});
622 if (!sizeof(arr))
623 return 0;
624
625 int issueid=to_int(arr[0]);
626 if (sizeof(arr)>1)
627 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
628 else str=0;
629
630 if (query_verb()=="ffix" || query_verb()=="fehlerfix")
631 {
632 fixing=1;
Vaniondb7851b2020-03-10 21:52:34 +0100633 res = ({int})ERRORD->ResolveIssue(issueid, str);
MG Mud User88f12472016-06-24 23:31:02 +0200634 }
635 else
636 {
Vaniondb7851b2020-03-10 21:52:34 +0100637 res = ({int})ERRORD->ReOpenIssue(issueid, str);
MG Mud User88f12472016-06-24 23:31:02 +0200638 }
639
640 if (res==-1)
641 {
642 tell_object(PL,
643 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
644 }
645 else if (res==-10)
646 {
647 tell_object(PL,
648 "Du hast leider keinen Schreibzugriff diesen Fehler.\n"
649 "Aber vielleicht moechtest Du mit fnotiz eine Notiz anhaengen?\n");
650 }
651 else if (res==-3)
652 {
653 if (fixing)
654 tell_object(PL,"Dieser Fehler ist bereits gefixt.\n");
655 else
656 tell_object(PL,"Dieser Fehler ist noch nicht gefixt.\n");
657 }
658 else if (res==1)
659 {
660 tell_object(PL,
661 sprintf("Fehler %d als gefixt markiert.\n",issueid));
662 }
663 else if (res==0)
664 {
665 tell_object(PL,
666 sprintf("Fehler %d als nicht gefixt markiert.\n",issueid));
667 }
668 // letzten Fehler merken.
669 lfehler = issueid;
670
671 return 1;
672}
673
674int CmdLock(string str) {
675 string *arr;
676 int locking;
677 int res;
678
679 notify_fail("Bitte eine ID und optional eine Notiz angeben!\n");
680 if(!objectp(TI))
681 return 0;
682
Vaniondb7851b2020-03-10 21:52:34 +0100683 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200684 if (!stringp(str) || !sizeof(str))
685 return 0;
686
687 arr=explode(str," ")-({""});
688 if (!sizeof(arr))
689 return 0;
690
691 int issueid=to_int(arr[0]);
692 if (sizeof(arr)>1)
693 str=implode(arr[1..]," "); //text wiederherstellen, aber ohne Key
694 else str=0;
695
696 if (query_verb()=="flock" || query_verb()=="fehlerlock")
697 {
698 locking=1;
Vaniondb7851b2020-03-10 21:52:34 +0100699 res=({int})ERRORD->LockIssue(issueid,str);
MG Mud User88f12472016-06-24 23:31:02 +0200700 }
701 else
702 {
Vaniondb7851b2020-03-10 21:52:34 +0100703 res=({int})ERRORD->UnlockIssue(issueid,str);
MG Mud User88f12472016-06-24 23:31:02 +0200704 }
705
706 if (res==-1)
707 {
708 tell_object(PL,
709 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
710 }
711 else if (res==-10)
712 {
713 tell_object(PL,
714 "Du hast leider keinen Schreibzugriff diesen Fehler.\n");
715 }
716 else if (res==-3)
717 {
718 if (locking)
719 tell_object(PL,
720 "Dieser Fehler ist bereits vor autom. Loeschen geschuetzt.\n");
721 else
722 tell_object(PL,
723 "Dieser Fehler ist bereits zum autom. Loeschen freigegeben.\n");
724 }
725 else if (res==-2)
726 {
727 tell_object(PL,
728 "Dieser Fehler ist bereits gefixt und wird bald geloescht.\n");
729 }
730 else if (res==1)
731 {
732 tell_object(PL,
733 sprintf("Fehler %d vor autom. Loeschen geschuetzt.\n",issueid));
734 }
735 else if (res==0)
736 {
737 tell_object(PL,
738 sprintf("Fehler %d zum autom. Loeschen freigegeben.\n",issueid));
739 }
740 // letzten Fehler merken.
741 lfehler = issueid;
742
743 return 1;
744}
745
746int CmdReassign(string str) {
747
748 notify_fail("Bitte eine ID, die neue UID und ggf. eine Notiz angeben!\n");
749 if(!objectp(TI))
750 return 0;
751
Vaniondb7851b2020-03-10 21:52:34 +0100752 str=({string})PL->_unparsed_args(0);
MG Mud User88f12472016-06-24 23:31:02 +0200753 if (!stringp(str) || !sizeof(str))
754 return 0;
755
756 string *arr=explode(str," ")-({""});
757 if (sizeof(arr)<2)
758 return 0;
759 int issueid=to_int(arr[0]);
760 string newuid=arr[1];
761
762 //text wiederherstellen, aber ohne Key und UID
763 if (sizeof(arr) > 2)
764 str = implode(arr[2..]," ");
765 else
766 str = 0;
767
Vaniondb7851b2020-03-10 21:52:34 +0100768 switch(({int})ERRORD->ReassignIssue(issueid, newuid, str))
MG Mud User88f12472016-06-24 23:31:02 +0200769 {
770 case -1:
771 tell_object(PL,
772 sprintf("Es gibt keinen Fehler mit der ID: %d\n",issueid));
773 return(1);
774 case -10:
775 tell_object(PL,
776 sprintf("Du hast keine Schreibrechte auf Fehler %d\n",issueid));
777 return 1;
778 case -2:
779 return(0); //offenbar keine neue uid angegeben. (kann nicht)
780 case -3:
781 tell_object(PL,break_string(
782 "Alte == Neue UID ist irgendwie unsinnig...",78));
783 return 1;
784 }
785 // letzten Fehler merken.
786 lfehler = issueid;
787
788 tell_object(PL,break_string(
789 sprintf("Der Fehler der ID %d wurde an die UID %s "
790 "uebertragen.\n", issueid, newuid),78));
791 return 1;
792}
793
Bugfix994aef02019-05-28 19:58:21 +0200794int CmdFehlerDirectory(string arg)
795{
796 struct fullissue_s issue=get_issue(arg);
797 if(!structp(issue))
798 {
799 PL->ReceiveMsg(
800 "Kein Eintrag mit dieser ID gefunden.",
801 MT_NOTIFICATION);
802 }
803 else
804 {
805 string path=issue->loadname||issue->obj;
806 if(!stringp(path) || !sizeof(path))
807 {
808 PL->ReceiveMsg(
809 "Kein Pfad zu dieser ID verfuegbar.",
810 MT_NOTIFICATION);
811 }
812 else
813 {
814 path=implode(explode(path,"/")[..<2],"/");
815 PL->SetProp(P_CURRENTDIR,path);
816 PL->ReceiveMsg(
817 "Aktuelles Verzeichnis ist jetzt: "+path,
818 MT_NOTIFICATION);
819 }
820 }
821 return 1;
822 }
823
MG Mud User88f12472016-06-24 23:31:02 +0200824// ************** public 'internal' functions **************
825public string QueryOwner() {return owner;}
826public mixed QueryIssueList() {return issuelist;}
827
Zesstraff356512018-08-27 20:20:36 +0200828protected void create() {
MG Mud User88f12472016-06-24 23:31:02 +0200829 if (!clonep(ME))
830 return;
831 ::create();
832
833 SetProp(P_SHORT,"Der Fehlerteufel");
834 SetProp(P_LONG,break_string(
835 "Dein Fehlerteufel soll Dir helfen, Informationen "
836 "ueber aufgetretene Fehler zu erhalten. Hierzu fragt er die "
837 "in \"Deinen\" UIDs aufgetretenen Fehler und deren Details vom "
838 "Fehlerspeicher der Mudlib ab. Folgende Kommandos kennt er:",78)
839 +"fehlerabfrage <id> - Fragt Details ueber Fehler mit der ID ab.\n"
840 "fehlerloeschen <id> - Fehler zum Loeschen markieren.\n"
841 "fehlerliste - Fehlerliste der eigenen UIDs anzeigen\n"
842 "fehlerrefresh - Fehlerdaten und UIDs neu einlesen\n"
843 "fehlerfilter - UIDs fuer den Filter angeben (s. manpage!)\n"
844 "fehlermodus - Fehler oder Warnungen ausgeben? (s. manpage)\n"
845 "fehlermonitor - zus. UIDs beobachten (s. manpage)\n"
846 "fnotiz <id> <note> - eine Notiz anhaengen\n"
847 "flock <id> <note> - Fehler vor autom. Loeschen schuetzen\n"
848 "funlock <id> <note> - Fehler zum autom. Loeschen freigeben\n"
849 "ffix <id> <note> - Fehler als gefixt kennzeichnen\n"
850 "funfix <id> <note> - gefixten Fehler als nicht-gefixt markieren\n"
Bugfix994aef02019-05-28 19:58:21 +0200851 "fdir <id> - in das Verzeichnis des fehlerhaften Objekts "
852 "wechseln\n"
MG Mud User88f12472016-06-24 23:31:02 +0200853 "fuebertrage <id> <newuid> <note>\n"
854 " - Fehler an die UID uebertragen\n"
855 );
856 SetProp(P_NAME,"Fehlerteufel");
857 SetProp(P_GENDER,MALE);
858 SetProp(P_WEIGHT,0);
859 SetProp(P_VALUE,0);
860 SetProp(P_SIZE,10);
861 SetProp(P_NODROP,"Den Fehlerteufel behaelst Du lieber bei Dir.\n");
862 SetProp(P_NEVERDROP,1);
863
864 AddId( ({"fehlerteufel","teufel"}) );
865
866 AddCmd(({"fehlerabfrage","fabfrage"}), "CmdFehlerZeigen" );
867 AddCmd(({"fehlerloeschen","floeschen"}), "CmdFehlerLoeschen");
868 AddCmd(({"fehlerliste","fliste", "fehleruebersicht","fuebersicht"}),
869 "CmdFehlerListe");
870 AddCmd(({"fehlerrefresh","frefresh"}),"CmdRefresh");
871 AddCmd(({"fehlerfilter","ffilter"}),"CmdFilter");
872 AddCmd(({"fehlermodus","fmodus"}),"CmdModus");
873 AddCmd(({"fehlermonitor","fmonitor"}),"CmdMonitor");
874 AddCmd(({"fehlernotiz","fnotiz"}),"CmdAddNote");
875 AddCmd(({"fehlerlock","flock","fehlerunlock","funlock"}),
876 "CmdLock");
877 AddCmd(({"fehlerfix","ffix","fehlerunfix","funfix"}),
878 "CmdFix");
879 AddCmd(({"fehleruebertrage","fuebertrage"}),"CmdReassign");
880 AddCmd(({"fehlereingabe", "feingabe"}), "CmdFehlerEingabe");
Bugfix994aef02019-05-28 19:58:21 +0200881 AddCmd(({"fehlerdir","fdir"}),"CmdFehlerDirectory");
MG Mud User88f12472016-06-24 23:31:02 +0200882}
883
Zesstraff356512018-08-27 20:20:36 +0200884public varargs void init(object origin)
MG Mud User88f12472016-06-24 23:31:02 +0200885{
886 if (find_call_out("remove") != -1) return;
887
888 // pruefung auf env nicht noetig, move geht nur in ein env und ohne env
889 // auch kein init().
890 if ( !query_once_interactive(environment()) ||
891 !IS_LEARNER(environment())) {
892 // in interactive, aber kein magier -> direkt weg.
893 call_out("remove",0,1);
894 return;
895 }
896 else if (!sizeof(owner))
897 // Env ist Interactiv und Magier (sonst waer man oben rausgeflogen)
898 owner=getuid(environment());
899 else if (owner!=getuid(environment())) {
900 //ok, nicht der Eigentuemer, direkt weg.
901 call_out("remove",0);
902 return;
903 }
904 SetProp(P_EXTRA_LOOK,break_string(
bugfixd94d0932020-04-08 11:27:13 +0200905 "Auf "+({string})environment()->Name(WESSEN)
906 +" Schulter sitzt ein kleiner "
MG Mud User88f12472016-06-24 23:31:02 +0200907 "Fehlerteufel, der "
bugfixd94d0932020-04-08 11:27:13 +0200908 +({string})environment()->QueryPronoun(WEM)
MG Mud User88f12472016-06-24 23:31:02 +0200909 +" immer wieder etwas ins Ohr fluestert.",78));
910
911 call_out("reset",1);
912
913 ::init();
914}
915
916public mixed Configure(mixed data)
917{
918 if (!data)
919 {
920 return (["filteruids":filteruids,
921 "filterstatus":filterstatus,
922 "modus":modus,
923 "monitoruids":monitoruids,
924 "fehlerzahl": fehlerzahl]);
925 }
926 else if (mappingp(data))
927 {
928 if (member(data,"filteruids") && pointerp(data["filteruids"]))
929 filteruids=data["filteruids"];
930 if (member(data,"filterstatus") && intp(data["filterstatus"]))
931 filterstatus=data["filterstatus"];
932 if (member(data,"modus") && intp(data["modus"]))
933 modus=data["modus"];
934 if (member(data,"monitoruids") && pointerp(data["monitoruids"]))
935 monitoruids=data["monitoruids"];
936 if (member(data,"fehlerzahl") && intp(data["fehlerzahl"]))
937 fehlerzahl=data["fehlerzahl"];
938 return 1;
939 }
940 return 0;
941}
942
943mapping _query_autoloadobj()
944{
945 return Configure(0);
946}
947
948mapping _set_autoloadobj(mixed data)
949{
950 Configure(data);
951 return _query_autoloadobj();
952}
953
954
955void reset()
956{
957 get_uids();
958 int neuefehlerzahl=get_issuelist();
959
960 if (fehlerzahl < neuefehlerzahl)
961 tell_object(environment(ME), break_string(
962 "Deine Fehlerliste ist soeben laenger geworden.",78,
963 "Dein Fehlerteufel teilt Dir mit: "));
964 else if (fehlerzahl > neuefehlerzahl)
965 tell_object(environment(ME), break_string(
966 "Deine Fehlerliste ist soeben kuerzer geworden.",78,
967 "Dein Fehlerteufel teilt Dir mit: "));
968 fehlerzahl = neuefehlerzahl;
969}
970
971// ******** private functions *********************
972private void get_uids()
973{
Vaniondb7851b2020-03-10 21:52:34 +0100974 uids=({string *})master()->QueryUIDsForWizard(owner);
MG Mud User88f12472016-06-24 23:31:02 +0200975 xmonitoruids=({});
976 if (sizeof(monitoruids))
977 {
978 closure cl=symbol_function("QueryUIDAlias", master());
979 foreach(string uid: monitoruids) {
Vaniondb7851b2020-03-10 21:52:34 +0100980 xmonitoruids += ({string*})funcall(cl, uid);
MG Mud User88f12472016-06-24 23:31:02 +0200981 }
982 }
983}
984
985/* Holt sich aus dem ErrorD die Liste ungeloeschter und ungefixter Fehler fuer
986 * fuer die UIDs des Magier fuer alle Typen
987 */
988private varargs int get_issuelist(int lmodus)
989{
990 int count;
991
992 if (!lmodus)
993 lmodus=modus;
994
995 issuelist=m_allocate(sizeof(ALL_ERR_TYPES),1);
996
997 foreach(int type: ALL_ERR_TYPES)
998 {
999 if (type & lmodus)
1000 {
1001 //DEBUG(sprintf("Type: %d\n",type));
1002 foreach(string uid : uids + xmonitoruids)
1003 {
1004 //DEBUG(sprintf("Type: %d, UID: %s\n",type,uid));
1005 < <int|string>* >* list =
Vaniondb7851b2020-03-10 21:52:34 +01001006 ({< <int|string>* >*})ERRORD->QueryIssueList(type,uid);
MG Mud User88f12472016-06-24 23:31:02 +02001007 count += sizeof(list);
1008
1009 if (!member(issuelist, type))
1010 issuelist += ([ type: ([ uid: list ]) ]);
1011 else if (!member(issuelist[type], uid))
1012 issuelist[type] += ([uid: list ]);
1013 }
1014 }
1015 }
Bugfix74112842019-05-28 19:06:33 +02001016
MG Mud User88f12472016-06-24 23:31:02 +02001017 return count;
1018}
1019
Bugfix74112842019-05-28 19:06:33 +02001020private struct fullissue_s get_issue(string arg)
1021{
1022 int issueid;
1023 struct fullissue_s issue;
1024
1025 if (stringp(arg) && sizeof(arg))
1026 {
1027 arg = trim(arg, TRIM_BOTH);
1028 issueid = to_int(arg);
1029 }
1030 else
1031 {
1032 issueid = lfehler;
1033 arg = to_string(issueid);
1034 }
1035
1036 // Wurde ein Hash uebergeben, ist issueid 0 und arg der Hash.
1037 // Wurde eine ID oder nichts uebergeben, ist issueid die ID als int und
1038 // arg die ID als string.
1039 if (to_string(issueid) == arg)
Vaniondb7851b2020-03-10 21:52:34 +01001040 issue = ({struct fullissue_s})ERRORD->QueryIssueByID(issueid);
Bugfix74112842019-05-28 19:06:33 +02001041 else
Vaniondb7851b2020-03-10 21:52:34 +01001042 issue = ({struct fullissue_s})ERRORD->QueryIssueByHash(arg);
Bugfix74112842019-05-28 19:06:33 +02001043 return issue;
1044}
1045
1046private struct fullissue_s|struct fullissue_s* get_issues(string arg)
1047{
bugfixd94d0932020-04-08 11:27:13 +02001048 arg=({string})PL->_unparsed_args();
Bugfix74112842019-05-28 19:06:33 +02001049 struct fullissue_s|struct fullissue_s* issues;
Bugfixe1949592019-09-16 20:41:54 +02001050
1051 // Erstmal schauen, ob arg eine ID ist.
1052 issues=get_issue(arg);
1053 // Wenn nicht, dann ist es wohl ein Pfad.
1054 if(!structp(issues))
Bugfix74112842019-05-28 19:06:33 +02001055 {
Bugfixe1949592019-09-16 20:41:54 +02001056 // Mit einem / am Anfang ist der Pfad vermutlich komplett, ansonsten
1057 // wird im aktuellen Verzeichnis gesucht.
1058 if(sizeof(arg) && arg[0] != '/')
1059 {
bugfixd94d0932020-04-08 11:27:13 +02001060 arg=({string})PL->QueryProp(P_CURRENTDIR)+"/"+arg;
Bugfixe1949592019-09-16 20:41:54 +02001061 }
Bugfix74112842019-05-28 19:06:33 +02001062 issues=({});
1063 foreach(int m: ALL_ERR_TYPES)
1064 {
1065 if (!(m & modus))
1066 continue;
1067 struct fullissue_s *tmp =
Vaniondb7851b2020-03-10 21:52:34 +01001068 ({struct fullissue_s *})ERRORD->QueryIssuesByFile(arg, m);
Bugfix74112842019-05-28 19:06:33 +02001069 if (tmp)
1070 issues+=tmp;
1071 }
1072 if (!sizeof(issues))
1073 issues=0;
1074 }
Bugfix74112842019-05-28 19:06:33 +02001075
1076 return issues;
1077}