blob: 83504b4a4306eb756a458a63f06e987e3d781a27 [file] [log] [blame]
/*
* MGtool-1.0
* File: toolcmds.c
* Maintainer: Kirk@MorgenGrauen
*/
/*------------------------------------------*/
/* the original Xtool is copyrighted by Hyp */
/*------------------------------------------*/
#include "tool.h"
/*----------------------------------------------------------------------
* command functions
*/
int Xcall(string str)
{
object obj, callobj;
string file, callstr, callfun, callexpr, error, errlog;
int *ru1, *ru2, xtime;
mixed res;
SECURE2(TRUE);
USAGE2(str, "xcall <object>-><function>(<arguments>)");
TK("Xcall: str: "+(str?str:"(NULL)"));
if(sscanf(str, "%s->%s(%s", callstr, callfun, callexpr)!=3)
return FALSE;
if(!(callobj=XFindObj(callstr)))
return TRUE;
else
{
#if 0
write_file(TOOL_LOG,
sprintf("%s (%s) xcall %s (env: %s)\n",ctime(time()),
getuid(cloner),str,object_name(environment(cloner))));
#endif
file=LPC_FILE+".c";
if(file_size(file)>0)
rm(file);
if(obj=find_object(LPC_FILE))
Destruct(obj);
obj=0;
write_file(file,
"#include <properties.h>\n"+
"#include <thing/properties.h>\n"+
"#include <defines.h>\n"+
"#include <wizlist.h>\n"+
"#include <moving.h>\n"+
"#include \"/secure/wizlevels.h\"\n"+
(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
"mixed get(string str){return previous_object()->XFindObj(str);}\n"+
"mixed eval(object obj,mixed me,mixed here){return obj->"+callfun+"("+callexpr+";}\n");
errlog = ERR_FILE;
if(file_size(errlog)>0)
rm(errlog);
if(error=catch((LPC_FILE)->__nixgibts__()))
W("Error: "+error[1..]);
else
{
obj=find_object(LPC_FILE);
ru1=rusage();
error=catch(res=(mixed)obj->eval(callobj, cloner, ENV(cloner)));
ru2=rusage();
if(error)
W("Error: "+error[1..]);
else
{
xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
PIPE_DELETE(pipe_of);
if(pipe_out&&pipe_of)
write_file(pipe_of,mixed_to_string(res, MAX_RECURSION)+"\n");
else
WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
if(objectp(res))
m_add(variable, "result", res);
}
}
rm(file);
}
if(obj) Destruct(obj);
return TRUE;
}
int Xcallouts(string str)
{
object obj;
mixed callouts, args;
string fun, tmp, file;
int delay, i, s;
SECURE2(TRUE);
TK("Xcallouts: str: "+(str?str:"(NULL)"));
if(!pipe_out)
{
USAGE1(str, "xcallo(uts) [search pattern]");
file=TMP_FILE;
if(file_size(file)>0)
rm(file);
if(!str)
str="^\\[~/";
else if(!regexp(({"dummy"}), str))
{
WDLN("Bad regular expression");
return TRUE;
}
}
else
{
USAGE1(str, "xcallo(uts)");
if(str&&str!="")
{
WDLN("More arguments than expected");
return TRUE;
}
}
callouts=call_out_info();
s=sizeof(callouts);
PIPE_DELETE(pipe_of);
for(i=0; i<s; i++)
{
if(callouts[i]&&pointerp(callouts[i]))
{
tmp=sprintf("%O %Os %O (%s)",callouts[i][0],callouts[i][2],
callouts[i][1],(sizeof(callouts[i])>3?
mixed_to_string(callouts[i][3],
MAX_RECURSION):"0"));
if(pipe_out&&pipe_of)
write_file(pipe_of,tmp+"\n");
else
if(sizeof(regexp(({tmp}), str)))
WLN(tmp);
}
}
return TRUE;
}
int Xcat(string str)
{
string *tmp,file;
int s;
SECURE2(TRUE);
TK("Xcat: str: "+str);
if(!pipe_in)
{
USAGE2(str, "xcat <file>");
if(!(file=XFindFile(str)))
{
WDLN("Can't find file");
return TRUE;
}
}
else
{
if(str&&str!="-")
USAGE3("xcat -");
if (file_size(file=pipe_if)<0)
{
WDLN("Missing input to xcat");
return TRUE;
}
}
tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
if(pipe_in&&pipe_if==PIPE_FILE)
rm(PIPE_FILE);
if (pipe_out&&pipe_of)
write_file(pipe_of,implode(tmp,"\n")+"\n");
else
WLN(implode(tmp,"\n"));
return TRUE;
}
int Xcd(string str)
{
object dest;
string path;
SECURE2(TRUE);
USAGE1(str, "xcd [object]");
TK("Xcd: str: "+(str?str:"(NULL)"));
if(!str)
{
if(!(path=(string)cloner->QueryProp("start_home")))
path="/";
}
else if((dest=XFindObj(str,1)))
path="/"+implode(old_explode(object_name(dest),"/")[0..<2],"/");
else
path="";
TK("Xcd: path: "+(path?path:"(NULL)"));
if(!sizeof(path))
path=str;
PL->_cd(path);
return TRUE;
}
int Xclean(string str)
{
object env;
SECURE2(TRUE);
USAGE1(str, "xcle(an) [object]");
TK("Xclean: str: "+(str?str:"(NULL)"));
if(!str)
env=ENV(cloner);
if(env||(env=XFindObj(str)))
{
PrintShort("Cleaning: ", env);
filter(filter(all_inventory(env), #'is_not_player),//'
"Destruct", ME);
}
return TRUE;
}
int Xclone(string str)
{
object obj;
string file, errlog, error;
SECURE2(TRUE);
USAGE2(str, "xclo(ne) <filename>");
if(!(file=XFindFile(str))) return TRUE;
errlog=ERR_FILE;
if(file_size(errlog)>0) rm(errlog);
WLN("Clone: "+short_path(file));
if(!(error=catch(obj=clone_object(file))))
{
m_add(variable, "clone", obj);
if(!MoveObj(obj, ENV(cloner), TRUE))
WDLN("Cannot move object into this room");
else if(!obj->QueryNoGet())
{
if(!MoveObj(obj, cloner, TRUE))
WDLN("Cannot move object into your inventory");
}
}
else
W("Error: "+error[1..]);
return TRUE;
}
int Xuclone(string str)
{
object obj;
string file, errlog, error;
SECURE2(TRUE);
USAGE2(str, "xuclo(ne) <filename>");
if(!(file=XFindFile(str))) return TRUE;
errlog=ERR_FILE;
if(file_size(errlog)>0) rm(errlog);
if(obj=find_object(file)) {
Destruct(obj);
WLN("Update and clone: "+short_path(file));
}
else
WLN("Clone: "+short_path(file));
if(!(error=catch(obj=clone_object(file))))
{
variable["clone"] = obj;
if(!MoveObj(obj, ENV(cloner), TRUE))
WDLN("Cannot move object into this room");
else if(!obj->QueryNoGet())
{
if(!MoveObj(obj, cloner, TRUE))
WDLN("Cannot move object into your inventory");
}
}
else
W("Error: "+error[1..]);
return TRUE;
}
int Xcmds(string str)
{
object obj;
mixed *cmds;
int i, s;
SECURE2(TRUE);
USAGE1(str, "xcm(ds) [object]");
TK("Xcmds: str: "+(str?str:"(NULL)"));
if(!str)
obj=ENV(cloner);
else if(!(obj=XFindObj(str)))
{
WDLN("Can't find object");
return TRUE;
}
s=sizeof(cmds=query_actions(cloner,1|2|4|8|16));
PIPE_DELETE(pipe_of);
for(i=0; i<s; i+=5)
if(cmds[i+3]==obj)
if(pipe_out&&pipe_of)
write_file(pipe_of,ALEFT(cmds[i]+" ", 15, ".")+
(cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()\n");
else
WLN(ALEFT(cmds[i]+" ", 15, ".")+
(cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()");
return TRUE;
}
int Xdbg(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xdb(g) <object>");
TK("Xdbg: str: "+(str?str:"(NULL)"));
if((obj=XFindObj(str)))
{
debug_info(1, obj);
debug_info(0, obj);
}
return TRUE;
}
int Xdclean(string str)
{
object env;
SECURE2(TRUE);
USAGE1(str, "xdc(lean) [object]");
TK("Xdclean: str: "+(str?str:"(NULL)"));
if(!str)
env=ENV(cloner);
if(env||(env=XFindObj(str)))
{
PrintShort("Deep cleaning: ", env);
filter(filter(all_inventory(env), #'is_not_player, ME),//'
"DeepClean", ME);
}
return TRUE;
}
int Xddes(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xdd(es) <object>");
TK("Xddes: str: "+(str?str:"(NULL)"));
if((obj=XFindObj(str)))
{
PrintShort("Deep destruct: ", obj);
filter(deep_inventory(obj), "Destruct", ME);
Destruct(obj);
}
return TRUE;
}
int Xdes(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xde(s) <object>");
TK("Xdes: str: "+(str?str:"(NULL)"));
if((obj=XFindObj(str)))
{
PrintShort("Destruct: ",obj);
Destruct(obj);
}
return TRUE;
}
int Xdlook(string str)
{
object obj;
SECURE2(TRUE);
USAGE1(str, "xdl(ook) [object]");
TK("Xdlook: str: "+(str?str:"(NULL)"));
if(!str)
obj=cloner;
if(obj||(obj=XFindObj(str)))
{
PIPE_DELETE(pipe_of);
DeepPrintShort(obj,NULL,NULL,(pipe_out&&pipe_of)?pipe_of:"");
}
return TRUE;
}
int Xdo(string str)
{
int i, n, s;
string *strs, cmd;
SECURE2(TRUE);
USAGE2(str, "xdo [<number1>#]<command1>[;[<number2>#]<command2>] ...");
if(!str||str==""||!(s=sizeof(strs=strip_explode(str, ";"))))
return FALSE;
for(i=0; i<s; i++)
{
if(strs[i])
{
switch(sscanf(strs[i], "%d#%s", n, cmd))
{
case 0:
if(!Command(strs[i])) return TRUE;
break;
case 1:
if(cmd&&(!Command(cmd))) return TRUE;
break;
case 2:
n= n<1 ? 1 : n;
if(cmd)
{
while(n--)
if(!Command(cmd)) return TRUE;
}
break;
}
}
}
return TRUE;
}
int Xdupdate(string str)
{
int i, s;
object obj;
string file, *list;
SECURE2(TRUE);
USAGE2(str, "xdu(pdate) <filename>");
if(!(file=XFindFile(str)))
return TRUE;
if(file[<2..<1]==".c")
file=file[0..<3];
if(obj=XFindObj(file))
{
PrintShort("Deep updating: ", obj);
list=inherit_list(obj);
for(s=sizeof(list); i<s; i++)
{
if(obj=find_object(list[i]))
Destruct(obj);
}
}
return TRUE;
}
int Xecho(string str)
{
TK("Xecho: str: "+(str?str:"(NULL)"));
WLN(str);
return TRUE;
}
int Xeval(string str)
{
object obj;
string file, error;
int *ru1, *ru2, xtime;
mixed res;
SECURE2(TRUE);
USAGE2(str, "xev(al) <expression>");
file=LPC_FILE+".c";
if(file_size(file)>0)
rm(file);
if(obj=find_object(LPC_FILE))
Destruct(obj);
#if 0
write_file(TOOL_LOG,
sprintf("%s (%s) xeval %s\n",
ctime(time()),getuid(cloner),str));
#endif
write_file(file,
"#include <properties.h>\n"+
"#include <thing/properties.h>\n"+
"#include <defines.h>\n"+
"#include <wizlist.h>\n"+
"#include <moving.h>\n"+
"#include \"/secure/wizlevels.h\"\n"+
(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
"get(str){return previous_object()->XFindObj(str);}\n"+
"eval(me,here){return "+str+";}");
if(error=catch(obj=clone_object(file)))
W("Error: "+error[1..]);
else
{
ru1=rusage();
error=catch(res=(mixed)obj->eval(cloner, ENV(cloner)));
ru2=rusage();
if(error)
W("Error: "+error[1..]);
else
{
xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
PIPE_DELETE(pipe_of);
if(pipe_out&&pipe_of)
write_file(pipe_of,mixed_to_string(res,MAX_RECURSION)+"\n");
else
WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
if(objectp(res))
variable["result"] = res;
}
}
rm(file);
if(obj)
Destruct(obj);
return TRUE;
}
int Xforall(string str)
{
int i, s, t, u;
string pat, cmd, arg, *strs, *files, fh, fr, fe, ft, ff;
SECURE2(TRUE);
USAGE2(str, "xfo(rall) <filepattern> <command>");
if(sscanf(str, "%s %s", pat, arg)!=2)
return FALSE;
files=long_get_dir(pat, FALSE);
if(!(s=sizeof(files)))
{
WDLN("No matching files found");
return TRUE;
}
strs=old_explode(files[0], "/");
fh="/";
if(t=sizeof(strs)-1)
fh+=implode(strs[0..t-1], "/");
for(i=0; i<s; i++)
{
ft=old_explode(files[i], "/")[t];
if((u=sizeof(strs=old_explode(ft, ".")))&&--u)
{
ff=implode(strs[0..u-1], ".");
fr=fh+"/"+ff;
fe=strs[u];
}
else
{
fe="";
ff=ft;
fr=files[i];
}
cmd=string_replace(arg, "!!", files[i]);
cmd=string_replace(cmd, "!e", fe);
cmd=string_replace(cmd, "!f", ff);
cmd=string_replace(cmd, "!h", fh);
cmd=string_replace(cmd, "!r", fr);
cmd=string_replace(cmd, "!t", ft);
if(!(Command(cmd)))
break;
}
return TRUE;
}
int Xgoto(string str)
{
object obj, tmp;
SECURE2(TRUE);
USAGE1(str, "xgo(to) [object]");
if(!str) str="~/workroom";
if(!(obj=XFindObj(str)))
{
if(!(str=XFindFile(str)))
return TRUE;
if(catch(call_other(str, "???")))
return TRUE;
obj=find_object(str);
}
tmp=obj;
while(obj&&living(obj))
obj=ENV(obj);
cloner->move(obj ? obj : tmp, M_TPORT);
return TRUE;
}
int Xgrep(string str)
{
int i, s, t, mode;
string *files, *ts;
SECURE2(TRUE);
TK("Xgrep: str: "+(str?str:"(NULL)"));
mode=0;
if(!pipe_in)
{
USAGE2(str, "xgr(ep) [-i] [-v] <regexp> <filepattern>");
if(!(ts=old_explode(str, " "))||!(s=sizeof(ts)))
return FALSE;
while(ts[0][0]=='-')
{
if(s<3)
{
WDLN("Too few arguments to xgrep");
return FALSE;
}
switch(ts[0])
{
case "-v":
mode|=XGREP_REVERT;
ts=ts[1..];
s--;
break;
case "-i":
mode|=XGREP_ICASE;
ts=ts[1..];
s--;
break;
case "-vi":
case "-iv":
mode|=XGREP_REVERT;
mode|=XGREP_ICASE;
ts=ts[1..];
s--;
break;
default:
WDLN("Unknown option "+ts[0]+" given to xgrep");
return FALSE;
}
}
str=implode(ts[0..s-2], " ");
}
else
{
if(!((ts=old_explode(str, " "))&&(s=sizeof(ts))))
USAGE3("xgr(ep) [-i] [-v] <regexp>");
while(ts[0][0]=='-')
{
if(s<2)
{
WDLN("Too few arguments to xgrep");
return FALSE;
}
switch(ts[0])
{
case "-v":
mode|=XGREP_REVERT;
ts=ts[1..];
s--;
break;
case "-i":
mode|=XGREP_ICASE;
ts=ts[1..];
s--;
break;
case "-iv":
case "-vi":
mode|=XGREP_REVERT;
mode|=XGREP_ICASE;
ts=ts[1..];
s--;
break;
default:
WDLN("Unknown option "+ts[0]+" given to xgrep");
return FALSE;
}
}
str=implode(ts[0..s-1], " ");
}
if(mode&XGREP_ICASE)
str=lower_case(str);
if(!(regexp(({"dummy"}), str)))
{
WDLN("Bad regular expression");
return TRUE;
}
if(!pipe_in)
{
if(file_size(TMP_FILE)>0)
rm(TMP_FILE);
if((t=sizeof(files=long_get_dir(XFile(ts[s-1]), FALSE)))&&
(file_size(files[0])>=0))
{
for(i=0; i<t; i++)
XGrepFile(str, files[i], mode);
if(pipe_out&&pipe_of)
{
PIPE_DELETE(pipe_of);
if(!pipe_ovr)
{
write_file(pipe_of,read_file(TMP_FILE,0,PIPE_MAX));
rm(TMP_FILE);
}
else
rename(TMP_FILE,pipe_of);
}
else
{
W(read_file(TMP_FILE,0,PIPE_MAX));
rm(TMP_FILE);
}
}
else
WDLN("Cannot read file(s)");
}
else
{
string *tmp;
if(file_size(pipe_if)<0)
{
WDLN("Missing input to xgrep");
return TRUE;
}
TK("Xgrep: str: "+str+" mode: "+mode);
s=sizeof(tmp=old_explode(read_file(pipe_if,0,PIPE_MAX),"\n"));
PIPE_DELETE(pipe_of);
for(i=0;i<s;i++)
{
// TK(tmp[i]+"<->"+str);
if(sizeof(regexp(({(mode&XGREP_ICASE?lower_case(tmp[i]):tmp[i])}),str)))
{
// TK("Xgrep: matched!");
if(!(mode&XGREP_REVERT))
if(pipe_out&&pipe_of)
write_file(pipe_of,tmp[i]+"\n");
else
WLN(tmp[i]);
}
else
if(mode&XGREP_REVERT)
if(pipe_out&&pipe_of)
write_file(pipe_of,tmp[i]+"\n");
else
WLN(tmp[i]);
}
}
return TRUE;
}
int Xhbeats(string str)
{
object obj;
object *hbeatinfo;
string tmp, file;
int i, s;
SECURE2(TRUE);
TK("Xhbeats: str: "+(str?str:"(NULL)"));
if(!pipe_out)
{
USAGE1(str, "xhb(eats) [search pattern]");
if(!str)
str=RNAME(cloner);
else if(!regexp(({"dummy"}), str))
{
WDLN("Bad regular expression");
return TRUE;
}
}
else
{
USAGE1(str,"xhb(eats)");
if(str&&str!="")
{
WDLN("More arguments than expected");
return TRUE;
}
}
s=sizeof(hbeatinfo=heart_beat_info());
PIPE_DELETE(pipe_of);
for(i=0; i<s; i++)
if(hbeatinfo[i]&&objectp(hbeatinfo[i]))
{
tmp=ObjFile(hbeatinfo[i]);
if(sizeof(regexp(({tmp}), str)))
if(pipe_out&&pipe_of)
write_file(pipe_of, tmp+"\n");
else
WLN(tmp);
}
return TRUE;
}
int Xhead(string str)
{
int lines;
string *tmp, file;
SECURE2(TRUE);
TK("Xhead: str: "+(str?str:"(NULL)"));
if(!pipe_in)
{
USAGE2(str, "xhead <-#> <file>");
if(sscanf(str,"-%d %s",lines,file)!=2)
return FALSE;
if(!(file=XFindFile(file)))
return FALSE;
}
else
{
USAGE2(str, "xhead <-#>");
if(sscanf(str,"-%d",lines)!=1)
return FALSE;
if (file_size(file=pipe_if)<0)
{
WDLN("Missing input to xhead");
return TRUE;
}
}
tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[0..lines-1];
if(pipe_in&&pipe_if==PIPE_FILE)
rm(PIPE_FILE);
if (pipe_out&&pipe_of)
{
PIPE_DELETE(pipe_of);
write_file(pipe_of,implode(tmp,"\n")+"\n");
}
else
WDLN(implode(tmp,"\n"));
return TRUE;
}
int Xhelp(string str)
{
SECURE2(TRUE);
USAGE1(str, "xhe(lp)");
XMoreFile(TOOL_MANPAGE, FALSE);
return TRUE;
}
int Xids(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xid(s) <object>");
TK("Xids: str: "+(str?str:"(NULL)"));
if((obj=XFindObj(str)))
WLN("UID=\""+getuid(obj)+"\" / EUID=\""+geteuid(obj)+"\"");
return TRUE;
}
int Xinfo(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xinf(o) <object>");
TK("Xinfo: str: "+(str?str:"(NULL)"));
if((obj=XFindObj(str)))
{
if(is_player(obj))
{
WLN(PlayerWho(obj));
WLN(PlayerMail(obj, FALSE));
WLN(PlayerIP(obj, FALSE));
WLN(PlayerRace(obj, FALSE));
WLN(PlayerDomain(obj, FALSE));
WLN(PlayerStats(obj, FALSE));
WLN(PlayerSnoop(obj, FALSE));
}
else
WDLN("Sorry, this is not a player");
}
return TRUE;
}
int Xinherit(string str)
{
int s;
object obj;
string *strs, *inlist;
SECURE2(TRUE);
USAGE2(str, "xinh(erit) <object> [function]");
TK("Xinherit: str: "+str);
if(!(strs=strip_explode(str, " ")))
return FALSE;
if(obj=XFindObj(strs[0]))
{
inlist=inherit_list(obj);
s=sizeof(inlist);
while(s--)
{
if(catch(call_other(inlist[s], "???")))
{
WDLN("Failed to load all inheritance objects");
return TRUE;
}
}
obj=find_object(inlist[0]);
PIPE_DELETE(pipe_of);
if(sizeof(strs)==1)
Inheritance(obj ,0 ,"");
else
Inheritance(obj, strs[1], "");
}
return TRUE;
}
int Xinventory(string str)
{
int i, short;
object item;
mixed who;
SECURE2(TRUE);
USAGE1(str, "xi [-s] [player]");
TK("Xinventory: str: "+str);
short=0;
who=cloner;
if(str&&str!="")
{
if(str=="-s")
{
short=1;
who=cloner;
}
else if(sscanf(str,"-s %s",who))
{
short=1;
who=XFindObj(who);
}
else if(sscanf(str,"%s",who))
{
short=0;
who=XFindObj(who);
}
else
who=cloner;
}
if(!who)
return FALSE;
PIPE_DELETE(pipe_of);
if(!(pipe_out&&pipe_of))
WLN(who->name(WESSEN)+" Inventory:"+(short?" (short)":""));
if(!short)
if(pipe_out&&pipe_of)
FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item, pipe_of);
else
FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item);
else
if(pipe_out&&pipe_of)
FORALL(item, who) write_file(pipe_of,++i+". ["+object_name(item)+"]\n");
else
FORALL(item, who) WLN(++i+". ["+object_name(item)+"]");
return TRUE;
}
int Xlag(string str)
{
int i;
float *lag;
object daemon;
string lags;
if(file_size(LAG_O_DAEMON+".c")<=0)
{
WLN("Sorry, lag-o-daemon is missing!");
return TRUE;
}
LAG_O_DAEMON->MachHin();
if(!(daemon=find_object(LAG_O_DAEMON)))
lag=({-1.0,-1.0,-1.0});
else
lag=(float *)daemon->read_lag_data();
lags="Letzte 60 min: ";
if(lag[0]>=0.0)
{
for(i=round(lag[0])-1;i>=0;i--)
lags+="#";
lags+=" ("+sprintf("%.1f",lag[0])+"%)";
}
else
lags+="N/A";
lags+="\nLetzte 15 min: ";
if(lag[1]>=0.0)
{
for(i=round(lag[1])-1;i>=0;i--)
lags+="#";
lags+=" ("+sprintf("%.1f",lag[1])+"%)";
}
else
lags+="N/A";
lags+="\nLetzte Minute: ";
if(lag[2]>=0.0)
{
for(i=round(lag[2])-1;i>=0;i--)
lags+="#";
lags+=" ("+sprintf("%.1f",lag[2])+"%)";
}
else
lags+="N/A";
WLN(lags);
return TRUE;
}
int Xlight(string str)
{
int s, addlight;
SECURE2(TRUE);
USAGE1(str, "xli(ght) [light]");
if(str)
{
if(!sscanf(str, "%d", addlight))
return FALSE;
xlight+=addlight;
cloner->AddIntLight(addlight);
}
WDLN("Current light levels: "+TOOL_NAME+"="+xlight+", room="+
ENV(cloner)->QueryIntLight());
return TRUE;
}
int Xload(string str)
{
int i, f;
object obj, *inv, vroom;
string file, errlog, error, *strs;
SECURE2(TRUE);
USAGE2(str, "xloa(d) <filename>");
if(!(file=XFindFile(str)))
return TRUE;
errlog=ERR_FILE;
if(file_size(errlog)>0)
rm(errlog);
if(obj=find_object(file))
{
if(catch(call_other(VOID, "???")))
{
WDLN("Error: cannot find "+VOID+" to rescue players");
return TRUE;
}
else
vroom = find_object(VOID);
if(inv=filter(all_inventory(obj), #'is_player, ME))//'
for(i=0; i<sizeof(inv); i++)
MoveObj(inv[i], vroom, TRUE);
Destruct(obj);
WLN("Update and load: "+file);
}
else
WLN("Load: "+file);
if(error=catch(call_other(file, "???")))
{
W("Error: "+error[1..]);
if(vroom)
tell_object(vroom, "*** Failed to load room. You are in the void!\n");
}
else if(inv)
{
obj=find_object(file);
for(i=0; i<sizeof(inv); i++)
if(inv[i])
MoveObj(inv[i], obj, TRUE);
}
return TRUE;
}
int Xlook(string str)
{
object obj;
string st;
string file;
SECURE2(TRUE);
USAGE1(str, "xloo(k) [object]");
TK("Xlook: str: "+str);
PIPE_DELETE(pipe_of);
file = pipe_out&&pipe_of ? pipe_of : "";
if(str&&str!="")
{
if((obj=XFindObj(str)))
PrintObj(obj,file);
}
else
{
obj=ENV(cloner);
PrintObj(obj,file);
}
return TRUE;
}
int Xlpc(string str)
{
object obj;
string file, error;
int *ru1, *ru2, time;
mixed res;
SECURE2(TRUE);
USAGE2(str, "xlp(c) <lpc code>");
file=LPC_FILE+".c";
if(file_size(file)>0)
rm(file);
if(obj=find_object(LPC_FILE))
Destruct(obj);
write_file(file,
"#pragma no_warn_missing_return,strong_types,warn_deprecated,rtt_checks\n"
"#include <properties.h>\n"
"#include <thing/properties.h>\n"
"#include <defines.h>\n"
"#include <wizlist.h>\n"
"#include <moving.h>\n"
"#include \"/secure/wizlevels.h\"\n"
+(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
"object get(string str){return previous_object()->XFindObj(str);}\n"+
"mixed eval(mixed me, mixed here){"+str+"}");
if(error=catch(obj=clone_object(file)))
W("Error: "+error[1..0]);
else
{
ru1=rusage();
error=catch(res=(mixed)obj->eval(cloner, ENV(cloner)));
ru2=rusage();
if(error)
W("Error: "+error[1..]);
else
{
time=ru2[0]-ru1[0]+ru2[1]-ru1[1];
WDLN("Evaluation time: "+(time<0 ? 0 : time)+" ms");
WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
if(objectp(res))
variable["result"] = res;
}
}
rm(file);
if(obj)
Destruct(obj);
return TRUE;
}
int Xman(string str)
{
string manpage;
int i, found;
SECURE2(TRUE);
USAGE2(str, "xma(n) <manpage>");
W("Man: ");
for(i=0, found=0; i<sizeof(manpath); i++)
{
manpage=manpath[i]+str;
if(file_size(manpage)>=0)
{
WLN(manpage);
XMoreFile(manpage, FALSE);
found=1;
break;
}
}
if(!found)
WLN("- no help available -");
return TRUE;
}
int Xmore(string str)
{
string *args, file;
int line;
SECURE2(TRUE);
TK("Xmore: str: "+str);
if (!pipe_in)
{
USAGE2(str, "xmor(e) <filename> [start]");
switch(sizeof(args=strip_explode(str, " ")))
{
case 1:
moreoffset=1;
break;
case 2:
sscanf(args[1], "%d", line);
moreoffset= line>0 ? line : 1;
break;
default:
return FALSE;
}
if(file=XFindFile(args[0]))
XMoreFile(file, TRUE);
}
else
{
if(file_size(pipe_if)<0)
{
WDLN("Missing input to xmore");
return TRUE;
}
if (!str||str=="")
line=1;
else if (sscanf(str, "%d", line)!=1)
USAGE3("xmor(e) [start]");
moreoffset= line>0 ? line : 1;
XMoreFile(pipe_if, TRUE);
}
return TRUE;
}
int Xmove(string str)
{
object obj1, obj2;
string what, into;
SECURE2(TRUE);
USAGE2(str, "xmov(e) <object> into <object>");
if((sscanf(str, "%s into %s", what, into)==2)&&
(obj1=XFindObj(what))&&(obj2=XFindObj(into)))
MoveObj(obj1, obj2, FALSE);
return TRUE;
}
int Xmsg(string str)
{
string tmp;
SECURE2(TRUE);
TK("Xmsg: str: "+str);
USAGE1(str, "xms(g) [to <object>|all]");
if(!str||str=="")
{
WDLN("Send message into room");
say("Message from "+CRNAME(cloner)+":\n");
if(pipe_in&&pipe_if)
say(read_file(pipe_if,0,PIPE_MAX));
else
{
WDLN("End message with \".\" or \"**\"");
input_to("XMsgSay");
}
return TRUE;
}
else if(sscanf(str, "to %s", tmp))
{
if(msgto=XFindObj(tmp))
{
PrintShort("Send message to: ", msgto);
tell_object(msgto, "Message from "+CRNAME(cloner)+" to you:\n");
if(pipe_in&&pipe_if)
tell_object(msgto,read_file(pipe_if,0,PIPE_MAX));
else
{
WDLN("End message with \".\" or \"**\"");
input_to("XMsgTell");
}
}
return TRUE;
}
else if(str=="all")
{
WDLN("Send message to all players");
shout("Message from "+CRNAME(cloner)+" to all:\n");
if(pipe_in&&pipe_if)
shout(read_file(pipe_if,0,PIPE_MAX));
else
{
WDLN("End message with \".\" or \"**\"");
input_to("XMsgShout");
}
return TRUE;
}
return FALSE;
}
int Xmtp(string str)
{
int s;
string *strs, opt, dir, file;
SECURE2(TRUE);
USAGE2(str, "xmt(p) [options] <directory> <filename>");
s=sizeof(strs=old_explode(str, " "));
if(s<2)
return FALSE;
else if(s==2)
opt="";
else
opt=implode(strs[0..s-3], " ");
if(!(dir="/"+(string)MASTER->valid_read(strs[s-2], geteuid(),
"get_dir", ME))) {
WDLN("No permission to open directory for reading");
return TRUE;
}
if(!(file="/"+(string)MASTER->valid_write(strs[s-1], geteuid(),
"write_file", ME))) {
WDLN("No permission to open script file for writing");
return TRUE;
}
if(file_size(dir)!=-2 || file_size(file)==-2)
return FALSE;
XmtpScript(dir, file, opt);
WDLN("Done");
return TRUE;
}
int Xproc(string str)
{
int s;
string *strs;
SECURE2(TRUE);
USAGE1(str, "xproc [-c] [-l] [-m] [-u] [-v]");
if(file_size(TOOL_PATH+"/proc")!=-2)
{
WLN("Sorry, no /proc information available!");
return TRUE;
}
if(!str||str==""||!(s=sizeof(strs=old_explode(str, " "))))
{
WLN("Load averages:");
cat(TOOL_PATH+"/proc/loadavg");
return TRUE;
}
while(s=sizeof(strs))
{
switch(strs[0])
{
case "-c":
WLN("CPU info:");
cat(TOOL_PATH+"/proc/cpuinfo");
break;
case "-l":
WLN("Load averages:");
cat(TOOL_PATH+"/proc/loadavg");
break;
case "-m":
WLN("Memory usage:");
cat(TOOL_PATH+"/proc/meminfo");
break;
case "-u":
WLN("Uptime:");
cat(TOOL_PATH+"/proc/uptime");
break;
case "-v":
WLN("Version:");
cat(TOOL_PATH+"/proc/version");
break;
default:
WLN("Unknown option: "+strs[0]);
}
strs=strs[1..];
}
return TRUE;
}
int Xprof(string str)
{
string *funcs, inh, tmp;
mixed *data, *d;
mapping xpr;
object obj;
int i, rn;
SECURE2(TRUE);
USAGE2(str, "xprof <<-c>|<-C> <file>>|<object>");
if(str[0..2]=="-c "||str[0..2]=="-C ")
{
rn=(str[1]=='C');
if(str=XFindFile(str[3..]))
{
inh=str=str[0..<3];
if(obj=find_object(inh))
Destruct(obj);
if(catch(call_other(inh,"???")))
return TRUE;
obj=find_object(inh);
if(rn)
{
inh+=".xprof.c";
rm(inh);
str+=".c";
rename(str, inh);
}
else
{
str=XPROF_FILE;
rm(str);
}
tmp="inherit \""+inh+"\";\n#include \""+XPROF_MACRO+"\"\n";
funcs=m_indices(mkmapping(functionlist(obj, 0x08000001)))-({"__INIT"});
for(i=sizeof(funcs); i--;)
tmp+="F("+funcs[i]+",\""+funcs[i]+"\","+
"(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9))\n";
write_file(str, tmp);
WDLN("Done");
}
}
else if(obj=XFindObj(str))
{
if(xpr=(mapping)obj->__query_xprof_data__())
{
funcs=m_indices(xpr);
data=m_values(xpr);
rm(TMP_FILE);
str="Evaluation cost per function:\nNAME "+
" CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
for(i=sizeof(funcs); i--;)
{
if(d=data[i]) {
funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
ARIGHT(" "+d[1],10,".") +" "+ARIGHT(" "+d[3],10,".")+" | "+
ARIGHT(" "+d[1]/d[0],9,".") +" "+ARIGHT(" "+d[3]/d[0],9,".");
}
}
str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
write_file(TMP_FILE,str);
str="\nElapsed time per function:\nNAME "+
" CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
funcs=m_indices(xpr);
for(i=sizeof(funcs); i--;)
{
if(d=data[i])
{
funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
ARIGHT(" "+(d[2]+5)/10+"ms",10,".")+" "+
ARIGHT(" "+(d[4]+5)/10+"ms",10,".")+" | "+
ARIGHT(" "+d[2]/d[0]+"us",9,".")+" "+
ARIGHT(" "+d[4]/d[0]+"us",9,".");
}
}
str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
write_file(TMP_FILE,str);
XMoreFile(TMP_FILE, FALSE);
}
else
WDLN("No profiling information available");
}
return TRUE;
}
int Xprops(string str)
{
int i, s, flag;
object obj;
string *tmp;
SECURE2(TRUE);
USAGE2(str, "xprop(s) [-f|-m] <object>");
TK("Xprops: str: "+str);
tmp=old_explode(str," ");
switch(tmp[0])
{
case "-f":
{
flag = 1;
tmp=tmp[1..];
break;
}
case "-m":
{
flag = 2;
tmp=tmp[1..];
break;
}
}
str=implode(tmp," ");
if((obj=XFindObj(str)))
DumpProperties(obj,flag);
return TRUE;
}
int Xquit(string str)
{
SECURE2(TRUE);
USAGE1(str, "xqu(it)");
str=object_name(ENV(cloner));
if(member(str, '#')<0)
cloner->set_home(str);
cloner->quit();
return TRUE;
}
int Xscan(string str)
{
SECURE2(TRUE);
USAGE1(str, "xsc(an)");
W("Destructed variable(s): ");
string* oldvars=m_indices(variable);
VarCheck(FALSE);
string* desvars=oldvars-m_indices(variable);
desvars = map(desvars, function string (string k)
{return "$"+k;} );
W(CountUp(desvars));
WLN("");
return TRUE;
}
int Xset(string str)
{
int i;
mixed obj;
string name, tmp;
SECURE2(TRUE);
USAGE1(str, "xse(t) [$<name>=<object>]");
if(str) {
if(member(({"$me","$m","$here","$h"}),str)!=-1)
WDLN("Sorry, this is a reserved variable ["+str+"]");
else if(sscanf(str, "$%s=%s", name, tmp))
{
if(obj=XFindObj(tmp))
{
variable[name] = obj;
WLN(" $"+name+"="+ObjFile(obj));
}
}
else
return FALSE;
}
else
{
VarCheck(FALSE);
WLN("Current settings:");
foreach(string key, mixed val : variable)
{
if (val)
WLN(" $"+key+"="+ObjFile(val));
else
m_delete(variable, key);
}
WLN(" $me="+ObjFile(cloner));
WLN(" $here="+ObjFile(ENV(cloner)));
}
return TRUE;
}
int Xsh(string str)
{
SECURE2(TRUE);
USAGE1(str, "xsh <filename>");
if(scriptline)
{
WDLN("Cannot execute another script file until last execution has ended");
return TRUE;
}
if(!(str=XFindFile(str)))
return TRUE;
str=read_file(str, 1, 1000);
if(!(scriptline=old_explode(str, "\n")))
{
WDLN("Bad script file");
return TRUE;
}
scriptsize=sizeof(scriptline);
XExecFile(NULL);
return TRUE;
}
int Xsort(string str)
{
string *tmp,file;
int s,reverse;
SECURE2(TRUE);
TK("Xsort: str: "+str);
if(!pipe_in)
{
USAGE2(str, "xso(rt) [-r] [file]");
if(!(tmp=old_explode(str, " "))||(s=sizeof(tmp))>2)
return FALSE;
if(tmp[0]=="-r")
if(s==1)
return FALSE;
else
{
reverse=TRUE;
tmp=tmp[1..];
}
else if(s>1)
return FALSE;
if(!(file=XFindFile(tmp[0])))
{
WDLN("Can't find file");
return TRUE;
}
}
else
{
if(str&&str!="")
if(str=="-r")
reverse=TRUE;
else
USAGE3("xso(rt) [-r]");
if (file_size(file=pipe_if)<0)
{
WDLN("Missing input to xsort");
return TRUE;
}
}
tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
if(pipe_in&&pipe_if==PIPE_FILE)
rm(PIPE_FILE);
tmp=sort_array(tmp,reverse?#'<:#'>);
if (pipe_out&&pipe_of)
write_file(pipe_of,implode(tmp,"\n")+"\n");
else
WDLN(implode(tmp,"\n"));
return TRUE;
}
int Xtail(string str)
{
string *tmp,file,sign;
int lines;
if (!str) {
WDLN("Missing input to xtail");
return TRUE;
}
sign="-";
lines=10;
SECURE2(TRUE);
TK("Xtail: str: "+str);
if(!pipe_in)
{
if(sscanf(str,"-%d %s",lines,file)==2)
sign="-";
else if(sscanf(str,"+%d %s",lines,file)==2)
sign="+";
else
file=str;
if(!(file=XFindFile(file)))
{
WDLN("Can't find file");
return TRUE;
}
}
else
{
if(sscanf(str,"-%d",lines)==1)
sign="-";
else if(sscanf(str,"+%d",lines)==1)
sign="+";
if (file_size(file=pipe_if)<0)
{
WDLN("Missing input to xtail");
return TRUE;
}
}
if(sign=="-")
{
if(!lines)
return TRUE;
}
if(file_size(file)>50000)
{
WDLN("File too large");
return TRUE;
}
if(sign=="+")
tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[lines..];
else
tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[<lines..];
if(pipe_in&&pipe_if==PIPE_FILE)
rm(PIPE_FILE);
if (pipe_out&&pipe_of)
write_file(pipe_of,implode(tmp,"\n")+"\n");
else
WLN(implode(tmp,"\n"));
return TRUE;
}
int Xtool(string str)
{
int m;
string tmp;
object obj;
SECURE2(TRUE);
TK("Xtool: str: "+str);
USAGE1(str, "xto(ol) [update|first=<on|off>|protect=<on|off>|"+
"invcheck=<on|off>|\n"+
"\t\tvarcheck=<on|off>|scanchk=<on|off>|short=<on|off>|\n"+
"\t\techo=<on|off>|more=<amount>|kill|news|save|load|reset]");
if(str&&str!="")
{
if(sscanf(str, "more=%d", m))
{
if(m<5)
WDLN("Sorry, amount of lines should be more then 5");
else
{
WDLN("Setting amount of displayed lines to "+m);
morelines=m;
}
}
else
switch(str)
{
case "update":
if(obj=find_object(TOOL_PATH))
Destruct(obj);
if(catch(obj=clone_object(TOOL_PATH)))
WLN("Updating "+TOOL_TITLE+" failed!");
else
obj->update_tool(AUTOLOAD_ARGS, cloner);
return TRUE;
break;
case "first=on":
MODE_ON(MODE_FIRST);
move(cloner);
WDLN("Automatic moving into pole position of inventory turned on");
break;
case "first=off":
MODE_OFF(MODE_FIRST);
WDLN("Automatic moving into pole position of inventory turned off");
break;
case "protect=on":
MODE_ON(MODE_PROTECT);
WDLN("Protection from forces and illegal moves turned on");
break;
case "protect=off":
MODE_OFF(MODE_PROTECT);
WDLN("Protection from forces and illegal moves turned off");
break;
case "invcheck=on":
MODE_ON(MODE_INVCHECK);
WDLN("Automatic checking for new objects in inventory turned on");
break;
case "invcheck=off":
MODE_OFF(MODE_INVCHECK);
WDLN("Automatic checking for new objects in inventory turned off");
break;
case "varcheck=on":
MODE_ON(MODE_VARCHECK);
VarCheck(TRUE);
WDLN("Automatic variable checking turned on");
break;
case "varcheck=off":
MODE_OFF(MODE_VARCHECK);
WDLN("Automatic variable checking turned off");
break;
case "scanchk=on":
MODE_ON(MODE_SCANCHK);
WDLN("Scan check turned on");
break;
case "scanchk=off":
MODE_OFF(MODE_SCANCHK);
WDLN("Scan check turned off");
break;
case "echo=on":
MODE_ON(MODE_ECHO);
WDLN("Echoing of multiple command execution turned on");
break;
case "echo=off":
MODE_OFF(MODE_ECHO);
WDLN("Echoing of multiple command execution turned off");
break;
case "short=on":
MODE_ON(MODE_SHORT);
WDLN("Use of short descriptions turned on");
break;
case "short=off":
MODE_OFF(MODE_SHORT);
WDLN("Use of short descriptions turned off");
break;
case "kill":
WDLN(TOOL_NAME+" selfdestructs");
destruct(ME);
break;
case "news":
XMoreFile(TOOL_NEWS, FALSE);
break;
case "reset":
WDLN("Resetting "+TOOL_TITLE);
ME->__INIT();
break;
case "load":
if(file_size(SAVE_FILE+".o")>0)
{
WDLN("Loading "+TOOL_TITLE+" settings");
restore_object(SAVE_FILE);
}
else
WDLN("Sorry, cannot find file to load settings");
break;
case "save":
WDLN("Saving "+TOOL_TITLE+" settings");
save_object(SAVE_FILE);
break;
default:
return FALSE;
}
}
else
{
WLN(TOOL_TITLE+" settings:");
tmp= (" first .... = "+(MODE(MODE_FIRST) ? "on\n" : "off\n"));
tmp+=(" protect .. = "+(MODE(MODE_PROTECT) ? "on\n" : "off\n"));
tmp+=(" invcheck . = "+(MODE(MODE_INVCHECK) ? "on\n" : "off\n"));
tmp+=(" varcheck . = "+(MODE(MODE_VARCHECK) ? "on\n" : "off\n"));
tmp+=(" scanchk .. = "+(MODE(MODE_SCANCHK) ? "on\n" : "off\n"));
tmp+=(" echo ..... = "+(MODE(MODE_ECHO) ? "on\n" : "off\n"));
tmp+=(" short .... = "+(MODE(MODE_SHORT) ? "on\n" : "off\n"));
tmp+=(" more ..... = "+morelines);
WLN(sprintf("%-80#s", tmp));
}
return TRUE;
}
int Xtrace(string str)
{
string file;
object obj;
SECURE2(TRUE);
USAGE1(str, "xtrac(e) <object>");
if(!str||str=="")
{
trace(0);
WDLN("Ending trace ["+short_path("/"+traceprefix(0))+"]");
}
else if(obj=XFindObj(str))
{
PrintShort("Tracing: ", obj);
file=object_name(obj);
file=file[1..<1];
traceprefix(file);
trace(TRACE_LEVEL);
}
return TRUE;
}
int Xtrans(string str)
{
object obj;
SECURE2(TRUE);
USAGE2(str, "xtran(s) <object>");
if((obj=XFindObj(str))&&ENV(obj))
{
tell_room(ENV(obj), CRNAME(obj)+" vanishes.\n");
tell_room(ENV(cloner), CRNAME(obj)+
" is teleported into this room by "+CRNAME(cloner)+".\n");
MoveObj(obj, ENV(cloner), TRUE);
tell_object(obj, "You've been teleported to "+CRNAME(cloner)+".\n");
}
else
WDLN("Failed to teleport object");
return TRUE;
}
int Xupdate(string str)
{
object obj;
string file;
SECURE2(TRUE);
USAGE2(str, "xup(date) <filename>");
if(!(file=XFindFile(str)))
return TRUE;
if(file[<2.. <1]==".c")
file=file[0.. <3];
if((obj=XFindObj(file))&&(obj=find_object(pure_file_name(obj))))
{
PrintShort("Updating: ", obj);
Destruct(obj);
}
else
WDLN("Object not found");
return TRUE;
}
int Xuptime(string str)
{
return TRUE;
}
int Xwc(string str)
{
string file;
string tmp, *tmp2;
int i, chars, words, lines, nchars, nwords, nlines;
SECURE2(TRUE);
TK("Xwc: str: "+str);
chars=words=lines=FALSE;
if(!pipe_in)
{
USAGE2(str, "xwc [-cwl] <file>");
if(str[0]=='-')
{
while((str=str[1..])[0]!=' '&&sizeof(str))
switch(str[0])
{
case 'c':
chars=TRUE;
break;
case 'w':
words=TRUE;
break;
case 'l':
lines=TRUE;
break;
default:
return FALSE;
}
str=str[1..];
}
if(!(file=XFindFile(str)))
{
WDLN("Can't find file");
return TRUE;
}
}
else
{
USAGE1(str,"xwc [-cwl]");
if(str)
if(str[0]=='-')
{
while((str=str[1..])[0]!=' '&&sizeof(str))
switch(str[0])
{
case 'c':
chars=TRUE;
break;
case 'w':
words=TRUE;
break;
case 'l':
lines=TRUE;
break;
default:
return FALSE;
}
}
else
return FALSE;
if(file_size(file=pipe_if)<0)
{
WDLN("Missing input to xwc");
return TRUE;
}
}
if(!(chars|words|lines))
chars=words=lines=TRUE;
nlines=nwords=nchars=0;
tmp=read_file(file,0,PIPE_MAX);
tmp2=explode(tmp,"\n");
if(lines)
{
nlines=sizeof(tmp2);
if(tmp2[<1]==""&&nlines>1)
nlines--;
}
if(words)
for(i=sizeof(tmp2)-1;i>=0;i--)
{
TK(sprintf("%O",tmp2[i]));
if(tmp2[i]!="")
nwords+=sizeof(regexplode(tmp2[i],"[ ]")-({""," "," "}));
TK(sprintf("%O",regexplode(tmp2[i],"[ ]")-({""," "," "})));
TK("nwords: "+nwords);
}
if(chars)
for(i=sizeof(tmp2)-1;i>=0;i--)
nchars+=sizeof(tmp2[i])+1;
tmp2=0;
tmp="";
if(lines)
tmp+=sprintf("%7d",nlines)+" ";
if(words)
tmp+=sprintf("%7d",nwords)+" ";
if(chars)
tmp+=sprintf("%7d",nchars)+" ";
if(file!=pipe_if)
tmp+=file;
WLN(tmp);
return TRUE;
}
int cmdavg_compare(string a, string b)
{
int x,y;
string dum;
sscanf(a,"%s cmdavg: %d",dum,x);
sscanf(b,"%s cmdavg: %d",dum,y);
return x==y?0:(x>y?1:-1);
}
int Xwho(string opt)
{
string *strs,str,func;
SECURE2(TRUE);
TK("Xwho: opt: \""+opt+"\"");
USAGE1(opt, "xwh(o) [mail|ip|race|guild|domain|stats|snoop]");
func="string_compare";
if(!opt||opt=="")
strs=map(users(), "PlayerWho", ME);
else
switch(opt)
{
case "mail":
strs=map(users(), "PlayerMail", ME, TRUE);
break;
case "ip":
strs=map(users(), "PlayerIP", ME, TRUE);
break;
case "race":
case "guild":
strs=map(users(), "PlayerRace", ME, TRUE);
break;
case "domain":
strs=map(users(), "PlayerDomain", ME, TRUE);
break;
case "stat":
case "stats":
strs=map(users(), "PlayerStats", ME, TRUE);
break;
case "snoop":
strs=map(users(), "PlayerSnoop", ME, TRUE);
break;
case "cmdavg":
strs=map(users(), "PlayerCmdAvg", ME, TRUE);
func="cmdavg_compare";
break;
default:
return FALSE;
}
strs=sort_array(strs, func, ME);
if(pipe_out&&pipe_of)
write_file(pipe_of,implode(strs,"\n")+"\n");
else
WLN(implode(strs,"\n"));
return TRUE;
}