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