ds2.9a12/bin/
ds2.9a12/extra/
ds2.9a12/extra/crat/
ds2.9a12/extra/creremote/
ds2.9a12/extra/mingw/
ds2.9a12/extra/wolfpaw/
ds2.9a12/fluffos-2.14-ds13/
ds2.9a12/fluffos-2.14-ds13/Win32/
ds2.9a12/fluffos-2.14-ds13/compat/
ds2.9a12/fluffos-2.14-ds13/compat/simuls/
ds2.9a12/fluffos-2.14-ds13/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/
ds2.9a12/fluffos-2.14-ds13/testsuite/clone/
ds2.9a12/fluffos-2.14-ds13/testsuite/command/
ds2.9a12/fluffos-2.14-ds13/testsuite/data/
ds2.9a12/fluffos-2.14-ds13/testsuite/etc/
ds2.9a12/fluffos-2.14-ds13/testsuite/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/master/
ds2.9a12/fluffos-2.14-ds13/testsuite/log/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/compiler/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/efuns/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/operators/
ds2.9a12/fluffos-2.14-ds13/testsuite/u/
ds2.9a12/lib/cmds/admins/
ds2.9a12/lib/cmds/common/
ds2.9a12/lib/cmds/creators/include/
ds2.9a12/lib/daemon/services/
ds2.9a12/lib/daemon/tmp/
ds2.9a12/lib/doc/
ds2.9a12/lib/doc/bguide/
ds2.9a12/lib/doc/efun/all/
ds2.9a12/lib/doc/efun/arrays/
ds2.9a12/lib/doc/efun/buffers/
ds2.9a12/lib/doc/efun/compile/
ds2.9a12/lib/doc/efun/floats/
ds2.9a12/lib/doc/efun/functions/
ds2.9a12/lib/doc/efun/general/
ds2.9a12/lib/doc/efun/mixed/
ds2.9a12/lib/doc/efun/numbers/
ds2.9a12/lib/doc/efun/parsing/
ds2.9a12/lib/doc/hbook/
ds2.9a12/lib/doc/help/classes/
ds2.9a12/lib/doc/help/races/
ds2.9a12/lib/doc/lfun/
ds2.9a12/lib/doc/lfun/all/
ds2.9a12/lib/doc/lfun/lib/abilities/
ds2.9a12/lib/doc/lfun/lib/armor/
ds2.9a12/lib/doc/lfun/lib/bank/
ds2.9a12/lib/doc/lfun/lib/bot/
ds2.9a12/lib/doc/lfun/lib/clay/
ds2.9a12/lib/doc/lfun/lib/clean/
ds2.9a12/lib/doc/lfun/lib/clerk/
ds2.9a12/lib/doc/lfun/lib/client/
ds2.9a12/lib/doc/lfun/lib/combat/
ds2.9a12/lib/doc/lfun/lib/connect/
ds2.9a12/lib/doc/lfun/lib/container/
ds2.9a12/lib/doc/lfun/lib/corpse/
ds2.9a12/lib/doc/lfun/lib/creator/
ds2.9a12/lib/doc/lfun/lib/daemon/
ds2.9a12/lib/doc/lfun/lib/damage/
ds2.9a12/lib/doc/lfun/lib/deterioration/
ds2.9a12/lib/doc/lfun/lib/donate/
ds2.9a12/lib/doc/lfun/lib/door/
ds2.9a12/lib/doc/lfun/lib/equip/
ds2.9a12/lib/doc/lfun/lib/file/
ds2.9a12/lib/doc/lfun/lib/fish/
ds2.9a12/lib/doc/lfun/lib/fishing/
ds2.9a12/lib/doc/lfun/lib/flashlight/
ds2.9a12/lib/doc/lfun/lib/follow/
ds2.9a12/lib/doc/lfun/lib/ftp_client/
ds2.9a12/lib/doc/lfun/lib/ftp_data_connection/
ds2.9a12/lib/doc/lfun/lib/fuel/
ds2.9a12/lib/doc/lfun/lib/furnace/
ds2.9a12/lib/doc/lfun/lib/genetics/
ds2.9a12/lib/doc/lfun/lib/holder/
ds2.9a12/lib/doc/lfun/lib/id/
ds2.9a12/lib/doc/lfun/lib/interactive/
ds2.9a12/lib/doc/lfun/lib/lamp/
ds2.9a12/lib/doc/lfun/lib/leader/
ds2.9a12/lib/doc/lfun/lib/light/
ds2.9a12/lib/doc/lfun/lib/limb/
ds2.9a12/lib/doc/lfun/lib/living/
ds2.9a12/lib/doc/lfun/lib/load/
ds2.9a12/lib/doc/lfun/lib/look/
ds2.9a12/lib/doc/lfun/lib/manipulate/
ds2.9a12/lib/doc/lfun/lib/meal/
ds2.9a12/lib/doc/lfun/lib/messages/
ds2.9a12/lib/doc/lfun/lib/player/
ds2.9a12/lib/doc/lfun/lib/poison/
ds2.9a12/lib/doc/lfun/lib/position/
ds2.9a12/lib/doc/lfun/lib/post_office/
ds2.9a12/lib/doc/lfun/lib/potion/
ds2.9a12/lib/doc/lfun/lib/room/
ds2.9a12/lib/doc/lfun/lib/server/
ds2.9a12/lib/doc/lfun/lib/spell/
ds2.9a12/lib/doc/lfun/lib/torch/
ds2.9a12/lib/doc/lfun/lib/vendor/
ds2.9a12/lib/doc/lfun/lib/virt_sky/
ds2.9a12/lib/doc/lfun/lib/weapon/
ds2.9a12/lib/doc/lfun/lib/worn_storage/
ds2.9a12/lib/doc/lpc/basic/
ds2.9a12/lib/doc/lpc/concepts/
ds2.9a12/lib/doc/lpc/constructs/
ds2.9a12/lib/doc/lpc/etc/
ds2.9a12/lib/doc/lpc/intermediate/
ds2.9a12/lib/doc/lpc/types/
ds2.9a12/lib/doc/misc/
ds2.9a12/lib/doc/old/
ds2.9a12/lib/domains/
ds2.9a12/lib/domains/Praxis/adm/
ds2.9a12/lib/domains/Praxis/attic/
ds2.9a12/lib/domains/Praxis/cemetery/mon/
ds2.9a12/lib/domains/Praxis/data/
ds2.9a12/lib/domains/Praxis/death/
ds2.9a12/lib/domains/Praxis/mountains/
ds2.9a12/lib/domains/Praxis/obj/armour/
ds2.9a12/lib/domains/Praxis/obj/magic/
ds2.9a12/lib/domains/Praxis/obj/weapon/
ds2.9a12/lib/domains/Praxis/orc_valley/
ds2.9a12/lib/domains/Ylsrim/
ds2.9a12/lib/domains/Ylsrim/adm/
ds2.9a12/lib/domains/Ylsrim/armor/
ds2.9a12/lib/domains/Ylsrim/broken/
ds2.9a12/lib/domains/Ylsrim/fish/
ds2.9a12/lib/domains/Ylsrim/meal/
ds2.9a12/lib/domains/Ylsrim/npc/
ds2.9a12/lib/domains/Ylsrim/obj/
ds2.9a12/lib/domains/Ylsrim/virtual/
ds2.9a12/lib/domains/Ylsrim/weapon/
ds2.9a12/lib/domains/campus/adm/
ds2.9a12/lib/domains/campus/etc/
ds2.9a12/lib/domains/campus/meals/
ds2.9a12/lib/domains/campus/save/
ds2.9a12/lib/domains/campus/txt/ai/charles/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.9a12/lib/domains/campus/txt/ai/charly/
ds2.9a12/lib/domains/campus/txt/ai/charly/bak/
ds2.9a12/lib/domains/campus/txt/jenny/
ds2.9a12/lib/domains/cave/doors/
ds2.9a12/lib/domains/cave/etc/
ds2.9a12/lib/domains/cave/meals/
ds2.9a12/lib/domains/cave/weap/
ds2.9a12/lib/domains/default/creator/
ds2.9a12/lib/domains/default/doors/
ds2.9a12/lib/domains/default/etc/
ds2.9a12/lib/domains/default/vehicles/
ds2.9a12/lib/domains/default/virtual/
ds2.9a12/lib/domains/default/weap/
ds2.9a12/lib/domains/town/txt/shame/
ds2.9a12/lib/domains/town/virtual/
ds2.9a12/lib/domains/town/virtual/bottom/
ds2.9a12/lib/domains/town/virtual/space/
ds2.9a12/lib/estates/
ds2.9a12/lib/ftp/
ds2.9a12/lib/lib/comp/
ds2.9a12/lib/lib/daemons/
ds2.9a12/lib/lib/daemons/include/
ds2.9a12/lib/lib/lvs/
ds2.9a12/lib/lib/user/
ds2.9a12/lib/lib/virtual/
ds2.9a12/lib/log/
ds2.9a12/lib/log/adm/
ds2.9a12/lib/log/archive/
ds2.9a12/lib/log/chan/
ds2.9a12/lib/log/errors/
ds2.9a12/lib/log/law/adm/
ds2.9a12/lib/log/law/email/
ds2.9a12/lib/log/law/names/
ds2.9a12/lib/log/law/sites-misc/
ds2.9a12/lib/log/law/sites-register/
ds2.9a12/lib/log/law/sites-tempban/
ds2.9a12/lib/log/law/sites-watch/
ds2.9a12/lib/log/open/
ds2.9a12/lib/log/reports/
ds2.9a12/lib/log/router/
ds2.9a12/lib/log/secure/
ds2.9a12/lib/log/watch/
ds2.9a12/lib/obj/book_source/
ds2.9a12/lib/obj/include/
ds2.9a12/lib/powers/prayers/
ds2.9a12/lib/powers/spells/
ds2.9a12/lib/realms/template/adm/
ds2.9a12/lib/realms/template/area/armor/
ds2.9a12/lib/realms/template/area/npc/
ds2.9a12/lib/realms/template/area/obj/
ds2.9a12/lib/realms/template/area/room/
ds2.9a12/lib/realms/template/area/weap/
ds2.9a12/lib/realms/template/bak/
ds2.9a12/lib/realms/template/cmds/
ds2.9a12/lib/save/kills/o/
ds2.9a12/lib/secure/cfg/classes/
ds2.9a12/lib/secure/cmds/builders/
ds2.9a12/lib/secure/cmds/creators/include/
ds2.9a12/lib/secure/cmds/players/
ds2.9a12/lib/secure/cmds/players/include/
ds2.9a12/lib/secure/daemon/imc2server/
ds2.9a12/lib/secure/daemon/include/
ds2.9a12/lib/secure/lib/
ds2.9a12/lib/secure/lib/include/
ds2.9a12/lib/secure/lib/net/include/
ds2.9a12/lib/secure/lib/std/
ds2.9a12/lib/secure/log/adm/
ds2.9a12/lib/secure/log/bak/
ds2.9a12/lib/secure/log/intermud/
ds2.9a12/lib/secure/log/network/
ds2.9a12/lib/secure/modules/
ds2.9a12/lib/secure/npc/
ds2.9a12/lib/secure/obj/include/
ds2.9a12/lib/secure/room/
ds2.9a12/lib/secure/save/
ds2.9a12/lib/secure/save/backup/
ds2.9a12/lib/secure/save/boards/
ds2.9a12/lib/secure/tmp/
ds2.9a12/lib/secure/upgrades/files/
ds2.9a12/lib/secure/verbs/creators/
ds2.9a12/lib/std/board/
ds2.9a12/lib/std/lib/
ds2.9a12/lib/tmp/
ds2.9a12/lib/verbs/admins/include/
ds2.9a12/lib/verbs/builders/
ds2.9a12/lib/verbs/common/
ds2.9a12/lib/verbs/common/include/
ds2.9a12/lib/verbs/creators/
ds2.9a12/lib/verbs/creators/include/
ds2.9a12/lib/verbs/rooms/
ds2.9a12/lib/verbs/rooms/include/
ds2.9a12/lib/www/client/
ds2.9a12/lib/www/errors/
ds2.9a12/lib/www/images/
ds2.9a12/lib/www/lpmuds/downloads_files/
ds2.9a12/lib/www/lpmuds/intermud_files/
ds2.9a12/lib/www/lpmuds/links_files/
ds2.9a12/win32/
/*    /cmd *    from Foundation II
 *    a listing of users for creators and ambassadors
 *    created by Descartes of Borg 940724
 */

