/*
By Drizzt@Darkpowers
This little thingy-mo-bobber will scan domain directories for
rooms, and print up some stats on themm..
A typical datafile should look like
/d/Fooland
/d/Fooland/rooms
Or something or a nothers. Just so you get all the rooms ditectories into
A datafile
-- Drizzt@Darkpowers added the -r and -f options
-- Drizzt@Darkpowers added the -d option
-- Leto@Earth fixed for use of MudOS v21, and prevented max_eval error
-- Avatar@Eodon fixed for use of MudOS v21.b5
*/
#include <mudlib.h>
inherit OBJECT;
string *scandirs,dm;
mixed *fail;
int rc,mc,oc,dflag;
mapping err;
mapping misfil;
int startup(string foo);
void exit_consistancy(object ob);
int start_up();
int scan_dir(string path);
void write_scanfile(string check, int rflag, int fflag);
string chunk(string str);
string chunk(string str){
if(!str) return 0;
if( str[<2..<1] != ".c" )
return str + ".c";
else return str;
}
void write_scanfile(string check, int rflag, int fflag){
string *files,file;
int i;
if(fflag){
file = read_file(check);
files = explode(file,"\n");
i = sizeof(files);
while(i--){
scandirs += ({ files[i] });
}
if(rflag){
i = sizeof(scandirs);
while(i--){
scan_dir(scandirs[i]+"/");
}
}
}
if(!fflag){
scandirs += ({ check });
if(rflag){
i = sizeof(scandirs);
while(i--){
scan_dir(scandirs[i]+"/");
}
}
}
return ;
}
int scan_dir(string path) {
mixed *dir;
string what;
int loop;
dir = get_dir( path );
if(!dir || !sizeof(dir)) return -1;
for(loop=0; loop<sizeof(dir); loop++) {
what = path + dir[loop];
if(file_size( what ) == -2) {
scan_dir(what + "/");
scandirs += ({ what });
}
}
return 1;
}
void create(){
seteuid(getuid());
scandirs = ({});
set("id",({"scanner","ms","*mu*","clip","clipboard"}));
set("short","A clip-board for scanning domains");
set("long",
"A clip-board for scanning domains\n[1] setup <flags> <file>\n"
"[2] scan (Scans files setup within setup)\n[3] write - writes"
" file to home directory\n[4] info - tells same as write.\n");
set("bulk",0);
set("mass",0);
}
void init(){
add_action("startup","setup");
add_action("info","info");
add_action("writeit","write");
add_action("start_up","Scan");
}
int startup(string foo){
string *flags, foostr,file,fle,*doodle;
int rflag, fflag,nflag,i;
if(!foo || sscanf(foo,"%s %s",foostr,fle) != 2){
write("MS: setup <flags> <filename>\n");
write("VFlags: -r = Recurse Subdirectories\n");
write("VFlags: -f = Use a pre-made file\n");
write("VFlags: ~/ = Use no options\n");
write("VFlags: -d = Scan a domain <filename = domain>\n");
write("Example: setup -r /d/Fooland ( Will scan /d/Fooland and recurse )\n");
write("Example: setup -rf /open/foo.data ( Will use /open/foo.data for scanning data\n");
write(" And will recurse.\n");
write("Example: setup -f /open/foo.data ( Will simply scan only using foo.data )\n");
write("Example: setup -d Fooland ( Will scan ALL of the Fooland Domain.\n");
return 1;
}
write("MS: Settings Reset.\n");
dm = 0;
dflag = 0;
scandirs = ({});
file = resolv_path((string)this_player()->query("cwd"),fle);
flags = explode(lower_case(foostr),"");
if(member_array("-", flags) != -1) flags -= ({ "-" });
if(member_array("r", flags) != -1) rflag = 1;
if(member_array("f", flags) != -1) fflag = 1;
if(member_array("/", flags) != -1) nflag = 1;
if(member_array("d", flags) != -1) dflag = 1;
if(dflag && fflag || dflag && rflag || dflag && nflag){
write("MS: You cannot specify the 'd' flag with any other flags.\n");
return 1;
}
if(fflag && !file_exists(file) && !nflag){
write("MS: No such file exists \""+file+"\".\n");
return 1;
}
if(!fflag && !directory_exists(fle) && !nflag && !dflag){
write("MS: No such directory exists \""+fle+"\".\n");
return 1;
}
if(nflag && rflag || nflag && fflag){
write("MS: Invalid use of flags.\n");
return 1;
}
if(dflag){
if(!directory_exists("/d/"+fle)){
write("MS: There is no such domain.\n");
write("MS: Valid Domain Directories include:\n");
doodle = get_dir("/d/");
i = sizeof(doodle);
while(i--){
if(file_size("/d/"+doodle[i]) == -2) write("MS: "+doodle[i]+"\n");
}
return 1;
}
}
write("MS: Starting the scan: ");
if(dflag) write("MS: Scanning Domain: "+fle+"\n");
if(rflag) write("MS: Recursing Directories\n");
if(fflag) write("MS: Using existing Configuration\n");
write("\n");
scandirs = ({});
if(dflag) write_scanfile("/d/"+fle,1, 0);
dm = fle;
if(fflag) write_scanfile(file,rflag,fflag);
else
write_scanfile(fle,rflag,fflag);
scandirs = uniq_array(scandirs);
write("MS: Scanning Complete - "+sizeof(scandirs)+" directories loaded.\n");
write("MS: Now type <Scan> to start the scanner.\n");
return 1;
}
int start_up(){
int i,j,k;
string *dir,val,foo;
string *individ;
object ms,rom, *obs;
err = ([ ]);
misfil = ([]);
fail = ({});
rc = 0;
oc = 0;
mc = 0;
if(sizeof(scandirs) == 0){
write("MS: No directories have been set for scanning.\n");
return 1;
}
write("MS: Initiating Scan:\n");
individ = scandirs;
i = sizeof(individ);
while(i--){
reset_eval_cost(); // Leto
write("MS: Scanning - "+individ[i]+" ");
dir = get_dir(individ[i]+"/");
j = sizeof(dir);
write(j+" files.\n");
while(j--){
reset_eval_cost(); // Leto
if(sscanf(individ[i]+"/"+dir[j],"%s.c",foo) == 1){
foo = individ[i]+"/"+dir[j];
rom = find_object(foo);
if(!rom) {
val = catch(foo->XXX());
if(val){
fail += ({ chunk(foo) });
} else {
rom = find_object(foo);
}
}
if(rom && rom->query("exits")){
obs = all_inventory(rom);
k = sizeof(obs);
while(k--){
if(obs[k]->query("npc")) mc++;
if(!obs[k]->query("npc") && !userp(obs[k])) oc++;
}
rc++;
exit_consistancy(rom);
rom->remove();
}
}
}
}
write("MS: Finished. Use <info> to display the information\n");
write(" And <write> to write to file.\n");
fail = uniq_array(fail);
return 1;
}
void exit_consistancy(object ob){
mapping exits, newexits;
string *rooms, *dirs, *rooms2, file,foo,fl,val;
object newb;
int i,j;
fl = base_name(ob);
exits = ob->query("exits");
dirs = keys(exits);
rooms = values(exits);
i = sizeof(dirs);
while(i--){
// First we need the file to be in file format not file.c
file = rooms[i];
file = chunk(file);
if(file_exists(file)){
foo = file;
newb = find_object(foo);
if(!newb) {
val = catch(foo->XXX());
if(val){
fail += ({ chunk(foo) });
} else {
newb = find_object(foo);
}
}
if(newb){
newexits = newb->query("exits");
if(newexits){
rooms2 = values(newexits);
if(member_array(fl,rooms2) == -1 && member_array(fl +".c",rooms2) == -1){
err += ([ chunk(base_name(ob)) : dirs[i] ]);
}
}
} else {
fail += ({ chunk(file) });
}
} else {
misfil += ([ chunk(fl) : chunk(file) ]);
}
}
}
int info(){
int i;
string *files, *dirs, stuff;
stuff = stuff + "Total objects counted were : "+oc+"\n";
stuff = stuff + "Total rooms counted were : "+rc+"\n";
stuff = stuff + "Total monsters counted were: "+mc+"\n";
if(!err || sizeof(err) == 0){
stuff = stuff + "Exit Consistancy: No errors found.\n";
} else {
files = keys(err);
dirs = values(err);
i = sizeof(dirs);
stuff = stuff + "Exit Consistancy: "+i+" errors found.\n";
while(i--){
stuff = stuff + "File: "+files[i]+" - Exit: "+dirs[i]+"\n";
}
stuff = stuff + "Missing Files: "+sizeof(misfil)+" were missing.\n";
files = keys(misfil);
dirs = values(misfil);
i = sizeof(files);
while(i--){
stuff = stuff + "File:"+files[i]+" couldn't access "+dirs[i];
}
i = sizeof(fail);
stuff = stuff + "Non-Loading files:";
if(i){
stuff = stuff + " "+i+" errors found.\n";
while(i--){
stuff = stuff + "File: "+dump_variable(fail[i])+" failed to load\n";
}
} else {
stuff = stuff + " All files loaded\n";
}
}
this_player()->more(stuff);
return 1;
}
int writeit(){
string file,*dirs,*files;
int i;
if(!dflag){
file = user_path(geteuid(this_player()))+"scanlog."+time();
if(!master()->valid_write(file,this_player(),"ed"))
file = "/tmp/"+geteuid(this_player())+".scanlog";
if(!master()->valid_write(file,this_player(),"ed")){
write("MS: Write failed.\n");
return 1;
}
} else {
file = "/d/"+dm;
if(!master()->valid_write(file,this_player(),"ed"))
file = user_path(geteuid(this_player()))+"scanlog."+time();
if(!master()->valid_write(file,this_player(),"ed"))
file = "/open/"+geteuid(this_player())+".scanlog";
if(!master()->valid_write(file,this_player(),"ed")){
write("MS: Write failed.\n");
return 1;
}
}
write_file(file,"ScanLog report at "+ctime(time())+"\n");
write_file(file,"***********************************\n");
write_file(file," Total Rooms: "+rc+"\n");
write_file(file,"Total Monsters: "+mc+"\n");
write_file(file," Total Objects: "+oc+"\n");
write_file(file,"***********************************\n");
files = keys(err);
dirs = values(err);
i = sizeof(files);
if(i){
write_file(file,"Exit-Consistancy Check: "+i+" errors found.\n");
write_file(file,"-------------------------------------------\n");
while(i--){
write_file(file,"["+i+"] File: "+files[i]+" Dir: "+dirs[i]+"\n");
}
write_file(file,"***********************************\n");
} else {
write_file(file,"Exit-Consistancy Check: No errors found.\n");
write_file(file,"***********************************\n");
}
files = keys(misfil);
dirs = values(misfil);
i = sizeof(dirs);
if(i){
write_file(file,"Missing Files Check: "+i+" errors found.\n");
write_file(file,"----------------------------------------\n");
while(i--){
write_file(file,"["+i+"] File: "+dirs[i]+" | accessed by "+files[i]);
}
write_file(file,"***********************************\n");
} else {
write_file(file,"Missing Files Check: No errors found.\n");
write_file(file,"***********************************\n");
}
i = sizeof(fail);
if(i){
write_file(file,"Non-Loading Files Check: "+i+" errors found.\n");
write_file(file,"----------------------------------------\n");
while(i--){
write_file(file,"["+i+"] File: "+fail[i]+"\n");
}
write_file(file,"***********************************\n");
} else {
write_file(file,"Non-Loading Files Check: All files loaded.\n");
}
write("MS: File written to \""+file+"\"\n");
return 1;
}