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