// Radix added logging of "update <player>" Dec 15, 1995 #define MASTER "/secure/master" #define PEOPLER "/obj/handlers/peopler" varargs object *wiz_present(string str, object onobj, int nogoout); string desc_object(mixed o); string desc_f_object(object o); static void wiz_commands() { add_action("function2","call"); add_action("parse_frogs", ";"); add_action("dest", "destruct"); add_action("show_stats", "stat"); add_action("trans", "trans"); } /* wiz_commands() */ /* ** commands in the app_commands will go to all players with ** level >= 20. This includes players who have opted to ** remain players rather than advancing to wizard. As such ** we must be careful in what we place here */ static void app_commands() { add_action("whereis","whereis"); add_action("get_pathof","pathof"); add_action("get_creator","coder"); add_action("get_inv","inv"); add_action("goback","goback"); add_action("upgrade_player", "upgrade"); add_action("find_shadows", "shadows"); add_action("do_find", "find"); add_action("do_debug", "dump"); add_action("do_debug", "debug"); } /* app_commands() */ static void all_commands() { } /* all_obj_commands() */ int whereis(string str) { object *ov,e; int i; notify_fail("Where is what?\n"); ov = wiz_present(str,this_player()); if (!sizeof(ov)) return 0; for (i = 0; i < sizeof(ov); i++) { if (ov[i]->query_invis() > 1) continue; if(interactive(ov[i])) if(!(this_player()->query_lord() || this_player()->query_thane())) { log_file("LOCATE",this_player()->query_cap_name()+" attempted to locate interactive: "+ov[i]->query_cap_name()+".\n"); write("Sorry, Locating players is not allowed for you.\n"); continue; } write(desc_object(ov[i]) + " is : \n"); e = ov[i]; while (e = environment(e)) write(" in " + desc_f_object(e) + "\n"); } return 1; } /* whereis() */ /* This is for querying about objects who don't want to be destructed */ static object discard_obj; int affirmative(string s) /* returns true if s is a 'yes' equiv response */ { s = lower_case(s); return (s == "y" || s == "yes" || s == "ok" || s == "please"); } /* affirmative() */ /* is there an error? print it */ void handle_error(string erm, string desc) { if (erm) { write(desc + " failed : " + erm); } } /* handle_error() */ /* added by Dank Mar 3 '93. also added query_prev() to move.c */ int goback() { object ob; if (!(ob = this_player()->query_prev())) write("Previous location is not valid.\n"); else this_player()->move_player("X",ob); return 1; } int get_pathof(string str) { object *ov; int i; notify_fail("Pathof what?\n"); ov = wiz_present(str,this_player()); if (!sizeof(ov)) return 0; for (i = 0; i < sizeof(ov); i++) { if (!ov[i]) continue; /* if (sizeof(ov) > 1) { */ write("Path of " + desc_object(ov[i]) + " in " + desc_object(environment(ov[i])) + ":\n"); /* } */ write(file_name(ov[i])+ "\n"); } return 1; } /* get_pathof() */ int get_inv(string str) { object *ov, obj; int i; notify_fail("Inv of what?\n"); /* thanks for the great error message ! */ if (!str) { ov = ({ this_player() }); } else { sscanf(str, "of %s", str); ov = wiz_present(str,this_player()); } if (!sizeof(ov)) return 0; for (i = 0; i < sizeof(ov); i++) { if (!ov[i]) continue; /* if( (interactive(ov[i])) && !(this_player()->query_lord() || this_player()->query_thane()) && !(ov[i]==this_player())) { log_file("LOCATE",this_player()->query_cap_name()+" attempted to find the inventory of interactive: "+ov[i]->query_cap_name()+".\n"); write("Sorry, You are not permitted to chcek the inventory of "+ov[i]->query_cap_name()+".\n"); continue; } */ write("Inv of " + desc_object(ov[i]) + " in " + desc_object(environment(ov[i])) + ":\n"); obj = first_inventory(ov[i]); while (obj) { write(" " + desc_f_object(obj) + "\n"); obj = next_inventory(obj); } } return 1; } /* inv() */ int get_creator(string str) { object *ov; int i; notify_fail("Creator of what?\n"); ov = wiz_present(str,this_player()); if (!sizeof(ov)) return 0; for (i = 0; i < sizeof(ov); i++) { write("Creator of " + desc_object(ov[i]) + ": " + "secure/master"->creator_file (file_name(ov[i])) + ", uid: " + getuid(ov[i]) + ", euid: "+geteuid(ov[i])+"\n"); } return 1; } /* get_creator() */ static object *dest_obj; static int objn, majd; void ask_dest() { if (!pointerp(dest_obj) || objn >= sizeof(dest_obj)) { write("No more things to dest.\n"); dest_obj = 0; /* wipe array to free memory */ return; } write("Dest object " + desc_object(dest_obj[objn]) + " ? "); input_to("dest_answer"); return; } /* ask_dest() */ void dest_answer(string s) { string err, shrt; if (affirmative(s)) { if (majd) { shrt = (string)dest_obj[objn]->short(); err = catch(dest_obj[objn]->dwep()); handle_error(err, "DWEP"); if (dest_obj[objn]) { write("It REALLY doesn't want to be dested.\n"); err = catch(destruct(dest_obj[objn])); handle_error(err, "destruct()"); } majd = 0; if (dest_obj[objn]) write("It didn't dest.\n"); else { say((string)this_player()->query_cap_name()+" disintegrates "+ (shrt ? shrt : "something") +".\n"); write("Ok.\n"); } objn++; ask_dest(); return; } else { err = catch(dest_obj[objn]->dest_me()); handle_error(err, "dest_me"); if (dest_obj[objn]) { write("This object does NOT want to be dested. Are you sure? "); majd = 1; input_to("dest_answer"); return; } write("Ok.\n"); objn++; ask_dest(); return; } } else if (s == "q" || s == "quit") { write("Ok. No more objects will be destd.\n"); dest_obj = 0; return; } write("Ok. Not destd.\n"); objn++; ask_dest(); return; } /* dest_answer() */ int dest(string str) { object *ob; int i; string qstr, err, shrt, dobj; dest_obj = ({ }); if (!str) {return 0;} notify_fail("Can't find " + str + " to dest.\n"); if (sscanf(str, "query %s", qstr) == 1) { dest_obj = wiz_present(qstr, this_player()); if (!sizeof(dest_obj)) return 0; objn = 0; majd = 0; /* MAJOR dest needed */ ask_dest(); return 1; } ob = wiz_present(str,this_player()); if (!sizeof(ob)) return 0; for (i = 0; i < sizeof(ob); i++) { if(interactive(ob[i]) && (sizeof(ob) !=1 || "/secure/master"->high_programmer(geteuid(ob[i])))) { write("You DON'T destruct " + ob[i]->query_cap_name() + ".\n"); continue; } if(interactive(ob[i]) && !(this_player()->query_lord() || this_player()->query_thane())) { log_file("BUSTED",this_player()->query_cap_name()+" attempted to dest interactive "+ob[i]->query_cap_name()+".\n"); write("Sorry, you are not permitted to dest "+ob[i]->query_cap_name()+".\n"); continue; } catch(shrt = (string)ob[i]->short()); dobj = desc_object(ob[i]); if( ob[i]->query_cap_name() && environment(ob[i]) ) log_file("MISC",(string)this_player(1)->query_cap_name()+" dests "+ob[i]->query_cap_name()+ " from "+environment(ob[i])->query_name()+" file "+file_name(environment(ob[i]))+"\n"); err = catch(ob[i] -> dest_me()); handle_error(err, "dest_me"); if (ob[i]) dest_obj += ({ ob[i] }); else { write("You destruct " + dobj + ".\n"); say((string)this_player()->query_cap_name()+" disintegrates "+ (shrt ? shrt : "something") + ".\n"); } } if (sizeof(dest_obj) > 0) { objn = 0; majd = 0; ask_dest(); return 1; } return 1; } /* dest() */ string desc_object(mixed o){ string str; int p; if (!o) return "** Null-space **"; if (!catch(str = (string)o->short()) && str) return str; if (!catch(str = (string)o->query_name()) && str) return str; return file_name(o); } /* desc_object() */ string desc_f_object(object o){ string str, tmp; str = desc_object(o); if (o && str != file_name(o)) { if (tmp) str += " (" + tmp + ")"; else str += " (" + file_name(o) + ")"; } return str; } /* desc_f_object() */ object *wzpresent2(string str, mixed onobj) { int i; object *obs, obj, *obs2; string s1, s2; if (pointerp(onobj)) { obs = ({ }); for(i = 0; i < sizeof(onobj); i++) obs += wzpresent2(str,onobj[i]); return obs; } if (str == "all") return all_inventory(onobj); /* every fish */ if (sscanf(str,"every %s",s1) == 1) { obs2 = all_inventory(onobj); obs = ({ }); for (i=0;i<sizeof(obs2);i++) if (obs2[i]->id(s1)) obs += ({ obs2[i] }); return obs; } obs2 = find_match(str,onobj); if(sizeof(obs2)) { return obs2; } if (obj = present(str,onobj)) return ({ obj }); for (obj = first_inventory(onobj); obj; obj = next_inventory(obj)) { s2 = file_name(obj); if (sscanf(s2, "%s"+str+"#%d", s1, i) || sscanf(s2, "%s#"+str, s1)) { return ({ obj }); } } return ({ }); } /* wiz_present2() */ varargs object *wiz_present(string str, object onobj, int nogoout) { /* nogoout is so that it WON'T check the environment of onobj */ int i,j; object ob, *obs, *obs2, *users_ob, *temp_ob; string s1, s2, *sts, temp; if (!str || !onobj) { return ({ }); } /* all the simple ones first */ if(str[0] == '@') { if (ob = find_living( (string)this_player()->expand_nickname(extract(str, 1)))) return ({ ob }); notify_fail("Unable to find living object: "+extract(str,1)+".\n"); return ({ }); } if (str == "me") return ({ this_player() }); if (str == "here") return ({ environment(this_player()) }); if (str == "everyone") return users(); if(str[0] == '/') { if (ob = find_object(str)) return ({ ob }); if (sizeof((sts = (string *)this_object()->get_cfiles(str)))) { obs = ({ }); for (i=0;i<sizeof(obs);i++) if ((ob = find_object(sts[i]))) obs += ({ ob }); return obs; } notify_fail("No loaded object: "+str+".\n"); return ({ }); } /* (fish) == environment of fish */ if (str[0] == '(' && str[strlen(str) - 1] == ')') { obs = wiz_present(extract(str,1,strlen(str) - 2),onobj); if (!sizeof(obs)) return obs; for (i = 0; i < sizeof(obs); i++) obs[i] = environment(obs[i]); return obs; } /* handle "fish on fish2" */ /* Hmm....sounds fishy to me. Timion 97 */ if (sscanf(str,"%s on %s",s1,s2) == 2 || sscanf(str,"%s in %s",s1,s2) == 2) { obs = wiz_present(s2, onobj); if (!sizeof(obs)) return obs; obs2 = ({ }); for (i = 0; i < sizeof(obs); i++) obs2 += wiz_present(s1,obs[i],1); return obs2; } /* fish and fish2 */ if (sscanf(str,"%s and %s",s1,s2) == 2) { obs = wiz_present(s1, onobj); obs2= wiz_present(s2, onobj); for (i=0;i<sizeof(obs);i++) /* remove duplicates ... */ if (member_array(obs[i], obs2) < 0) obs2 += ({ obs[i] }); return obs2; } /* fish except fish2 */ if (sscanf(str,"%s except %s",s1,s2) == 2 || sscanf(str,"%s but %s",s1,s2) == 2) { obs = wiz_present(s1, onobj); obs2= wiz_present(s2, onobj); for (i=0;i<sizeof(obs2);i++) while ((j=member_array(obs2[i], obs)) > -1) obs = delete(obs,j--,1); return obs; } if (sscanf(str,"player %s",s1)) return ({ find_player(s1) }); if (!sizeof(obs2 = wzpresent2(str,onobj)) && !nogoout) { obs2 = wzpresent2(str, environment(onobj)); } if (sizeof(obs2)) return obs2; /* check for a find_match locally */ obs2 = find_match(str,onobj); if (sizeof(obs2) > 0) return obs2; /* default to return find_living ... */ if (ob = find_living((string)this_player()->expand_nickname(str))) return ({ ob }); return ({ }); } /* wiz_present() */ static mixed *parse_args(string str, string close) { mixed *args, *m, *m2; object *obs; string s1, s2, s3, s4, s5, s6, s7; int i; mapping map; args = ({ }); while (strlen(str)) { while (strlen(str) && str[0] == ' ') str = str[1..1000]; if (!strlen(str) || str[0..0] == close) return ({ args, str[1..1000] }); switch (str[0]) { case '\'' : if (sscanf(str, "'%s'%s", s1, s2) != 2) { write("Unterminated string.\n"); return 0; } args += ({ replace(s1, "\\n", "\n") }); str = s2; break; case '`' : if (sscanf(str, "`%s`%s", s1, s2) != 2) { write("Unterminated string.\n"); return 0; } args += ({ replace(s1, "\\n", "\n") }); str = s2; break; case '"' : if (sscanf(str, "\"%s\"%s", s1, s2) != 2) { write("Unterminated string.\n"); return 0; } args += ({ replace(s1, "\\n", "\n") }); str = s2; break; case '{' : m = parse_args(str[1..1000], "}"); if (!m) return 0; args += ({ m[0] }); str = m[1]; break; case '[' : str = str[1..1000]; map = ([ ]); while (1) { m = parse_args(str, ":"); /* Ok... if we cannot find another : maybe we are at the end? */ if (!m) { while (strlen(str) && str[0] == ' ') str = str[1..1000]; if (str[0] == ']') break; } if (!(m2 = parse_args(str, ","))) { if (!(m2 = parse_args(str, "]"))) return 0; if (sizeof(m[0])) map[m[0][0]] = (sizeof(m2[0])?m2[0][0]:0); break; } if (sizeof(m[0])) map[m[0][0]] = (sizeof(m2[0])?m2[0][0]:0); } args += ({ map }); break; case '|' : if (sscanf(str, "|%s|%s", s1, s2) != 2) { write("Unmatched |\n"); return 0; } obs = wiz_present(str, this_player()); if (!sizeof(obs)) args += ({ this_player() }); else if (sizeof(obs) == 1) args += ({ obs[0] }); else args += ({ obs }); str = s2; break; case '0'..'9' : case '-' : if (sscanf(str, "%d%s", i, str) != 2) { write("Number expected.\n"); return 0; } args += ({ i }); break; default : s2 = s3 = 0; sscanf(str, "%s,%s", s4, s2); sscanf(str, "%s"+close+"%s", s5, s3); if (sscanf(str, "%s->%s", s6, s7) == 2 && (!s3 || strlen(s5) > strlen(s6)) && (!s2 || strlen(s4) > strlen(s6))) { /* Now we do something trully revolting.... */ while (s7[0] == ' ') s7 = s7[1..1000]; if (sscanf(s7, "%s(%s", s1, s7) != 2) { write("'(' expected.\nLine left unprocessed"+s7+"\n"); return 0; } obs = wiz_present(s6, this_player()); if (!sizeof(obs)) { write("The object "+s6+" needs to exist.\n"); return 0; } m = parse_args(s7, ")"); if (!m) return 0; if (sizeof(m[0]) < 6) m[0] += allocate(6-sizeof(m[0])); obs = map_array(obs, "mapped_call", this_object(), ({ s1 })+m[0]); if (sizeof(obs) == 1) args += obs; else args += ({ obs }); str = m[1]; break; } else if (s2 && s3) if (strlen(s4) < strlen(s5)) { s1 = ","; str = s4; } else { s1 = close; s2 = s3; str = s5; } else if (s2) { s1 = ","; str = s4; } else if (s3) { s1 = close; s2 = s3; str = s5; } else { s1 = ""; s2 = ""; } obs = wiz_present(str, this_player()); if (!sizeof(obs)) { if (str[0] >= '0' && str[0] <= '9' || str[0] == '-') { sscanf(str, "%d%s", i, str); args += ({ i }); } else args += ({ replace(str, "\\n", "\n") }); } else if (sizeof(obs) == 1) args += ({ obs[0] }); else args += ({ obs }); str = s1+s2; break; } /* Skip rubbish and if we dont have a comma we have finished. */ while (strlen(str) && str[0] == ' ') str = str[1..1000]; if (!strlen(str)) return ({ args, str }); if (str[0..0] == close) return ({ args, str[1..1000] }); if (str[0] != ',') { write("Parse error reading arguments, ',' or '"+close+"' expected.\n"); write("Line left unprocessed "+str+"\n"); return 0; } str = str[1..1000]; } return ({ args, str }); } /* parse_args() */ void inform_of_call(object ob, mixed *argv) { string str; int i; str = this_object()->query_cap_name() + " calls " + argv[0] + "("; for (i=1; i<sizeof(argv); ) { str += replace(sprintf("%O", argv[i]), "\n", " "); if (++i < sizeof(argv)) str += ","; } /* Arggghhh! This is annoying me. ob->event_inform(this_object(), str + ") on you", "call"); */ } /* inform_of_call() */ static mixed mapped_call(object ob, mixed *argv) { inform_of_call(ob, argv); return call_other(ob, argv[0], argv[1],argv[2],argv[3], argv[4],argv[5],argv[6]); } /* mapped_call() */ /* Free form parse_args code */ static int parse_frogs(string str) { mixed junk; if (this_player(1) != this_object()) return 0; /* We are not as such looking for an end thingy of any sort... */ junk = parse_args(str, ";"); /* It has already printed an error, so we return 1... */ if (!junk) return 1; log_file("EXECS",(string)this_player(1)->query_cap_name()+" exec'd "+str+"\n"); write("The line "+str+" Returns: \n"); printf("%O\n", junk[0]); return 1; } /* parse_forgs() */ static int function2(string str) { /* call fish(x,y,z) object */ mixed *args; string *s, s1, s2; string fn,os; string *argv; object *ov,retobj; mixed fish, shad, f, file; int i; if (this_player(1) != this_object()) return 0; if (!str) { notify_fail("USAGE : call lfun(arg[,arg[,arg...]]) object[s]\n"); return 0; } log_file("CALLS",(string)this_player()->query_cap_name()+" CALLS "+str+"\n"); s = explode("&"+str+"&", ")"); if (sizeof(s) < 2 || sscanf(s[0], "%s(%s", s1, s2) != 2) { notify_fail("USAGE : call lfun(arg[,arg[,arg...]]) object[s]\n"); return 0; } fn = replace(s1[1..1000], " ", ""); s[0] = s2; args = parse_args(implode(s, ")"), ")"); if (!args) return 1; argv = args[0]; os = args[1][0..strlen(args[1])-2]; while (strlen(os) && os[0] == ' ') os = os[1..1000]; notify_fail("Can't find object "+os+".\n"); ov = wiz_present(os,this_object()); if (!sizeof(ov)) return 0; if (sizeof(argv) < 6) argv += allocate(6 - sizeof(argv)); for (i=0; i < sizeof(ov); i++) { fish = ov[i]; while (shad = shadow(fish, 0)) { fish = shad; if (f = function_exists(fn, fish)) file = f; } if (!file) file = function_exists(fn, ov[i]); if (file) { retobj = call_other(ov[i],fn,argv[0],argv[1],argv[2], argv[3],argv[4],argv[5]); inform_of_call(ov[i], ({ fn }) + argv); if ( ov[i] && interactive(ov[i]) && !ov[i]->query_creator() ) log_file("CALLP",ctime(time())+": "+(string)this_player()->query_cap_name()+" CALLS "+str+" -- player "+(string)ov[i]->query_name()+"\n"); write("*** function on '"+ desc_object(ov[i])+"' found in "+ file+" ***\n"); write("Returned: "); printf("%O\n", retobj); } else write("*** function on '"+desc_object(ov[i])+"' Not found ***\n"); file = 0; } return 1; } /* function2() */ static int do_find(string str) { string func, thing, s, ping; object *obs, fish; int i; notify_fail("Usage: find function() <object(s)>\n"); if(!str) return 0; if(sscanf(str, "%s() %s", func, thing) != 2) if(sscanf(str, "%s %s", func, thing) != 2) return 0; obs = wiz_present(thing, this_object()); if (!sizeof(obs)) { notify_fail("Can't find " + thing + ".\n"); return 0; } s = ""; for (i=0; i < sizeof(obs); i++) { if(ping = function_exists(func, obs[i])) s += "*** " + desc_object(obs[i])+": "+func+"() found in " + ping + "\n"; else s += "*** " + desc_object(obs[i]) + ": " + func + "() not found.\n"; fish = obs[i]; while(fish = shadow(fish, 0)) if(function_exists(func, fish)) s += " Shadowed by " + file_name(fish) + "\n"; } write(s); return 1; } /* do_find() */ int show_stats(string str) { object *ob; mixed *ob1; string *key; string s,str2,bing; int i,c,j; bing = ""; ob = wiz_present(str, this_object()); if (!sizeof(ob)) { write("No such object.\n"); return 1; } for (j=0;j<sizeof(ob);j++) { /* if(interactive(ob[j]) && !(this_player()->query_lord() || this_player()->query_thane()) && !(this_player() == obj(j)) { log_file("LOCATE",this_player()->query_cap_name()+" tried to Stat "+ob[j]->query_cap_name()+".\n"); write("You are not allowed to stat "+ob[j]->query_cap_name()+".\n"); continue; } */ ob1 =ob[j]->stats(); if (!pointerp(ob1)) continue; s = ""; for (i=0;i<(sizeof(ob1)-1);i++) if(ob1[i]) if(ob1[i][0]) s += ob1[i][0] + ": "+ob1[i][1]+"\n"; bing += sprintf("%-*#s\n\n\n", this_object()->query_cols(), s); } this_object()->more_string(bing); return 1; } /* show_stats() */ int trans(string str) { object *obs; int i; if (this_player(1) != this_object()) return 0; if (!str || !(sizeof(obs = wiz_present(str, this_object())))) { write("Transport who ?\n"); return 1; } for (i=0;i<sizeof(obs);i++) { if (environment(obs[i]) == environment()) { write(desc_object(obs[i])+" is already here.\n"); continue; } /* if( interactive(obs[i]) && !(this_player()->query_thane() || this_player()->query_lord()) && !(obs[i]->query_property("test_char")) { log_file("BUSTED",this_player()->query_cap_name()+" tried to illegally trans "+obs[i]->query_cap_name()+".\n"); write("Sorry, You are not powerful enough to trans "+obs[i]->query_cap_name()+". Ask a higher ranking immortal.\n"); continue; } */ if(environment(obs[i])) log_file("MISC",(string)this_player(1)->query_cap_name()+" trans'd "+ obs[i]->query_cap_name()+" from "+file_name(environment(obs[i]))+ " to "+file_name(environment(this_player()))+"\n"); tell_object(obs[i], "You are magically transfered somewhere.\n"); obs[i] -> move_player("X", file_name(environment(this_player()))); // Radix, December 15, 1995 - Warn about transing newbies if(obs[i]->query_level() < 6 && interactive(obs[i])) write("WARNING: This could be a newbie. Removal from a " "newbie area could have serious consequences.\n"); } return 1; } /* trans() */ int upgrade_player() { object ob; ob = clone_object("/secure/upgrade"); ob->new_player(this_object()); return 1; } /* upgrade_player() */ int find_shadows(string s) { object *objs, *shadows; object nobj; int i, j; if (!s || s == "") s = "me"; objs = wiz_present(s, this_object()); if (sizeof(objs) == 0) { notify_fail("Can't find object.\n"); return 0; } for (i = 0; i < sizeof(objs); i++) { shadows = ({ }); nobj = objs[i]; while(nobj = shadow(nobj, 0)) shadows += ({ nobj }); if(!sizeof(shadows)) { write(desc_f_object(objs[i]) + " is not being shadowed.\n"); } else { write(desc_f_object(objs[i]) + " is being shadowed by:\n"); for(j=0; j<sizeof(shadows); j++) write(" " + file_name(shadows[j]) + "\n"); } } return 1; } /* find_shadows() */ int do_debug(string str) { object *obs; if(!str) { notify_fail("Usage: " + query_verb() + " <object>\n"); return 0; } if(!sizeof(obs = wiz_present(str, this_object()))) { notify_fail("Object " + str + " not found.\n"); return 0; } write(debug_info( (query_verb() == "dump"?0:1), obs[0])); return 1; } /* do_debug() */