/* */ /* WIZLIST : 2-24-94 By: Rastafan @ New Moon */ /* */ /* This is a refined 'who' or 'finger' command that shows */ /* useful data about all online users. It also sorts the */ /* users by 'level', with all creators and Lords above all */ /* players. Logins are also shown at the bottom of the list. */ /* Sort_array() is the primary sorting routine that is used, */ /* however, quicksort() can be used if desired. This was */ /* done for CPU tests and possible speed saving. */ /* */ #include "living.h" /* Function declaration for the quicksort routine. */ void quicksort( int l, int r ); /* The following two variables are global, used with */ /* Quicksort for sorting the list. */ static string *lines; static int *sort_list; /* Function: WIZLIST() */ /* */ /* This function lists all users in decending order based */ /* on the following criteria: */ /* High Lords, Lords, Creators sorted by Cre-Grade, */ /* Players sorted by Level(including guests which are lev 0) */ /* and then Logins at the bottom. */ /* */ /* It uses two different ways to sort, depending on if an */ /* argument is given or not. If not, it uses sort_array() */ /* which seems to be faster and is not limited by CPU cycles */ /* if an argument is given, it uses the quicksort algorithm */ /* which may be faster in some cases, but is limited in CPU */ /* cycles by the driver. */ /* */ int wizlist( string str ) { string ret; /* A temporary variable for holding return values. */ object *obs, g_ob; /* obs holds the list of all users and g_ob is the */ /* guild object for a particular user. */ string editor, gend, ears, grd, guild, name, race, real_name, tmp1, tmp2; /* Editor is a string Yes or No stating if a creator is */ /* in the editor. Gend is gender, ears is earmuffs, grd */ /* is the cre-grade, guild is the guild name, name is */ /* the persons name, race is their race, real_name is */ /* their real name and tmp1 and tmp2 are just place */ /* holders for sscanf(). */ int i, j, k, l, m, cgrd, idle; /* i,j,l,m are all loop variables, k is the */ /* number of visible users, cgrd is the */ /* actual numerical grade for a creator and */ /* is not displayed, idle is the number of */ /* seconds a person has been idle. */ obs = users(); /* get all users. */ j = sizeof( obs ); sort_list = allocate( j ); /* Dynamic allocation of memory. */ lines = allocate( j ); for( i = 0; i < j; i++ ) { string euid; if( obs[ i ]->query_invis() && !this_player()->query_creator() ) continue; if( (int)obs[ i ]->query_invis() == 2 && !this_player()->query_lord() ) continue; ears = (obs[ i ]->query_earmuffs()? "e" : " "); idle = query_idle( obs[ i ] ); if( obs[ i ]->query_in_editor() ) editor = "Yes"; else editor = "No"; switch( obs[ i ]->query_gender() ) { case GENDER_NEUTER: gend = "?"; break; case GENDER_MALE: gend = "M"; break; case GENDER_FEMALE: gend = "F"; break; } euid = geteuid( obs[ i ] ); grd = obs[ i ]->query_object_type(); /* euid is the players name if they're a creator, PLAYER if they are */ /* a player, and Root if they are logging in. */ switch( euid ) { case "PLAYER": euid = " " + obs[ i ]->query_level() + " "; sort_list[ k ] = obs[ i ]->query_level(); break; case "Root": euid = "LOGIN"; sort_list[ k ] = (-1); break; default: euid = "High"; cgrd = (int)"/obj/handlers/cregrade"-> query_cre_grade( obs[ i ]->query_name() ); if( grd == "H" ) cgrd = 101; sort_list[ k ] = cgrd + 1000; break; } /* The following code gets the actual name of the guild, some guilds */ /* have exceptionally large 'names' and so we don't bother with it */ /* and just get the file name of the guild, a one word statement of */ /* the guild, like "wizards" or "fighters". */ g_ob = obs[ i ]->query_guild_ob(); if( g_ob ) { if( sscanf( g_ob, "%sguilds/%s/%s", tmp1, guild, tmp2 ) != 3 ) if( sscanf( g_ob, "%sguilds/%s", tmp1, guild ) != 2 ) guild = "?"; } else guild = "none"; race = obs[ i ]->query_race(); name = (obs[ i ]->query_invis()? "(" + obs[ i ]->query_name() + ")" : capitalize( (string)obs[ i ]->query_name() )); real_name = ((ret = (string)obs[ i ]->query_real_name())? ret : "-"); /* each 'line' contains all the information we want to print out, */ /* followed by a separator 'FOO' and then the 'value' we are sorting */ /* by. The value is not printed, it is stripped off when we print. */ lines[ k ] = sprintf( " %-2s %-5s %1s%1s %-11.11s %-17.17s %-10.10s %-10.10s %4d %3s FOO %d\n", grd, euid, ears, gend, name, real_name, race, guild, idle, editor, sort_list[ k ] ); k++; } /* use either quicksort() or sort_array() */ if( str ) quicksort( 0, k - 1 ); else lines = sort_array( lines, "check_great", this_object() ); /* setup the output */ write( "\n" ); write( sprintf( "%-3s %-5s %1s%1s %-11.11s %-17.17s %-10.10s %-10.10s %4s %3s\n", "cre", "Level", "E", "G", "Name", "Real Name", "Race", "Guild", "Idle", "Ed?" ) ); write( "---------------------------------------" + "---------------------------------------\n" ); for( i = k - 1; i >= 0; i-- ) { sscanf( lines[ i ], "%s FOO %s", lines[ i ], tmp1 ); write( lines[ i ] + "\n" ); } write( sprintf( "%s %2d %s %s\n", "--------------------------------", k, "People On", "--------------------------------" ) ); return 1; } /* Function: CHECK_GREAT() */ /* */ /* This is the function used by sort_array() to determine */ /* if one line is 'larger' than the other. */ int check_great( string line1, string line2 ) { int a, b; string tmp; sscanf( line1, "%s FOO %d", tmp, a ); sscanf( line2, "%s FOO %d", tmp, b ); if( a > b ) return 1; else return -1; } /* Function: QUICKSORT() */ /* */ /* This is the quicksort() function as implemented in */ /* Sedgewicks "Algorithms" book. */ /* Some lines have multiple statements on them, this was done */ /* because the statements are intimately related. */ void quicksort( int l, int r ) { int v, t, i, j; string ts; if( r > l ) { v = sort_list[ r ]; i = l - 1; j = r; do { do { ++i; } while( sort_list[ i ] < v ); do { --j; } while( (sort_list[ j ] > v) && (j > 0) ); t = sort_list[ i ]; sort_list[ i ] = sort_list[ j ]; sort_list[ j ] = t; ts = lines[ i ]; lines[ i ] = lines[ j ]; lines[ j ] = ts; } while( j > i ); sort_list[ j ] = sort_list[ i ]; sort_list[ i ] = sort_list[ r ]; sort_list[ r ] = t; lines[ j ] = lines[ i ]; lines[ i ] = lines[ r ]; lines[ r ] = ts; quicksort( l, i - 1 ); quicksort( i + 1, r ); } }