#include <lib.h>
#include <localtime.h>
#include <config.h>
#include <dirs.h>
#include <daemons.h>

inherit LIB_DAEMON;

static private int *__SortFlags;

static private string query_time();
private string calculateFormatString(int screenSize);
object *whom, *who, *display;
string *args;

string GetBaseName(object ob){
    string ret;
    if(ob) ret = capitalize(last_string_element(base_name(ob),"/"));
    if(!ret && ob) ret = ob->GetCapName();
    if(!ret) ret = "";
    return ret;
}

mixed room_env(object ob){
    string *riders;
    object env = environment(ob);
    if(!env) return 0;
    if(!living(env)) return env;
    if(arrayp(riders = env->GetRiders()) && member_array(ob, riders) != -1 &&
      environment(env)) env = environment(env);
    return env;
}

int cmd(string str) {
    string msg, tmp1, tmp2;
    int i, maxi, aflag, bflag, cflag, eflag, gflag, hflag, lflag, mflag;
    int nflag, pflag, rflag, sflag, uflag;
    int screenSize;
    string formatString;
    string bar;

    whom = ({});

    if(!str || str == "" || strlen(str) == 1 || str[0] != '-') args = ({});
    else args = explode(str[1..strlen(str)-1], "");
    i = sizeof(args);
    while(i--) {
        switch(args[i]) {
        case "a": aflag = 1; break; /* list arches */
        case "b": bflag = 1; break; /* list ambassadors */
        case "c": cflag = 1; break; /* list creators */
        case "e": eflag = 1; break; /* sort by race */
        case "g": gflag = 1; break; /* sort by age */
        case "h": hflag = 1; break; /* list high mortals */
        case "l": lflag = 1; break; /* sort by level */
        case "m": mflag = 1; break; /* page through eventPage */
        case "n": nflag = 1; break; /* list newbies */
        case "p": pflag = 1; break; /* list regular mortals */
        case "r": rflag = 1; break; /* sort by realm location */
        case "s": sflag = 1; break; /* sort by class */
        case "u": uflag = 1; break; /* list undead */
        }
    }
    who = filter(users(), "filter_invis", this_object());
    foreach(object real_person in who){
        if(sizeof(base_name(real_person))) whom += ({ real_person });
    }

    who = whom;

    if(!aflag && !bflag && !cflag && !hflag && !nflag && !pflag && !uflag)
        display = who;
    else {
        display = ({});
        if(aflag) display += filter(who, "filter_arches", this_object());
        if(bflag) display += filter(who, "filter_ambass", this_object());
        if(cflag) display += filter(who, "filter_cres", this_object());
        if(hflag) display += filter(who, "filter_hms", this_object());
        if(nflag) display += filter(who, "filter_newbie", this_object());
        if(pflag) display += filter(who, "filter_mortal", this_object());
        if(uflag) display += filter(who, "filter_undead", this_object());
        display = distinct_array(display);
    }
    if(!eflag && !gflag && !lflag && !rflag && !sflag) 
        maxi = sizeof(display=sort_array(display,"general_sort",this_object()));
    else {
        __SortFlags = ({ eflag, gflag, lflag, rflag, sflag });
        maxi = sizeof(display = sort_array(display,"special_sort",this_object()));
    }
    screenSize = ((int*)this_player()->GetScreen())[0];
    formatString = calculateFormatString(screenSize);
    bar = "--------------------------------------------------------------------------";
    for(i = 75; i < screenSize; i++) bar += "-";
    bar += "\n";
    msg = bar;
    tmp1 = " " + maxi + ((maxi != 1) ? " people" : " person") + " in current sort ";
    tmp2 = query_time() + " ";
    i = sizeof(tmp1) + sizeof(tmp2);
    msg += tmp1;
    for(i = sizeof(tmp1) + sizeof(tmp2) + 1; i < screenSize; i++) msg += " ";
    msg += tmp2 + "\n";
    msg += bar;
    msg += implode(map_array(display, "map_info", this_object(), formatString), "\n") + "\n";
    msg += bar;
    msg += center(mud_name(), screenSize - 1);
    if(!check_string_length()) mflag = 1;
    if(!mflag && check_string_length(msg)) this_player()->eventPrint(msg);
    else print_long_string(this_player(),msg);
    return 1;
}

