blob: 4598ba69bc5206afcf937a27b65d8bd684611caf [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/*
2 * MGtool-1.0
3 * File: toolcmds.c
4 * Maintainer: Kirk@MorgenGrauen
5 */
6
7/*------------------------------------------*/
8/* the original Xtool is copyrighted by Hyp */
9/*------------------------------------------*/
10
11#include "tool.h"
12
13/*----------------------------------------------------------------------
14 * command functions
15 */
16
17int Xcall(string str)
18{
19 object obj, callobj;
20 string file, callstr, callfun, callexpr, error, errlog;
21 int *ru1, *ru2, xtime;
22 mixed res;
23
24 SECURE2(TRUE);
25 USAGE2(str, "xcall <object>-><function>(<arguments>)");
26 TK("Xcall: str: "+(str?str:"(NULL)"));
27 if(sscanf(str, "%s->%s(%s", callstr, callfun, callexpr)!=3)
28 return FALSE;
29 if(!(callobj=XFindObj(callstr)))
30 return TRUE;
31 else
32 {
33#if 0
34 write_file(TOOL_LOG,
35 sprintf("%s (%s) xcall %s (env: %s)\n",ctime(time()),
36 getuid(cloner),str,object_name(environment(cloner))));
37#endif
38 file=LPC_FILE+".c";
39 if(file_size(file)>0)
40 rm(file);
41 if(obj=find_object(LPC_FILE))
42 Destruct(obj);
43 obj=0;
44 write_file(file,
45 "#include <properties.h>\n"+
46 "#include <thing/properties.h>\n"+
47 "#include <defines.h>\n"+
48 "#include <wizlist.h>\n"+
49 "#include <moving.h>\n"+
50 "#include \"/secure/wizlevels.h\"\n"+
51 (file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
52 "mixed get(string str){return previous_object()->XFindObj(str);}\n"+
53 "mixed eval(object obj,mixed me,mixed here){return obj->"+callfun+"("+callexpr+";}\n");
54 errlog = ERR_FILE;
55 if(file_size(errlog)>0)
56 rm(errlog);
57 if(error=catch((LPC_FILE)->__nixgibts__()))
58 W("Error: "+error[1..]);
59 else
60 {
61 obj=find_object(LPC_FILE);
62 ru1=rusage();
bugfixd94d0932020-04-08 11:27:13 +020063 error=catch(res=({mixed})obj->eval(callobj, cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +020064 ru2=rusage();
65 if(error)
66 W("Error: "+error[1..]);
67 else
68 {
69 xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
70 WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
71 PIPE_DELETE(pipe_of);
72 if(pipe_out&&pipe_of)
73 write_file(pipe_of,mixed_to_string(res, MAX_RECURSION)+"\n");
74 else
75 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
76 if(objectp(res))
77 m_add(variable, "result", res);
78 }
79 }
80 rm(file);
81 }
82 if(obj) Destruct(obj);
83 return TRUE;
84}
85
86int Xcallouts(string str)
87{
Arathorn65b45e02022-02-07 22:03:57 +010088 mixed callouts;
89 string tmp, file;
90 int i, s;
MG Mud User88f12472016-06-24 23:31:02 +020091
92 SECURE2(TRUE);
93 TK("Xcallouts: str: "+(str?str:"(NULL)"));
94 if(!pipe_out)
95 {
96 USAGE1(str, "xcallo(uts) [search pattern]");
97 file=TMP_FILE;
98 if(file_size(file)>0)
99 rm(file);
100 if(!str)
101 str="^\\[~/";
102 else if(!regexp(({"dummy"}), str))
103 {
104 WDLN("Bad regular expression");
105 return TRUE;
106 }
107 }
108 else
109 {
110 USAGE1(str, "xcallo(uts)");
111 if(str&&str!="")
112 {
113 WDLN("More arguments than expected");
114 return TRUE;
115 }
116 }
117 callouts=call_out_info();
118 s=sizeof(callouts);
119 PIPE_DELETE(pipe_of);
120 for(i=0; i<s; i++)
121 {
122 if(callouts[i]&&pointerp(callouts[i]))
123 {
124 tmp=sprintf("%O %Os %O (%s)",callouts[i][0],callouts[i][2],
125 callouts[i][1],(sizeof(callouts[i])>3?
126 mixed_to_string(callouts[i][3],
127 MAX_RECURSION):"0"));
128 if(pipe_out&&pipe_of)
129 write_file(pipe_of,tmp+"\n");
130 else
131 if(sizeof(regexp(({tmp}), str)))
132 WLN(tmp);
133 }
134 }
135 return TRUE;
136}
137
138int Xcat(string str)
139{
140 string *tmp,file;
MG Mud User88f12472016-06-24 23:31:02 +0200141
142 SECURE2(TRUE);
143 TK("Xcat: str: "+str);
144 if(!pipe_in)
145 {
146 USAGE2(str, "xcat <file>");
147 if(!(file=XFindFile(str)))
148 {
149 WDLN("Can't find file");
150 return TRUE;
151 }
152 }
153 else
154 {
155 if(str&&str!="-")
156 USAGE3("xcat -");
157
158 if (file_size(file=pipe_if)<0)
159 {
160 WDLN("Missing input to xcat");
161 return TRUE;
162 }
163 }
164 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
165 if(pipe_in&&pipe_if==PIPE_FILE)
166 rm(PIPE_FILE);
167 if (pipe_out&&pipe_of)
168 write_file(pipe_of,implode(tmp,"\n")+"\n");
169 else
170 WLN(implode(tmp,"\n"));
171 return TRUE;
172}
173
174int Xcd(string str)
175{
176 object dest;
177 string path;
178
179 SECURE2(TRUE);
180 USAGE1(str, "xcd [object]");
181 TK("Xcd: str: "+(str?str:"(NULL)"));
182 if(!str)
183 {
bugfixd94d0932020-04-08 11:27:13 +0200184 if(!(path=({string})cloner->QueryProp("start_home")))
MG Mud User88f12472016-06-24 23:31:02 +0200185 path="/";
186 }
187 else if((dest=XFindObj(str,1)))
188 path="/"+implode(old_explode(object_name(dest),"/")[0..<2],"/");
189 else
190 path="";
191
192 TK("Xcd: path: "+(path?path:"(NULL)"));
193 if(!sizeof(path))
194 path=str;
195 PL->_cd(path);
196
197 return TRUE;
198}
199
200int Xclean(string str)
201{
202 object env;
203
204 SECURE2(TRUE);
205 USAGE1(str, "xcle(an) [object]");
206 TK("Xclean: str: "+(str?str:"(NULL)"));
207 if(!str)
208 env=ENV(cloner);
209 if(env||(env=XFindObj(str)))
210 {
211 PrintShort("Cleaning: ", env);
212 filter(filter(all_inventory(env), #'is_not_player),//'
213 "Destruct", ME);
214 }
215 return TRUE;
216}
217
218int Xclone(string str)
219{
220 object obj;
221 string file, errlog, error;
222
223 SECURE2(TRUE);
224 USAGE2(str, "xclo(ne) <filename>");
225 if(!(file=XFindFile(str))) return TRUE;
226 errlog=ERR_FILE;
227 if(file_size(errlog)>0) rm(errlog);
228 WLN("Clone: "+short_path(file));
229 if(!(error=catch(obj=clone_object(file))))
230 {
231 m_add(variable, "clone", obj);
232 if(!MoveObj(obj, ENV(cloner), TRUE))
233 WDLN("Cannot move object into this room");
bugfixd94d0932020-04-08 11:27:13 +0200234 else if(!({mixed})obj->QueryNoGet())
MG Mud User88f12472016-06-24 23:31:02 +0200235 {
236 if(!MoveObj(obj, cloner, TRUE))
237 WDLN("Cannot move object into your inventory");
238 }
239 }
240 else
241 W("Error: "+error[1..]);
242 return TRUE;
243}
244
245int Xuclone(string str)
246{
247 object obj;
248 string file, errlog, error;
249
250 SECURE2(TRUE);
251 USAGE2(str, "xuclo(ne) <filename>");
252 if(!(file=XFindFile(str))) return TRUE;
253 errlog=ERR_FILE;
254 if(file_size(errlog)>0) rm(errlog);
255 if(obj=find_object(file)) {
256 Destruct(obj);
257 WLN("Update and clone: "+short_path(file));
258 }
259 else
260 WLN("Clone: "+short_path(file));
261 if(!(error=catch(obj=clone_object(file))))
262 {
263 variable["clone"] = obj;
264 if(!MoveObj(obj, ENV(cloner), TRUE))
265 WDLN("Cannot move object into this room");
bugfixd94d0932020-04-08 11:27:13 +0200266 else if(!({mixed})obj->QueryNoGet())
MG Mud User88f12472016-06-24 23:31:02 +0200267 {
268 if(!MoveObj(obj, cloner, TRUE))
269 WDLN("Cannot move object into your inventory");
270 }
271 }
272 else
273 W("Error: "+error[1..]);
274 return TRUE;
275}
276
277int Xcmds(string str)
278{
279 object obj;
280 mixed *cmds;
281 int i, s;
282
283 SECURE2(TRUE);
284 USAGE1(str, "xcm(ds) [object]");
285 TK("Xcmds: str: "+(str?str:"(NULL)"));
286 if(!str)
287 obj=ENV(cloner);
288 else if(!(obj=XFindObj(str)))
289 {
290 WDLN("Can't find object");
291 return TRUE;
292 }
293 s=sizeof(cmds=query_actions(cloner,1|2|4|8|16));
294 PIPE_DELETE(pipe_of);
295 for(i=0; i<s; i+=5)
296 if(cmds[i+3]==obj)
297 if(pipe_out&&pipe_of)
298 write_file(pipe_of,ALEFT(cmds[i]+" ", 15, ".")+
299 (cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()\n");
300 else
301 WLN(ALEFT(cmds[i]+" ", 15, ".")+
302 (cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()");
303 return TRUE;
304}
305
306int Xdbg(string str)
307{
308 object obj;
309
310 SECURE2(TRUE);
311 USAGE2(str, "xdb(g) <object>");
312 TK("Xdbg: str: "+(str?str:"(NULL)"));
313 if((obj=XFindObj(str)))
314 {
315 debug_info(1, obj);
316 debug_info(0, obj);
317 }
318 return TRUE;
319}
320
321int Xdclean(string str)
322{
323 object env;
324
325 SECURE2(TRUE);
326 USAGE1(str, "xdc(lean) [object]");
327 TK("Xdclean: str: "+(str?str:"(NULL)"));
328 if(!str)
329 env=ENV(cloner);
330 if(env||(env=XFindObj(str)))
331 {
332 PrintShort("Deep cleaning: ", env);
333 filter(filter(all_inventory(env), #'is_not_player, ME),//'
334 "DeepClean", ME);
335 }
336 return TRUE;
337}
338
339int Xddes(string str)
340{
341 object obj;
342
343 SECURE2(TRUE);
344 USAGE2(str, "xdd(es) <object>");
345 TK("Xddes: str: "+(str?str:"(NULL)"));
346 if((obj=XFindObj(str)))
347 {
348 PrintShort("Deep destruct: ", obj);
349 filter(deep_inventory(obj), "Destruct", ME);
350 Destruct(obj);
351 }
352 return TRUE;
353}
354
355int Xdes(string str)
356{
357 object obj;
358
359 SECURE2(TRUE);
360 USAGE2(str, "xde(s) <object>");
361 TK("Xdes: str: "+(str?str:"(NULL)"));
362 if((obj=XFindObj(str)))
363 {
364 PrintShort("Destruct: ",obj);
365 Destruct(obj);
366 }
367 return TRUE;
368}
369
370int Xdlook(string str)
371{
372 object obj;
373
374 SECURE2(TRUE);
375 USAGE1(str, "xdl(ook) [object]");
376 TK("Xdlook: str: "+(str?str:"(NULL)"));
377 if(!str)
378 obj=cloner;
379 if(obj||(obj=XFindObj(str)))
380 {
381 PIPE_DELETE(pipe_of);
382 DeepPrintShort(obj,NULL,NULL,(pipe_out&&pipe_of)?pipe_of:"");
383 }
384 return TRUE;
385}
386
387int Xdo(string str)
388{
389 int i, n, s;
390 string *strs, cmd;
391
392 SECURE2(TRUE);
393 USAGE2(str, "xdo [<number1>#]<command1>[;[<number2>#]<command2>] ...");
394 if(!str||str==""||!(s=sizeof(strs=strip_explode(str, ";"))))
395 return FALSE;
396 for(i=0; i<s; i++)
397 {
398 if(strs[i])
399 {
400 switch(sscanf(strs[i], "%d#%s", n, cmd))
401 {
402 case 0:
403 if(!Command(strs[i])) return TRUE;
404 break;
405 case 1:
406 if(cmd&&(!Command(cmd))) return TRUE;
407 break;
408 case 2:
409 n= n<1 ? 1 : n;
410 if(cmd)
411 {
412 while(n--)
413 if(!Command(cmd)) return TRUE;
414 }
415 break;
416 }
417 }
418 }
419 return TRUE;
420}
421
422int Xdupdate(string str)
423{
424 int i, s;
425 object obj;
426 string file, *list;
427
428 SECURE2(TRUE);
429 USAGE2(str, "xdu(pdate) <filename>");
430 if(!(file=XFindFile(str)))
431 return TRUE;
432 if(file[<2..<1]==".c")
433 file=file[0..<3];
434 if(obj=XFindObj(file))
435 {
436 PrintShort("Deep updating: ", obj);
437 list=inherit_list(obj);
438 for(s=sizeof(list); i<s; i++)
439 {
440 if(obj=find_object(list[i]))
441 Destruct(obj);
442 }
443 }
444 return TRUE;
445}
446
447int Xecho(string str)
448{
449 TK("Xecho: str: "+(str?str:"(NULL)"));
450 WLN(str);
451 return TRUE;
452}
453
454int Xeval(string str)
455{
456 object obj;
457 string file, error;
458 int *ru1, *ru2, xtime;
459 mixed res;
460
461 SECURE2(TRUE);
462 USAGE2(str, "xev(al) <expression>");
463 file=LPC_FILE+".c";
464 if(file_size(file)>0)
465 rm(file);
466 if(obj=find_object(LPC_FILE))
467 Destruct(obj);
468#if 0
469 write_file(TOOL_LOG,
470 sprintf("%s (%s) xeval %s\n",
471 ctime(time()),getuid(cloner),str));
472#endif
473 write_file(file,
474 "#include <properties.h>\n"+
475 "#include <thing/properties.h>\n"+
476 "#include <defines.h>\n"+
477 "#include <wizlist.h>\n"+
478 "#include <moving.h>\n"+
479 "#include \"/secure/wizlevels.h\"\n"+
480 (file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
Zesstra13fb5a02020-04-15 13:28:39 +0200481 "mixed get(string str){return previous_object()->XFindObj(str);}\n"+
482 "mixed eval(mixed me,mixed here){return "+str+";}");
MG Mud User88f12472016-06-24 23:31:02 +0200483 if(error=catch(obj=clone_object(file)))
484 W("Error: "+error[1..]);
485 else
486 {
487 ru1=rusage();
bugfixd94d0932020-04-08 11:27:13 +0200488 error=catch(res=({mixed})obj->eval(cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +0200489 ru2=rusage();
490 if(error)
491 W("Error: "+error[1..]);
492 else
493 {
494 xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
495 WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
496 PIPE_DELETE(pipe_of);
497 if(pipe_out&&pipe_of)
498 write_file(pipe_of,mixed_to_string(res,MAX_RECURSION)+"\n");
499 else
500 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
501 if(objectp(res))
502 variable["result"] = res;
503 }
504 }
505 rm(file);
506 if(obj)
507 Destruct(obj);
508 return TRUE;
509}
510
511int Xforall(string str)
512{
513 int i, s, t, u;
514 string pat, cmd, arg, *strs, *files, fh, fr, fe, ft, ff;
515
516 SECURE2(TRUE);
517 USAGE2(str, "xfo(rall) <filepattern> <command>");
518 if(sscanf(str, "%s %s", pat, arg)!=2)
519 return FALSE;
520 files=long_get_dir(pat, FALSE);
521 if(!(s=sizeof(files)))
522 {
523 WDLN("No matching files found");
524 return TRUE;
525 }
526 strs=old_explode(files[0], "/");
527 fh="/";
528 if(t=sizeof(strs)-1)
529 fh+=implode(strs[0..t-1], "/");
530 for(i=0; i<s; i++)
531 {
532 ft=old_explode(files[i], "/")[t];
533 if((u=sizeof(strs=old_explode(ft, ".")))&&--u)
534 {
535 ff=implode(strs[0..u-1], ".");
536 fr=fh+"/"+ff;
537 fe=strs[u];
538 }
539 else
540 {
541 fe="";
542 ff=ft;
543 fr=files[i];
544 }
545 cmd=string_replace(arg, "!!", files[i]);
546 cmd=string_replace(cmd, "!e", fe);
547 cmd=string_replace(cmd, "!f", ff);
548 cmd=string_replace(cmd, "!h", fh);
549 cmd=string_replace(cmd, "!r", fr);
550 cmd=string_replace(cmd, "!t", ft);
551 if(!(Command(cmd)))
552 break;
553 }
554 return TRUE;
555}
556
557int Xgoto(string str)
558{
559 object obj, tmp;
560
561 SECURE2(TRUE);
562 USAGE1(str, "xgo(to) [object]");
563 if(!str) str="~/workroom";
564 if(!(obj=XFindObj(str)))
565 {
566 if(!(str=XFindFile(str)))
567 return TRUE;
568 if(catch(call_other(str, "???")))
569 return TRUE;
570 obj=find_object(str);
571 }
572 tmp=obj;
573 while(obj&&living(obj))
574 obj=ENV(obj);
575 cloner->move(obj ? obj : tmp, M_TPORT);
576 return TRUE;
577}
578
579int Xgrep(string str)
580{
581 int i, s, t, mode;
582 string *files, *ts;
583
584 SECURE2(TRUE);
585 TK("Xgrep: str: "+(str?str:"(NULL)"));
586 mode=0;
587 if(!pipe_in)
588 {
589 USAGE2(str, "xgr(ep) [-i] [-v] <regexp> <filepattern>");
590 if(!(ts=old_explode(str, " "))||!(s=sizeof(ts)))
591 return FALSE;
592 while(ts[0][0]=='-')
593 {
594 if(s<3)
595 {
596 WDLN("Too few arguments to xgrep");
597 return FALSE;
598 }
599 switch(ts[0])
600 {
601 case "-v":
602 mode|=XGREP_REVERT;
603 ts=ts[1..];
604 s--;
605 break;
606 case "-i":
607 mode|=XGREP_ICASE;
608 ts=ts[1..];
609 s--;
610 break;
611 case "-vi":
612 case "-iv":
613 mode|=XGREP_REVERT;
614 mode|=XGREP_ICASE;
615 ts=ts[1..];
616 s--;
617 break;
618 default:
619 WDLN("Unknown option "+ts[0]+" given to xgrep");
620 return FALSE;
621 }
622 }
623 str=implode(ts[0..s-2], " ");
624 }
625 else
626 {
627 if(!((ts=old_explode(str, " "))&&(s=sizeof(ts))))
628 USAGE3("xgr(ep) [-i] [-v] <regexp>");
629 while(ts[0][0]=='-')
630 {
631 if(s<2)
632 {
633 WDLN("Too few arguments to xgrep");
634 return FALSE;
635 }
636 switch(ts[0])
637 {
638 case "-v":
639 mode|=XGREP_REVERT;
640 ts=ts[1..];
641 s--;
642 break;
643 case "-i":
644 mode|=XGREP_ICASE;
645 ts=ts[1..];
646 s--;
647 break;
648 case "-iv":
649 case "-vi":
650 mode|=XGREP_REVERT;
651 mode|=XGREP_ICASE;
652 ts=ts[1..];
653 s--;
654 break;
655 default:
656 WDLN("Unknown option "+ts[0]+" given to xgrep");
657 return FALSE;
658 }
659 }
660 str=implode(ts[0..s-1], " ");
661 }
662
663 if(mode&XGREP_ICASE)
664 str=lower_case(str);
665 if(!(regexp(({"dummy"}), str)))
666 {
667 WDLN("Bad regular expression");
668 return TRUE;
669 }
670 if(!pipe_in)
671 {
672 if(file_size(TMP_FILE)>0)
673 rm(TMP_FILE);
674 if((t=sizeof(files=long_get_dir(XFile(ts[s-1]), FALSE)))&&
675 (file_size(files[0])>=0))
676 {
677 for(i=0; i<t; i++)
678 XGrepFile(str, files[i], mode);
679 if(pipe_out&&pipe_of)
680 {
681 PIPE_DELETE(pipe_of);
682 if(!pipe_ovr)
683 {
684 write_file(pipe_of,read_file(TMP_FILE,0,PIPE_MAX));
685 rm(TMP_FILE);
686 }
687 else
688 rename(TMP_FILE,pipe_of);
689 }
690 else
691 {
692 W(read_file(TMP_FILE,0,PIPE_MAX));
693 rm(TMP_FILE);
694 }
695 }
696 else
697 WDLN("Cannot read file(s)");
698 }
699 else
700 {
701 string *tmp;
702 if(file_size(pipe_if)<0)
703 {
704 WDLN("Missing input to xgrep");
705 return TRUE;
706 }
707 TK("Xgrep: str: "+str+" mode: "+mode);
708 s=sizeof(tmp=old_explode(read_file(pipe_if,0,PIPE_MAX),"\n"));
709 PIPE_DELETE(pipe_of);
710 for(i=0;i<s;i++)
711 {
712 // TK(tmp[i]+"<->"+str);
713 if(sizeof(regexp(({(mode&XGREP_ICASE?lower_case(tmp[i]):tmp[i])}),str)))
714 {
715 // TK("Xgrep: matched!");
716 if(!(mode&XGREP_REVERT))
717 if(pipe_out&&pipe_of)
718 write_file(pipe_of,tmp[i]+"\n");
719 else
720 WLN(tmp[i]);
721 }
722 else
723 if(mode&XGREP_REVERT)
724 if(pipe_out&&pipe_of)
725 write_file(pipe_of,tmp[i]+"\n");
726 else
727 WLN(tmp[i]);
728 }
729 }
730 return TRUE;
731}
732
733int Xhbeats(string str)
734{
MG Mud User88f12472016-06-24 23:31:02 +0200735 object *hbeatinfo;
Arathorn65b45e02022-02-07 22:03:57 +0100736 string tmp;
MG Mud User88f12472016-06-24 23:31:02 +0200737 int i, s;
738
739 SECURE2(TRUE);
740 TK("Xhbeats: str: "+(str?str:"(NULL)"));
741 if(!pipe_out)
742 {
743 USAGE1(str, "xhb(eats) [search pattern]");
744 if(!str)
745 str=RNAME(cloner);
746 else if(!regexp(({"dummy"}), str))
747 {
748 WDLN("Bad regular expression");
749 return TRUE;
750 }
751 }
752 else
753 {
754 USAGE1(str,"xhb(eats)");
755 if(str&&str!="")
756 {
757 WDLN("More arguments than expected");
758 return TRUE;
759 }
760 }
761 s=sizeof(hbeatinfo=heart_beat_info());
762 PIPE_DELETE(pipe_of);
763 for(i=0; i<s; i++)
764 if(hbeatinfo[i]&&objectp(hbeatinfo[i]))
765 {
766 tmp=ObjFile(hbeatinfo[i]);
767 if(sizeof(regexp(({tmp}), str)))
768 if(pipe_out&&pipe_of)
769 write_file(pipe_of, tmp+"\n");
770 else
771 WLN(tmp);
772 }
773 return TRUE;
774}
775
776int Xhead(string str)
777{
778 int lines;
779 string *tmp, file;
780
781 SECURE2(TRUE);
782 TK("Xhead: str: "+(str?str:"(NULL)"));
783 if(!pipe_in)
784 {
785 USAGE2(str, "xhead <-#> <file>");
786 if(sscanf(str,"-%d %s",lines,file)!=2)
787 return FALSE;
788 if(!(file=XFindFile(file)))
789 return FALSE;
790 }
791 else
792 {
793 USAGE2(str, "xhead <-#>");
794 if(sscanf(str,"-%d",lines)!=1)
795 return FALSE;
796 if (file_size(file=pipe_if)<0)
797 {
798 WDLN("Missing input to xhead");
799 return TRUE;
800 }
801 }
802 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[0..lines-1];
803 if(pipe_in&&pipe_if==PIPE_FILE)
804 rm(PIPE_FILE);
805 if (pipe_out&&pipe_of)
806 {
807 PIPE_DELETE(pipe_of);
808 write_file(pipe_of,implode(tmp,"\n")+"\n");
809 }
810 else
811 WDLN(implode(tmp,"\n"));
812 return TRUE;
813}
814
815int Xhelp(string str)
816{
817 SECURE2(TRUE);
818 USAGE1(str, "xhe(lp)");
819 XMoreFile(TOOL_MANPAGE, FALSE);
820 return TRUE;
821}
822
823int Xids(string str)
824{
825 object obj;
826
827 SECURE2(TRUE);
828 USAGE2(str, "xid(s) <object>");
829 TK("Xids: str: "+(str?str:"(NULL)"));
830 if((obj=XFindObj(str)))
831 WLN("UID=\""+getuid(obj)+"\" / EUID=\""+geteuid(obj)+"\"");
832 return TRUE;
833}
834
835int Xinfo(string str)
836{
837 object obj;
838
839 SECURE2(TRUE);
840 USAGE2(str, "xinf(o) <object>");
841 TK("Xinfo: str: "+(str?str:"(NULL)"));
842 if((obj=XFindObj(str)))
843 {
844 if(is_player(obj))
845 {
846 WLN(PlayerWho(obj));
847 WLN(PlayerMail(obj, FALSE));
848 WLN(PlayerIP(obj, FALSE));
849 WLN(PlayerRace(obj, FALSE));
850 WLN(PlayerDomain(obj, FALSE));
851 WLN(PlayerStats(obj, FALSE));
852 WLN(PlayerSnoop(obj, FALSE));
853 }
854 else
855 WDLN("Sorry, this is not a player");
856 }
857 return TRUE;
858}
859
860int Xinherit(string str)
861{
862 int s;
863 object obj;
864 string *strs, *inlist;
865
866 SECURE2(TRUE);
867 USAGE2(str, "xinh(erit) <object> [function]");
868 TK("Xinherit: str: "+str);
869 if(!(strs=strip_explode(str, " ")))
870 return FALSE;
871 if(obj=XFindObj(strs[0]))
872 {
873 inlist=inherit_list(obj);
874 s=sizeof(inlist);
875 while(s--)
876 {
877 if(catch(call_other(inlist[s], "???")))
878 {
879 WDLN("Failed to load all inheritance objects");
880 return TRUE;
881 }
882 }
883 obj=find_object(inlist[0]);
884 PIPE_DELETE(pipe_of);
885 if(sizeof(strs)==1)
886 Inheritance(obj ,0 ,"");
887 else
888 Inheritance(obj, strs[1], "");
889 }
890 return TRUE;
891}
892
893int Xinventory(string str)
894{
895 int i, short;
896 object item;
897 mixed who;
898
899 SECURE2(TRUE);
900 USAGE1(str, "xi [-s] [player]");
901 TK("Xinventory: str: "+str);
902 short=0;
903 who=cloner;
904 if(str&&str!="")
905 {
906 if(str=="-s")
907 {
908 short=1;
909 who=cloner;
910 }
911 else if(sscanf(str,"-s %s",who))
912 {
913 short=1;
914 who=XFindObj(who);
915 }
916 else if(sscanf(str,"%s",who))
917 {
918 short=0;
919 who=XFindObj(who);
920 }
921 else
922 who=cloner;
923 }
924 if(!who)
925 return FALSE;
926 PIPE_DELETE(pipe_of);
927 if(!(pipe_out&&pipe_of))
bugfixd94d0932020-04-08 11:27:13 +0200928 WLN(({string})who->name(WESSEN)+" Inventory:"+(short?" (short)":""));
MG Mud User88f12472016-06-24 23:31:02 +0200929 if(!short)
930 if(pipe_out&&pipe_of)
931 FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item, pipe_of);
932 else
933 FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item);
934 else
935 if(pipe_out&&pipe_of)
936 FORALL(item, who) write_file(pipe_of,++i+". ["+object_name(item)+"]\n");
937 else
938 FORALL(item, who) WLN(++i+". ["+object_name(item)+"]");
939 return TRUE;
940}
941
942int Xlag(string str)
943{
MG Mud User88f12472016-06-24 23:31:02 +0200944 float *lag;
945 object daemon;
946 string lags;
947
Zesstrabc791ab2017-01-30 23:06:48 +0100948 if(!(daemon=load_object(LAG_O_DAEMON)))
MG Mud User88f12472016-06-24 23:31:02 +0200949 lag=({-1.0,-1.0,-1.0});
950 else
bugfixd94d0932020-04-08 11:27:13 +0200951 lag=({float*})daemon->read_lag_data();
Zesstradb5c6522020-05-27 00:26:35 +0200952
953 lags =sprintf("Letzte 60 min: %.1f%%\n",lag[2]);
954 lags+=sprintf("Letzte 15 min: %.1f%%\n",lag[1]);
955 lags+=sprintf("Letzte Minute: %.1f%%\n",lag[0]);
956
MG Mud User88f12472016-06-24 23:31:02 +0200957 WLN(lags);
958 return TRUE;
959}
960
961int Xlight(string str)
962{
Arathorn65b45e02022-02-07 22:03:57 +0100963 int addlight;
MG Mud User88f12472016-06-24 23:31:02 +0200964
965 SECURE2(TRUE);
966 USAGE1(str, "xli(ght) [light]");
967 if(str)
968 {
969 if(!sscanf(str, "%d", addlight))
970 return FALSE;
971 xlight+=addlight;
972 cloner->AddIntLight(addlight);
973 }
974 WDLN("Current light levels: "+TOOL_NAME+"="+xlight+", room="+
bugfixd94d0932020-04-08 11:27:13 +0200975 ({int})ENV(cloner)->QueryIntLight());
MG Mud User88f12472016-06-24 23:31:02 +0200976 return TRUE;
977}
978
979int Xload(string str)
980{
Arathorn65b45e02022-02-07 22:03:57 +0100981 int i;
MG Mud User88f12472016-06-24 23:31:02 +0200982 object obj, *inv, vroom;
Arathorn65b45e02022-02-07 22:03:57 +0100983 string file, errlog, error;
MG Mud User88f12472016-06-24 23:31:02 +0200984
985 SECURE2(TRUE);
986 USAGE2(str, "xloa(d) <filename>");
987 if(!(file=XFindFile(str)))
988 return TRUE;
989 errlog=ERR_FILE;
990 if(file_size(errlog)>0)
991 rm(errlog);
992 if(obj=find_object(file))
993 {
994 if(catch(call_other(VOID, "???")))
995 {
996 WDLN("Error: cannot find "+VOID+" to rescue players");
997 return TRUE;
998 }
999 else
1000 vroom = find_object(VOID);
1001 if(inv=filter(all_inventory(obj), #'is_player, ME))//'
1002 for(i=0; i<sizeof(inv); i++)
1003 MoveObj(inv[i], vroom, TRUE);
1004 Destruct(obj);
1005 WLN("Update and load: "+file);
1006 }
1007 else
1008 WLN("Load: "+file);
1009 if(error=catch(call_other(file, "???")))
1010 {
1011 W("Error: "+error[1..]);
1012 if(vroom)
1013 tell_object(vroom, "*** Failed to load room. You are in the void!\n");
1014 }
1015 else if(inv)
1016 {
1017 obj=find_object(file);
1018 for(i=0; i<sizeof(inv); i++)
1019 if(inv[i])
1020 MoveObj(inv[i], obj, TRUE);
1021 }
1022 return TRUE;
1023}
1024
1025int Xlook(string str)
1026{
1027 object obj;
MG Mud User88f12472016-06-24 23:31:02 +02001028 string file;
1029
1030 SECURE2(TRUE);
1031 USAGE1(str, "xloo(k) [object]");
1032 TK("Xlook: str: "+str);
1033 PIPE_DELETE(pipe_of);
1034 file = pipe_out&&pipe_of ? pipe_of : "";
1035 if(str&&str!="")
1036 {
1037 if((obj=XFindObj(str)))
1038 PrintObj(obj,file);
1039 }
1040 else
1041 {
1042 obj=ENV(cloner);
1043 PrintObj(obj,file);
1044 }
1045 return TRUE;
1046}
1047
1048int Xlpc(string str)
1049{
1050 object obj;
1051 string file, error;
1052 int *ru1, *ru2, time;
1053 mixed res;
1054
1055 SECURE2(TRUE);
1056 USAGE2(str, "xlp(c) <lpc code>");
1057 file=LPC_FILE+".c";
1058 if(file_size(file)>0)
1059 rm(file);
1060 if(obj=find_object(LPC_FILE))
1061 Destruct(obj);
1062 write_file(file,
1063 "#pragma no_warn_missing_return,strong_types,warn_deprecated,rtt_checks\n"
1064 "#include <properties.h>\n"
1065 "#include <thing/properties.h>\n"
1066 "#include <defines.h>\n"
1067 "#include <wizlist.h>\n"
1068 "#include <moving.h>\n"
1069 "#include \"/secure/wizlevels.h\"\n"
1070 +(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
1071 "object get(string str){return previous_object()->XFindObj(str);}\n"+
1072 "mixed eval(mixed me, mixed here){"+str+"}");
1073 if(error=catch(obj=clone_object(file)))
1074 W("Error: "+error[1..0]);
1075 else
1076 {
1077 ru1=rusage();
bugfixd94d0932020-04-08 11:27:13 +02001078 error=catch(res=({mixed})obj->eval(cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +02001079 ru2=rusage();
1080 if(error)
1081 W("Error: "+error[1..]);
1082 else
1083 {
1084 time=ru2[0]-ru1[0]+ru2[1]-ru1[1];
1085 WDLN("Evaluation time: "+(time<0 ? 0 : time)+" ms");
1086 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
1087 if(objectp(res))
1088 variable["result"] = res;
1089 }
1090 }
1091 rm(file);
1092 if(obj)
1093 Destruct(obj);
1094 return TRUE;
1095}
1096
1097int Xman(string str)
1098{
1099 string manpage;
1100 int i, found;
1101
1102 SECURE2(TRUE);
1103 USAGE2(str, "xma(n) <manpage>");
1104 W("Man: ");
1105 for(i=0, found=0; i<sizeof(manpath); i++)
1106 {
1107 manpage=manpath[i]+str;
1108 if(file_size(manpage)>=0)
1109 {
1110 WLN(manpage);
1111 XMoreFile(manpage, FALSE);
1112 found=1;
1113 break;
1114 }
1115 }
1116 if(!found)
1117 WLN("- no help available -");
1118 return TRUE;
1119}
1120
1121int Xmore(string str)
1122{
1123 string *args, file;
1124 int line;
1125
1126 SECURE2(TRUE);
1127 TK("Xmore: str: "+str);
1128 if (!pipe_in)
1129 {
1130 USAGE2(str, "xmor(e) <filename> [start]");
1131 switch(sizeof(args=strip_explode(str, " ")))
1132 {
1133 case 1:
1134 moreoffset=1;
1135 break;
1136 case 2:
1137 sscanf(args[1], "%d", line);
1138 moreoffset= line>0 ? line : 1;
1139 break;
1140 default:
1141 return FALSE;
1142 }
1143 if(file=XFindFile(args[0]))
1144 XMoreFile(file, TRUE);
1145 }
1146 else
1147 {
1148 if(file_size(pipe_if)<0)
1149 {
1150 WDLN("Missing input to xmore");
1151 return TRUE;
1152 }
1153 if (!str||str=="")
1154 line=1;
1155 else if (sscanf(str, "%d", line)!=1)
1156 USAGE3("xmor(e) [start]");
1157 moreoffset= line>0 ? line : 1;
1158 XMoreFile(pipe_if, TRUE);
1159 }
1160 return TRUE;
1161}
1162
1163int Xmove(string str)
1164{
1165 object obj1, obj2;
1166 string what, into;
1167
1168 SECURE2(TRUE);
1169 USAGE2(str, "xmov(e) <object> into <object>");
1170 if((sscanf(str, "%s into %s", what, into)==2)&&
1171 (obj1=XFindObj(what))&&(obj2=XFindObj(into)))
1172 MoveObj(obj1, obj2, FALSE);
1173 return TRUE;
1174}
1175
1176int Xmsg(string str)
1177{
1178 string tmp;
1179
1180 SECURE2(TRUE);
1181 TK("Xmsg: str: "+str);
1182 USAGE1(str, "xms(g) [to <object>|all]");
1183 if(!str||str=="")
1184 {
1185 WDLN("Send message into room");
1186 say("Message from "+CRNAME(cloner)+":\n");
1187 if(pipe_in&&pipe_if)
1188 say(read_file(pipe_if,0,PIPE_MAX));
1189 else
1190 {
1191 WDLN("End message with \".\" or \"**\"");
1192 input_to("XMsgSay");
1193 }
1194 return TRUE;
1195 }
1196 else if(sscanf(str, "to %s", tmp))
1197 {
1198 if(msgto=XFindObj(tmp))
1199 {
1200 PrintShort("Send message to: ", msgto);
1201 tell_object(msgto, "Message from "+CRNAME(cloner)+" to you:\n");
1202 if(pipe_in&&pipe_if)
1203 tell_object(msgto,read_file(pipe_if,0,PIPE_MAX));
1204 else
1205 {
1206 WDLN("End message with \".\" or \"**\"");
1207 input_to("XMsgTell");
1208 }
1209 }
1210 return TRUE;
1211 }
1212 else if(str=="all")
1213 {
1214 WDLN("Send message to all players");
1215 shout("Message from "+CRNAME(cloner)+" to all:\n");
1216 if(pipe_in&&pipe_if)
1217 shout(read_file(pipe_if,0,PIPE_MAX));
1218 else
1219 {
1220 WDLN("End message with \".\" or \"**\"");
1221 input_to("XMsgShout");
1222 }
1223 return TRUE;
1224 }
1225 return FALSE;
1226}
1227
1228int Xmtp(string str)
1229{
1230 int s;
1231 string *strs, opt, dir, file;
1232
1233 SECURE2(TRUE);
1234 USAGE2(str, "xmt(p) [options] <directory> <filename>");
1235 s=sizeof(strs=old_explode(str, " "));
1236 if(s<2)
1237 return FALSE;
1238 else if(s==2)
1239 opt="";
1240 else
1241 opt=implode(strs[0..s-3], " ");
bugfixd94d0932020-04-08 11:27:13 +02001242 if(!(dir="/"+({int})MASTER->valid_read(strs[s-2], geteuid(),
MG Mud User88f12472016-06-24 23:31:02 +02001243 "get_dir", ME))) {
1244 WDLN("No permission to open directory for reading");
1245 return TRUE;
1246 }
bugfixd94d0932020-04-08 11:27:13 +02001247 if(!(file="/"+({int})MASTER->valid_write(strs[s-1], geteuid(),
MG Mud User88f12472016-06-24 23:31:02 +02001248 "write_file", ME))) {
1249 WDLN("No permission to open script file for writing");
1250 return TRUE;
1251 }
1252 if(file_size(dir)!=-2 || file_size(file)==-2)
1253 return FALSE;
1254 XmtpScript(dir, file, opt);
1255 WDLN("Done");
1256 return TRUE;
1257}
1258
1259int Xproc(string str)
1260{
MG Mud User88f12472016-06-24 23:31:02 +02001261 string *strs;
1262
1263 SECURE2(TRUE);
1264 USAGE1(str, "xproc [-c] [-l] [-m] [-u] [-v]");
1265
1266 if(file_size(TOOL_PATH+"/proc")!=-2)
1267 {
1268 WLN("Sorry, no /proc information available!");
1269 return TRUE;
1270 }
1271
Arathorn65b45e02022-02-07 22:03:57 +01001272 if(!str||str==""||!(sizeof(strs=old_explode(str, " "))))
MG Mud User88f12472016-06-24 23:31:02 +02001273 {
1274 WLN("Load averages:");
1275 cat(TOOL_PATH+"/proc/loadavg");
1276 return TRUE;
1277 }
1278
Arathorn65b45e02022-02-07 22:03:57 +01001279 while(sizeof(strs))
MG Mud User88f12472016-06-24 23:31:02 +02001280 {
1281 switch(strs[0])
1282 {
1283 case "-c":
1284 WLN("CPU info:");
1285 cat(TOOL_PATH+"/proc/cpuinfo");
1286 break;
1287 case "-l":
1288 WLN("Load averages:");
1289 cat(TOOL_PATH+"/proc/loadavg");
1290 break;
1291 case "-m":
1292 WLN("Memory usage:");
1293 cat(TOOL_PATH+"/proc/meminfo");
1294 break;
1295 case "-u":
1296 WLN("Uptime:");
1297 cat(TOOL_PATH+"/proc/uptime");
1298 break;
1299 case "-v":
1300 WLN("Version:");
1301 cat(TOOL_PATH+"/proc/version");
1302 break;
1303 default:
1304 WLN("Unknown option: "+strs[0]);
1305 }
1306 strs=strs[1..];
1307 }
1308 return TRUE;
1309}
1310
1311int Xprof(string str)
1312{
1313 string *funcs, inh, tmp;
1314 mixed *data, *d;
1315 mapping xpr;
1316 object obj;
1317 int i, rn;
1318
1319 SECURE2(TRUE);
1320 USAGE2(str, "xprof <<-c>|<-C> <file>>|<object>");
1321 if(str[0..2]=="-c "||str[0..2]=="-C ")
1322 {
1323 rn=(str[1]=='C');
1324 if(str=XFindFile(str[3..]))
1325 {
1326 inh=str=str[0..<3];
1327 if(obj=find_object(inh))
1328 Destruct(obj);
1329 if(catch(call_other(inh,"???")))
1330 return TRUE;
1331 obj=find_object(inh);
1332 if(rn)
1333 {
1334 inh+=".xprof.c";
1335 rm(inh);
1336 str+=".c";
1337 rename(str, inh);
1338 }
1339 else
1340 {
1341 str=XPROF_FILE;
1342 rm(str);
1343 }
1344 tmp="inherit \""+inh+"\";\n#include \""+XPROF_MACRO+"\"\n";
1345 funcs=m_indices(mkmapping(functionlist(obj, 0x08000001)))-({"__INIT"});
1346 for(i=sizeof(funcs); i--;)
1347 tmp+="F("+funcs[i]+",\""+funcs[i]+"\","+
1348 "(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9))\n";
1349 write_file(str, tmp);
1350 WDLN("Done");
1351 }
1352 }
1353 else if(obj=XFindObj(str))
1354 {
bugfixd94d0932020-04-08 11:27:13 +02001355 if(xpr=({mixed})obj->__query_xprof_data__())
MG Mud User88f12472016-06-24 23:31:02 +02001356 {
1357 funcs=m_indices(xpr);
1358 data=m_values(xpr);
1359 rm(TMP_FILE);
1360 str="Evaluation cost per function:\nNAME "+
1361 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1362 for(i=sizeof(funcs); i--;)
1363 {
1364 if(d=data[i]) {
1365 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1366 ARIGHT(" "+d[1],10,".") +" "+ARIGHT(" "+d[3],10,".")+" | "+
1367 ARIGHT(" "+d[1]/d[0],9,".") +" "+ARIGHT(" "+d[3]/d[0],9,".");
1368 }
1369 }
1370 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1371 write_file(TMP_FILE,str);
1372 str="\nElapsed time per function:\nNAME "+
1373 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1374 funcs=m_indices(xpr);
1375 for(i=sizeof(funcs); i--;)
1376 {
1377 if(d=data[i])
1378 {
1379 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1380 ARIGHT(" "+(d[2]+5)/10+"ms",10,".")+" "+
1381 ARIGHT(" "+(d[4]+5)/10+"ms",10,".")+" | "+
1382 ARIGHT(" "+d[2]/d[0]+"us",9,".")+" "+
1383 ARIGHT(" "+d[4]/d[0]+"us",9,".");
1384 }
1385 }
1386 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1387 write_file(TMP_FILE,str);
1388 XMoreFile(TMP_FILE, FALSE);
1389 }
1390 else
1391 WDLN("No profiling information available");
1392 }
1393 return TRUE;
1394}
1395
1396int Xprops(string str)
1397{
Arathorn65b45e02022-02-07 22:03:57 +01001398 int flag;
MG Mud User88f12472016-06-24 23:31:02 +02001399 object obj;
1400 string *tmp;
1401
1402 SECURE2(TRUE);
1403 USAGE2(str, "xprop(s) [-f|-m] <object>");
1404 TK("Xprops: str: "+str);
1405 tmp=old_explode(str," ");
1406 switch(tmp[0])
1407 {
1408 case "-f":
1409 {
1410 flag = 1;
1411 tmp=tmp[1..];
1412 break;
1413 }
1414 case "-m":
1415 {
1416 flag = 2;
1417 tmp=tmp[1..];
1418 break;
1419 }
1420 }
1421 str=implode(tmp," ");
1422 if((obj=XFindObj(str)))
1423 DumpProperties(obj,flag);
1424 return TRUE;
1425}
1426
1427int Xquit(string str)
1428{
1429 SECURE2(TRUE);
1430 USAGE1(str, "xqu(it)");
1431 str=object_name(ENV(cloner));
1432 if(member(str, '#')<0)
1433 cloner->set_home(str);
1434 cloner->quit();
1435 return TRUE;
1436}
1437
1438int Xscan(string str)
1439{
1440 SECURE2(TRUE);
1441 USAGE1(str, "xsc(an)");
1442 W("Destructed variable(s): ");
1443 string* oldvars=m_indices(variable);
1444 VarCheck(FALSE);
1445 string* desvars=oldvars-m_indices(variable);
1446 desvars = map(desvars, function string (string k)
1447 {return "$"+k;} );
1448 W(CountUp(desvars));
1449 WLN("");
1450 return TRUE;
1451}
1452
1453int Xset(string str)
1454{
MG Mud User88f12472016-06-24 23:31:02 +02001455 mixed obj;
1456 string name, tmp;
1457
1458 SECURE2(TRUE);
1459 USAGE1(str, "xse(t) [$<name>=<object>]");
1460 if(str) {
1461 if(member(({"$me","$m","$here","$h"}),str)!=-1)
1462 WDLN("Sorry, this is a reserved variable ["+str+"]");
1463 else if(sscanf(str, "$%s=%s", name, tmp))
1464 {
1465 if(obj=XFindObj(tmp))
1466 {
1467 variable[name] = obj;
1468 WLN(" $"+name+"="+ObjFile(obj));
1469 }
1470 }
1471 else
1472 return FALSE;
1473 }
1474 else
1475 {
1476 VarCheck(FALSE);
1477 WLN("Current settings:");
1478 foreach(string key, mixed val : variable)
1479 {
1480 if (val)
1481 WLN(" $"+key+"="+ObjFile(val));
1482 else
1483 m_delete(variable, key);
1484 }
1485 WLN(" $me="+ObjFile(cloner));
1486 WLN(" $here="+ObjFile(ENV(cloner)));
1487 }
1488 return TRUE;
1489}
1490
1491int Xsh(string str)
1492{
1493 SECURE2(TRUE);
1494 USAGE1(str, "xsh <filename>");
1495 if(scriptline)
1496 {
1497 WDLN("Cannot execute another script file until last execution has ended");
1498 return TRUE;
1499 }
1500 if(!(str=XFindFile(str)))
1501 return TRUE;
1502 str=read_file(str, 1, 1000);
1503 if(!(scriptline=old_explode(str, "\n")))
1504 {
1505 WDLN("Bad script file");
1506 return TRUE;
1507 }
1508 scriptsize=sizeof(scriptline);
1509 XExecFile(NULL);
1510 return TRUE;
1511}
1512
1513int Xsort(string str)
1514{
1515 string *tmp,file;
1516 int s,reverse;
1517
1518 SECURE2(TRUE);
1519 TK("Xsort: str: "+str);
1520 if(!pipe_in)
1521 {
1522 USAGE2(str, "xso(rt) [-r] [file]");
1523 if(!(tmp=old_explode(str, " "))||(s=sizeof(tmp))>2)
1524 return FALSE;
1525 if(tmp[0]=="-r")
1526 if(s==1)
1527 return FALSE;
1528 else
1529 {
1530 reverse=TRUE;
1531 tmp=tmp[1..];
1532 }
1533 else if(s>1)
1534 return FALSE;
1535 if(!(file=XFindFile(tmp[0])))
1536 {
1537 WDLN("Can't find file");
1538 return TRUE;
1539 }
1540 }
1541 else
1542 {
1543 if(str&&str!="")
1544 if(str=="-r")
1545 reverse=TRUE;
1546 else
1547 USAGE3("xso(rt) [-r]");
1548 if (file_size(file=pipe_if)<0)
1549 {
1550 WDLN("Missing input to xsort");
1551 return TRUE;
1552 }
1553 }
1554 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
1555 if(pipe_in&&pipe_if==PIPE_FILE)
1556 rm(PIPE_FILE);
1557 tmp=sort_array(tmp,reverse?#'<:#'>);
1558 if (pipe_out&&pipe_of)
1559 write_file(pipe_of,implode(tmp,"\n")+"\n");
1560 else
1561 WDLN(implode(tmp,"\n"));
1562 return TRUE;
1563}
1564
1565int Xtail(string str)
1566{
1567 string *tmp,file,sign;
1568 int lines;
1569
1570 if (!str) {
1571 WDLN("Missing input to xtail");
1572 return TRUE;
1573 }
1574
1575 sign="-";
1576 lines=10;
1577 SECURE2(TRUE);
1578 TK("Xtail: str: "+str);
1579 if(!pipe_in)
1580 {
1581 if(sscanf(str,"-%d %s",lines,file)==2)
1582 sign="-";
1583 else if(sscanf(str,"+%d %s",lines,file)==2)
1584 sign="+";
1585 else
1586 file=str;
1587
1588 if(!(file=XFindFile(file)))
1589 {
1590 WDLN("Can't find file");
1591 return TRUE;
1592 }
1593 }
1594 else
1595 {
1596 if(sscanf(str,"-%d",lines)==1)
1597 sign="-";
1598 else if(sscanf(str,"+%d",lines)==1)
1599 sign="+";
1600 if (file_size(file=pipe_if)<0)
1601 {
1602 WDLN("Missing input to xtail");
1603 return TRUE;
1604 }
1605 }
1606
1607 if(sign=="-")
1608 {
1609 if(!lines)
1610 return TRUE;
1611 }
1612
1613 if(file_size(file)>50000)
1614 {
1615 WDLN("File too large");
1616 return TRUE;
1617 }
1618
1619 if(sign=="+")
1620 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[lines..];
1621 else
1622 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[<lines..];
1623 if(pipe_in&&pipe_if==PIPE_FILE)
1624 rm(PIPE_FILE);
1625 if (pipe_out&&pipe_of)
1626 write_file(pipe_of,implode(tmp,"\n")+"\n");
1627 else
1628 WLN(implode(tmp,"\n"));
1629 return TRUE;
1630}
1631
1632int Xtool(string str)
1633{
1634 int m;
1635 string tmp;
1636 object obj;
1637
1638 SECURE2(TRUE);
1639 TK("Xtool: str: "+str);
1640 USAGE1(str, "xto(ol) [update|first=<on|off>|protect=<on|off>|"+
1641 "invcheck=<on|off>|\n"+
1642 "\t\tvarcheck=<on|off>|scanchk=<on|off>|short=<on|off>|\n"+
1643 "\t\techo=<on|off>|more=<amount>|kill|news|save|load|reset]");
1644 if(str&&str!="")
1645 {
1646 if(sscanf(str, "more=%d", m))
1647 {
1648 if(m<5)
1649 WDLN("Sorry, amount of lines should be more then 5");
1650 else
1651 {
1652 WDLN("Setting amount of displayed lines to "+m);
1653 morelines=m;
1654 }
1655 }
1656 else
1657 switch(str)
1658 {
1659 case "update":
1660 if(obj=find_object(TOOL_PATH))
1661 Destruct(obj);
1662 if(catch(obj=clone_object(TOOL_PATH)))
1663 WLN("Updating "+TOOL_TITLE+" failed!");
1664 else
1665 obj->update_tool(AUTOLOAD_ARGS, cloner);
1666 return TRUE;
MG Mud User88f12472016-06-24 23:31:02 +02001667 case "first=on":
1668 MODE_ON(MODE_FIRST);
1669 move(cloner);
1670 WDLN("Automatic moving into pole position of inventory turned on");
1671 break;
1672 case "first=off":
1673 MODE_OFF(MODE_FIRST);
1674 WDLN("Automatic moving into pole position of inventory turned off");
1675 break;
1676 case "protect=on":
1677 MODE_ON(MODE_PROTECT);
1678 WDLN("Protection from forces and illegal moves turned on");
1679 break;
1680 case "protect=off":
1681 MODE_OFF(MODE_PROTECT);
1682 WDLN("Protection from forces and illegal moves turned off");
1683 break;
1684 case "invcheck=on":
1685 MODE_ON(MODE_INVCHECK);
1686 WDLN("Automatic checking for new objects in inventory turned on");
1687 break;
1688 case "invcheck=off":
1689 MODE_OFF(MODE_INVCHECK);
1690 WDLN("Automatic checking for new objects in inventory turned off");
1691 break;
1692 case "varcheck=on":
1693 MODE_ON(MODE_VARCHECK);
1694 VarCheck(TRUE);
1695 WDLN("Automatic variable checking turned on");
1696 break;
1697 case "varcheck=off":
1698 MODE_OFF(MODE_VARCHECK);
1699 WDLN("Automatic variable checking turned off");
1700 break;
1701 case "scanchk=on":
1702 MODE_ON(MODE_SCANCHK);
1703 WDLN("Scan check turned on");
1704 break;
1705 case "scanchk=off":
1706 MODE_OFF(MODE_SCANCHK);
1707 WDLN("Scan check turned off");
1708 break;
1709 case "echo=on":
1710 MODE_ON(MODE_ECHO);
1711 WDLN("Echoing of multiple command execution turned on");
1712 break;
1713 case "echo=off":
1714 MODE_OFF(MODE_ECHO);
1715 WDLN("Echoing of multiple command execution turned off");
1716 break;
1717 case "short=on":
1718 MODE_ON(MODE_SHORT);
1719 WDLN("Use of short descriptions turned on");
1720 break;
1721 case "short=off":
1722 MODE_OFF(MODE_SHORT);
1723 WDLN("Use of short descriptions turned off");
1724 break;
1725 case "kill":
1726 WDLN(TOOL_NAME+" selfdestructs");
1727 destruct(ME);
1728 break;
1729 case "news":
1730 XMoreFile(TOOL_NEWS, FALSE);
1731 break;
1732 case "reset":
1733 WDLN("Resetting "+TOOL_TITLE);
1734 ME->__INIT();
1735 break;
1736 case "load":
1737 if(file_size(SAVE_FILE+".o")>0)
1738 {
1739 WDLN("Loading "+TOOL_TITLE+" settings");
1740 restore_object(SAVE_FILE);
1741 }
1742 else
1743 WDLN("Sorry, cannot find file to load settings");
1744 break;
1745 case "save":
1746 WDLN("Saving "+TOOL_TITLE+" settings");
1747 save_object(SAVE_FILE);
1748 break;
1749 default:
1750 return FALSE;
1751 }
1752 }
1753 else
1754 {
1755 WLN(TOOL_TITLE+" settings:");
1756 tmp= (" first .... = "+(MODE(MODE_FIRST) ? "on\n" : "off\n"));
1757 tmp+=(" protect .. = "+(MODE(MODE_PROTECT) ? "on\n" : "off\n"));
1758 tmp+=(" invcheck . = "+(MODE(MODE_INVCHECK) ? "on\n" : "off\n"));
1759 tmp+=(" varcheck . = "+(MODE(MODE_VARCHECK) ? "on\n" : "off\n"));
1760 tmp+=(" scanchk .. = "+(MODE(MODE_SCANCHK) ? "on\n" : "off\n"));
1761 tmp+=(" echo ..... = "+(MODE(MODE_ECHO) ? "on\n" : "off\n"));
1762 tmp+=(" short .... = "+(MODE(MODE_SHORT) ? "on\n" : "off\n"));
1763 tmp+=(" more ..... = "+morelines);
1764 WLN(sprintf("%-80#s", tmp));
1765 }
1766 return TRUE;
1767}
1768
1769int Xtrace(string str)
1770{
1771 string file;
1772 object obj;
1773
1774 SECURE2(TRUE);
1775 USAGE1(str, "xtrac(e) <object>");
1776 if(!str||str=="")
1777 {
1778 trace(0);
1779 WDLN("Ending trace ["+short_path("/"+traceprefix(0))+"]");
1780 }
1781 else if(obj=XFindObj(str))
1782 {
1783 PrintShort("Tracing: ", obj);
1784 file=object_name(obj);
1785 file=file[1..<1];
1786 traceprefix(file);
1787 trace(TRACE_LEVEL);
1788 }
1789 return TRUE;
1790}
1791
1792int Xtrans(string str)
1793{
1794 object obj;
1795
1796 SECURE2(TRUE);
1797 USAGE2(str, "xtran(s) <object>");
1798 if((obj=XFindObj(str))&&ENV(obj))
1799 {
1800 tell_room(ENV(obj), CRNAME(obj)+" vanishes.\n");
1801 tell_room(ENV(cloner), CRNAME(obj)+
1802 " is teleported into this room by "+CRNAME(cloner)+".\n");
1803 MoveObj(obj, ENV(cloner), TRUE);
1804 tell_object(obj, "You've been teleported to "+CRNAME(cloner)+".\n");
1805 }
1806 else
1807 WDLN("Failed to teleport object");
1808 return TRUE;
1809}
1810
1811int Xupdate(string str)
1812{
1813 object obj;
1814 string file;
1815
1816 SECURE2(TRUE);
1817 USAGE2(str, "xup(date) <filename>");
1818 if(!(file=XFindFile(str)))
1819 return TRUE;
1820 if(file[<2.. <1]==".c")
1821 file=file[0.. <3];
1822 if((obj=XFindObj(file))&&(obj=find_object(pure_file_name(obj))))
1823 {
1824 PrintShort("Updating: ", obj);
1825 Destruct(obj);
1826 }
1827 else
1828 WDLN("Object not found");
1829 return TRUE;
1830}
1831
1832int Xuptime(string str)
1833{
1834 return TRUE;
1835}
1836
1837int Xwc(string str)
1838{
1839 string file;
1840 string tmp, *tmp2;
1841 int i, chars, words, lines, nchars, nwords, nlines;
1842
1843 SECURE2(TRUE);
1844 TK("Xwc: str: "+str);
1845 chars=words=lines=FALSE;
1846 if(!pipe_in)
1847 {
1848 USAGE2(str, "xwc [-cwl] <file>");
1849 if(str[0]=='-')
1850 {
1851 while((str=str[1..])[0]!=' '&&sizeof(str))
1852 switch(str[0])
1853 {
1854 case 'c':
1855 chars=TRUE;
1856 break;
1857 case 'w':
1858 words=TRUE;
1859 break;
1860 case 'l':
1861 lines=TRUE;
1862 break;
1863 default:
1864 return FALSE;
1865 }
1866 str=str[1..];
1867 }
1868 if(!(file=XFindFile(str)))
1869 {
1870 WDLN("Can't find file");
1871 return TRUE;
1872 }
1873 }
1874 else
1875 {
1876 USAGE1(str,"xwc [-cwl]");
1877 if(str)
1878 if(str[0]=='-')
1879 {
1880 while((str=str[1..])[0]!=' '&&sizeof(str))
1881 switch(str[0])
1882 {
1883 case 'c':
1884 chars=TRUE;
1885 break;
1886 case 'w':
1887 words=TRUE;
1888 break;
1889 case 'l':
1890 lines=TRUE;
1891 break;
1892 default:
1893 return FALSE;
1894 }
1895 }
1896 else
1897 return FALSE;
1898 if(file_size(file=pipe_if)<0)
1899 {
1900 WDLN("Missing input to xwc");
1901 return TRUE;
1902 }
1903 }
1904 if(!(chars|words|lines))
1905 chars=words=lines=TRUE;
1906 nlines=nwords=nchars=0;
1907 tmp=read_file(file,0,PIPE_MAX);
1908 tmp2=explode(tmp,"\n");
1909 if(lines)
1910 {
1911 nlines=sizeof(tmp2);
1912 if(tmp2[<1]==""&&nlines>1)
1913 nlines--;
1914 }
1915 if(words)
1916 for(i=sizeof(tmp2)-1;i>=0;i--)
1917 {
1918 TK(sprintf("%O",tmp2[i]));
1919 if(tmp2[i]!="")
1920 nwords+=sizeof(regexplode(tmp2[i],"[ ]")-({""," "," "}));
1921 TK(sprintf("%O",regexplode(tmp2[i],"[ ]")-({""," "," "})));
1922 TK("nwords: "+nwords);
1923 }
1924 if(chars)
1925 for(i=sizeof(tmp2)-1;i>=0;i--)
1926 nchars+=sizeof(tmp2[i])+1;
1927 tmp2=0;
1928 tmp="";
1929 if(lines)
1930 tmp+=sprintf("%7d",nlines)+" ";
1931 if(words)
1932 tmp+=sprintf("%7d",nwords)+" ";
1933 if(chars)
1934 tmp+=sprintf("%7d",nchars)+" ";
1935 if(file!=pipe_if)
1936 tmp+=file;
1937 WLN(tmp);
1938 return TRUE;
1939}
1940
1941int cmdavg_compare(string a, string b)
1942{
1943 int x,y;
Arathorn65b45e02022-02-07 22:03:57 +01001944 sscanf(a,"%~s cmdavg: %d",x);
1945 sscanf(b,"%~s cmdavg: %d",y);
MG Mud User88f12472016-06-24 23:31:02 +02001946 return x==y?0:(x>y?1:-1);
1947}
1948
1949int Xwho(string opt)
1950{
Arathorn65b45e02022-02-07 22:03:57 +01001951 string *strs,func;
MG Mud User88f12472016-06-24 23:31:02 +02001952
1953 SECURE2(TRUE);
1954 TK("Xwho: opt: \""+opt+"\"");
1955 USAGE1(opt, "xwh(o) [mail|ip|race|guild|domain|stats|snoop]");
1956 func="string_compare";
1957 if(!opt||opt=="")
1958 strs=map(users(), "PlayerWho", ME);
1959 else
1960 switch(opt)
1961 {
1962 case "mail":
1963 strs=map(users(), "PlayerMail", ME, TRUE);
1964 break;
1965 case "ip":
1966 strs=map(users(), "PlayerIP", ME, TRUE);
1967 break;
1968 case "race":
1969 case "guild":
1970 strs=map(users(), "PlayerRace", ME, TRUE);
1971 break;
1972 case "domain":
1973 strs=map(users(), "PlayerDomain", ME, TRUE);
1974 break;
1975 case "stat":
1976 case "stats":
1977 strs=map(users(), "PlayerStats", ME, TRUE);
1978 break;
1979 case "snoop":
1980 strs=map(users(), "PlayerSnoop", ME, TRUE);
1981 break;
1982 case "cmdavg":
1983 strs=map(users(), "PlayerCmdAvg", ME, TRUE);
1984 func="cmdavg_compare";
1985 break;
1986 default:
1987 return FALSE;
1988 }
1989 strs=sort_array(strs, func, ME);
1990 if(pipe_out&&pipe_of)
1991 write_file(pipe_of,implode(strs,"\n")+"\n");
1992 else
1993 WLN(implode(strs,"\n"));
1994 return TRUE;
1995}