/** * This prints out nicely formated lists of information. It ius used * by the people, finger etc commands. * @author Pinkfish */ #include <peopler.h> #define MULTIPLAYER "/handlers/multiplayer" string *de_names, *abbrev, *var_names; void create() { de_names = DE_NAMES; abbrev = ABBREV; var_names = ({ "dirs", "netstat", "people", "qpeople", "terms", "netdups", }); } /* create() */ /** * This method returns the list of people using the 'str' as a * constraint. So it only shows the people who match with the * str. * @param str the constraint string * @return the array of people */ object *get_people(string str) { object *ob; int i; string s1; ob = users(); for(i = 0; i<sizeof(ob); i++) { if (str && (sscanf(ob[i]->query_name(),str+"%s", s1) != 1)) { ob = ob[0..i - 1] + ob[i+1..]; i--; } } return ob; } /* get_people() */ private string create_title(mixed *bits) { int i, pos; string str; str = ""; for (i=0;i<sizeof(bits);i+=2) { if ((pos = (bits[i]&~MASK)) == STRING) str += bits[i+1]; else if (strlen(de_names[pos]) > bits[i+1]) str += sprintf("%"+bits[i+1]+"."+bits[i+1]+"s", ""); else switch (bits[i]&MASK) { case CENTER : str += sprintf("%"+bits[i+1]+"."+bits[i+1]+"|s", de_names[pos]); break; case RIGHT : str += sprintf("%"+bits[i+1]+"."+bits[i+1]+"s", de_names[pos]); break; default : str += sprintf("%"+bits[i+1]+"."+bits[i+1]+"-s", de_names[pos]); break; } } return str; } /* create_title() */ private string review_thingy(mixed *bing) { int i; string str; str = ""; for (i = 0; i < sizeof(bing); i += 2) { if (bing[i] == STRING) { str += bing[i+1]; } else { switch (bing[i]&MASK) { case CENTER : str += "%|"+bing[i+1]+abbrev[bing[i]&~MASK]; break; case RIGHT : str += "%"+bing[i+1]+abbrev[bing[i]&~MASK]; break; default : str += "%-"+bing[i+1]+abbrev[bing[i]&~MASK]; break; } } } return str; } /* review_thingy() */ /** * This method prints out the entries given the input pattern. * Ok, the method for doing the format is... * ({ type, width, ... }) * With strings the width is the string... */ private void print_entrys(object *obs, mixed *format, int with_dups) { int age, j; mixed g; string form, str, mess, *not_allowed; object ob, env, *dups; mapping per_ip; reset_eval_cost(); if (with_dups) { per_ip = unique_mapping(obs, (: query_ip_number($1) :)); } mess = sprintf("%s\n", create_title(format)); foreach(ob in obs) { str = ""; for (j=0;j<sizeof(format);j+=2) { switch (format[j]&MASK) { case RIGHT : form = "%"+format[j+1]+"."+format[j+1]; break; case CENTER : form = "%|"+format[j+1]+"."+format[j+1]; break; default : form = "%-"+format[j+1]+"."+format[j+1]; break; } switch (format[j]&~MASK) { case STRING : /* Ignore width for this one... */ str += format[j+1]; break; case C_NAME : str += sprintf(form+"s", capitalize( (string)ob->query_name() ) ); break; case GENDER : str += sprintf(form+"s", ob->query_gender_string()); break; case P_NAME : str += sprintf(form+"s", (ob->query_in_editor()?"*":"")+ ( ob->query_invis() ? "("+ (string)ob->query_name() +")" : (string)ob->query_name() ) ); break; case GUILD : if(ob) str += sprintf(form+"s", (ob->query_race()?ob->query_race():"No race")); else str += sprintf(form+"s", "Broken race"); break; case LEVEL : str += sprintf(form+"s", ""+ ob->query_level()); break; case ROWS : str += sprintf(form+"s", ""+ ob->query_rows()); break; case COLS : str += sprintf(form+"s", ""+ ob->query_cols()); break; case TERMINAL : str += sprintf(form+"s", ((g = ob->query_term_name()) ? g + (g == "network" ? " (" + ob->query_cur_term() + ")" : "") : "")); break; case IP_NUMBER : str += sprintf(form+"s", query_ip_number(ob)); break; case IP_NAME : str += sprintf(form+"s", (query_ident(ob)?query_ident(ob)+"@":"")+ query_ip_name(ob)); break; case TYPE : str += sprintf(form+"s", ob->query_object_type()+""); break; case AGE : age = (int)ob->query_time_on(); if (age < -86400) str += sprintf(form+"s", (age/-86400)+"D"); else if (age < -3600) str += sprintf(form+"s", (age/-3600)+"h"); else if (age < -60) str += sprintf(form+"s", (age/-60)+"m"); else str += sprintf(form+"s", (age/-1)+"s"); break; case ROOM : env = environment(ob); str += sprintf(form+"s",env?file_name(env):"No environment"); break; case EUID : env = environment(ob); str += sprintf(form+"s",env?geteuid(env):"No environment"); break; case UID : env = environment(ob); str += sprintf(form+"s",env?getuid(env):"No environment"); break; case CFILE : env = environment(ob); str += sprintf(form+"s",env?"/secure/master"->creator_file(env) :"No environment"); break; case CUR_DIR : str += sprintf(form+"s", (ob->query_current_path()? ob->query_current_path():"No dir")); break; case ND_ALLOWED : dups = per_ip[query_ip_number(ob)] - ({ ob }); not_allowed = MULTIPLAYER->check_allowed(ob, dups); str += sprintf(form+"s", (sizeof(not_allowed) ? query_multiple_short(not_allowed) : "")); break; } } /* for j... */ mess += sprintf("%s\n", str); } /* for i... */ this_player()->more_string( mess ); } /* print_entrys() */ /** * This method is the main access point to the peopler. It prints out * the commands. The optional sort function allows you to sort on * somethign other than the name of the player. * <p> * The format of the pattern string is an array with every second element * being the type and the other element being the width of the printable * string. * <pre> * ({ type, width, ... }) * </pre> * With strings the width is the string... * @param pattern the pattern to print with * @param constraint All the names should start with this, 0 fo rnone * @param sort_func the function to sort with (optional) * @param only_duplicates only print entries whicxh are the same (using the * sort_func * @return 0 on failure, 1 on success * @see help::people * @see help::netstat * @see help::snetstat * @see help::netdups * @see help::terms * @see help::dirs */ int do_command(mixed *pattern, string constraint, function sort_func, int only_duplicates) { object *obs; object *tmpobs; int i; obs = get_people(constraint); if (!sizeof(obs)) { notify_fail("Nobody seems to start with '" + constraint + "'.\n"); return 0; } if (!sort_func) { sort_func = (: strcmp($1->query_name(), $2->query_name()) :); } obs = sort_array(obs, sort_func); if (only_duplicates) { tmpobs = ({ }); for (i = 1; i <sizeof(obs); i++) { if (!evaluate(sort_func, obs[i - 1], obs[i])) { if (member_array(obs[i - 1], tmpobs) == -1) { tmpobs += obs[i - 1..i]; } else { tmpobs += ({ obs[i] }); } } } if (!sizeof(tmpobs)) { notify_fail("Unable to find any duplicates.\n"); return 0; } obs = tmpobs; } print_entrys(obs, pattern, only_duplicates); return 1; } /* do_command() */ /** * The review command. Prints out the current settings for * the commands. * @param str the player name restriction string * @return 0 if it failed, 1 if it succeeded * @see help::review */ int review() { mixed *bing; bing = (mixed *)this_player()->query_property("people list"); if (!bing) bing = P_DEFAULT; write("People : "+review_thingy(bing)+"\n"); bing = (mixed *)this_player()->query_property("qpeople list"); if (!bing) bing = QP_DEFAULT; write("Qpeople: "+review_thingy(bing)+"\n"); bing = (mixed *)this_player()->query_property("netstat list"); if (!bing) bing = N_DEFAULT; write("Netstat: "+review_thingy(bing)+"\n"); bing = (mixed *)this_player()->query_property("term list"); if (!bing) bing = T_DEFAULT; write("Terms : "+review_thingy(bing)+"\n"); bing = (mixed *)this_player()->query_property("dir list"); if (!bing) bing = D_DEFAULT; write("Dirs : "+review_thingy(bing)+"\n"); bing = (mixed *)this_player()->query_property("netdup list"); if (!bing) bing = ND_DEFAULT; write("Netdups: "+review_thingy(bing)+"\n"); } /* review() */ private mixed *create_review(string str) { string *bits, rest; int i, bing, width, tmp; mixed *ret; bits = explode("$"+str, "%"); bits[0] = bits[0][1..]; if (!strlen(bits[0])) ret = ({ }); else ret = ({ STRING, bits[0] }); for (i=1;i<sizeof(bits);i++) { bing = RIGHT; rest = bits[i]; if (rest[0] == '|') { bing = CENTER; rest = rest[1..]; } else if (rest[0] == '-') { bing = 0; rest = rest[1..]; } if (sscanf(rest, "%d%s", width, rest) == 2) { tmp = member_array(rest[0..0], abbrev); if (tmp == -1) { write("Unknown thingy '"+rest[0..0]+"'\n"); return 0; } ret += ({ tmp+bing, width }); rest = rest[1..]; if (strlen(rest)) ret += ({ STRING, rest }); } else { ret += ({ STRING, bits[i] }); } } return ret; } /* create_review() */ private void list_matches() { int i; for (i=0;i<sizeof(de_names);i++) { if (i == STRING) continue; printf("%s: %s\n", abbrev[i], de_names[i]); } } /* list_matches() */ /** * Sets a variable. Sets the variable to the specified value. * @param the name and arg of the varible * @return 0 on failure, 1 on success */ int set_var(string str) { string name, type; mixed *bing; if (str == "help") { write("The non helpful help.\nThis is the list of things that go after "+ "the %'s in the value.\n"); list_matches(); return 1; } if (!str || sscanf(str, "%s %s", name, type) != 2) { notify_fail("Syntax: "+query_verb()+" <var_name> <value>\n"+ " "+query_verb()+" help\n"); return 0; } if (member_array(name, var_names) == -1) { notify_fail("You cannot set the var "+name+", it has to be one of "+ implode(var_names[0..<2], ", ")+" or " + var_names[<1] + ".\n"); return 0; } bing = create_review(type); if (!bing) return 1; this_player( 1 )->add_property( name +" list", bing ); write("Ok, set var "+name+" to "+type+".\n"); return 1; } /* set_var() */