static int filter_invis(object ob) {
    if(!ob || !sizeof(base_name(ob))) return 0;
    if(!((int)ob->GetKeyName())) return 0;
    if(!((int)ob->GetInvis(this_player()))) return 1;
    if(archp(this_player())) return 1;
    if(archp(ob)) return 0;
    return 1;
}

static int filter_arches(object ob) { return archp(ob); }

static int filter_ambass(object ob) { return ambassadorp(ob); }

static int filter_cres(object ob) { return (creatorp(ob) && !archp(ob)); }

static int filter_hms(object ob) { return high_mortalp(ob); }

static int filter_newbie(object ob) {
    return (!creatorp(ob) && !ambassadorp(ob) && (MAX_NEWBIE_LEVEL >=
        (int)ob->GetLevel()));
}

static int filter_mortal(object ob) {
    if(creatorp(ob) || high_mortalp(ob) || ambassadorp(ob)) return 0;
    if((int)ob->GetLevel() <= MAX_NEWBIE_LEVEL) return 0;
    return 1;
}

static int filter_undead(object ob) { return (int)ob->query_ghost(); }

static int general_sort(object alpha, object beta) {
    int x, y;

    if(archp(alpha)) {
        if(!archp(beta)) return -1;
        else return strcmp((string)GetBaseName(alpha), 
              (string)GetBaseName(beta));
    }
    else if(archp(beta)) return 1;
    if(creatorp(alpha)) {
        if(!creatorp(beta)) return -1;
        else return strcmp((string)GetBaseName(alpha),
              (string)GetBaseName(beta));
    }
    else if(creatorp(beta)) return 1;
    if(ambassadorp(alpha)) {
        if(!ambassadorp(beta)) return -1;
        else return strcmp((string)GetBaseName(alpha),
              (string)GetBaseName(beta));
    }
    else if(ambassadorp(beta)) return 1;
    if((x = (int)alpha->GetLevel()) > (y = (int)beta->GetLevel()))
        return -1;
    else if(x < y) return 1;
    else return strcmp((string)GetBaseName(alpha),
          (string)GetBaseName(beta));
}

static int special_sort(object alpha, object beta) {
    string a, b;
    int x, y;

    if(__SortFlags[4]) {
        if((a=(string)alpha->query_class())!=(b=(string)beta->query_class())) {
            if(!a) a = "zzzz";
            if(!b) b= "zzzz";
            return strcmp(a, b);
        }
    }
    if(__SortFlags[0]) {
        if((a=(string)alpha->query_race()) != (b=(string)beta->query_race())) {
            if(!a) a = "zzzz";
            if(!b) b = "zzzz";
            return strcmp(a, b);
        }
    }
    if(__SortFlags[3]) {
        if((a = file_name(room_env(alpha))) != 
          (b = file_name(room_env(beta)))) return strcmp(a, b);
    }
    if(__SortFlags[2]) {
        if((x = (int)alpha->GetLevel()) != (y=(int)beta->GetLevel())) {
            if(x > y) return -1;
            else return 1;
        }
    }
    if(__SortFlags[1]) {
        if((x = (int)alpha->GetAge()) != (y = (int)beta->GetAge())) {
            if(x > y) return -1;
            else return 1;
        }
    }
    return 0;
}

private string calculateFormatString(int screenSize) {
    int nomSize = (((screenSize - 21) * 12) / 54);
    int ipSize = (((screenSize - 21) * 18) / 54);
    int envSize = (((screenSize - 21) * 24) / 54);

    if(nomSize < 12) nomSize = 12;
    if(ipSize < 18) ipSize = 18;
    if(envSize < 24) envSize = 24;

    return "%:-5s %:-2s %:-" + nomSize + "s %:-" + ipSize
    + "s %:-5s %:-3s %:-" + envSize + "s";
}

static string map_info(object ob, string formatString) {
    string age, nom, blk, lev, ip, env, idle;
    int x;

    x = (int)ob->GetAge();
    if(x > 86400) age = sprintf("%:-2d D", x/86400);
    else if(x > 3600) age = sprintf("%:-2d h", x/3600);
    else age = sprintf("%:-2d m", x/60);
    nom = (string)GetBaseName(ob);
    if((int)ob->GetInvis()) nom = "("+nom+")";
    if(in_edit(ob) || in_input(ob)) nom = "["+nom+"]";
    if(creatorp(ob)) {
        if((int)ob->GetBlocked("all")) blk = "ACG";
        else {
            if((int)ob->GetBlocked("cre")) blk = " C";
            else blk = "  ";
            if((int)ob->GetBlocked("gossip")) blk += "G";
            else blk += " ";
        }
    }
    else blk = "   ";
    if(!(x = (int)ob->GetLevel())) lev = "-";
    else lev = x+"";
    if((x = query_idle(ob)) < 60) idle = "";
    else if(x >= 2600) idle = sprintf("%:-3d h", x/3600);
    else idle = sprintf("%:-2d m", x/60);
    ip = query_ip_name(ob);
    if(!room_env(ob)) env = "no environment";
    else env = file_name(room_env(ob));
    if(!strsrch(env, REALMS_DIRS)) 
        env = "~" + env[strlen(REALMS_DIRS)+1..];
    else if(!strsrch(env, DOMAINS_DIRS))
        env = "^"+env[strlen(DOMAINS_DIRS)+1..strlen(env)-1];
    return sprintf(formatString, age, lev, nom, ip, idle, blk, env);
}

static private string query_time() {
    string tzone;
    int x, offset;

    tzone = query_tz();
    offset = (int)TIME_D->GetOffset(tzone);
    offset += EXTRA_TIME_OFFSET;
    if(query_os_type() != "windows" ) x = offset * 3600;
    else x = 0;
    return tzone + " time is: " + ctime(time() + x);
}

void help() {
    message("help", "Syntax: people [-abceghlmnprsu]\n\n"
      "Gives you a listing of people on "+mud_name()+".  Output is "
      "formatted into columns with the following meanings:\n"
      "    amount of time spent total on "+mud_name()+"\n"
      "    level\n"
      "    name\n"
      "    address from which the person is connecting\n"
      "    amount of time idle\n"
      "    blocking information, if any... A is all, C cre, G gossip\n"
      "    current environment file name\n\n"
      "Command flags have the following meanings:\n"
      "    -a list all arches\n"
      "    -b list all ambassadors\n"
      "    -c list all non-arch creators\n"
      "    -e sort the listing by race\n"
      "    -g sort the listing by age\n"
      "    -h list all high mortals\n"
      "    -l sort the listing by level\n"
      "    -m pipe the listing through the more pager\n"
      "    -n list all newbies\n"
      "    -p list all non-newbie and non-high mortal mortals\n"
      "    -r sort the listing by current environment\n"
      "    -s sort the listing by class\n"
      "    -u list all undead people\n\n"
      "People in the editor or in mail or posting will be marked with [].  "
      "People who are invisible to others, but not to you will be marked "
      "with ().  The default sort is by arch, then by creator, then by "
      "ambassador, then by level.  You can perform multiple sorts, but "
      "you cannot change the priority.  Sorts priority is: class, race, "
      "realm, level, age.  You can also include multiple groups in your "
      "listing.\n\nSee also: who, users", this_player());
}