/***************************************************************************\
[*]    ___    ____   ____   __   __  ____ [*]   ROGUE: ROM With Attitude  [*]
[*]   /#/ )  /#/  ) /#/  ) /#/  /#/ /#/   [*]    All rights reserved      [*]
[*]  /#/ <  /#/  / /#/ _  /#/  /#/ /#/--  [*]   Copyright(C) 2000-2001    [*]
[*] /#/   \(#(__/ (#(__/ (#(__/#/ (#(___  [*] Kenneth Conley (Mendanbar)  [*]
[*]  Expression of Digital Creativity..   [*]  scmud@mad.scientist.com    [*]
[-]---------------------------------------+-+-----------------------------[-]
[*] File: new_sock3.c                                                     [*]
[*] Usage: new do_sockets command for ROM                                 [*]
[*] From: rogue.dyn.dhs.org:3033                                          [*]
\***************************************************************************/

With this version I went ahead and stripped out all of the switches:
 "case CON_GET_BLAH: st = "Get Blah"; break;"

I replaced it with a table so I can use it in more than one place just
as easily as puting "socket_state(d->connected)" instead of having to
put the entire switch statement in numerous locations. Thanks Edwin for
reminding me to use this.

With this new function you will be able to see more information from
the characters instead of just Name@Socket. You will also be able to
see the connection state, Playing, Get New Class, etc. Players that
are not in the Playing state will be colored green so you can spot
non-playing sockets in an instant.

The format is taken from my StarCraft mud which is Circle based so
I wont claim I came up with that all-too-cool format. Just so you know.

With this function you will be able to see sockets that have not entered
their name yet, multiple players, complete host names, and players between
two specific numbers. There is also name and host searching to list all names
or hosts with matching likeness. (socket -h aol.com)

My color codes for Rogue are "`" you may need to change them.
The "`" key is usually located by the ~ tilde just so you know.
It's a un-used out-of-the-way key and works great! You don't have
to hold shift to input it so it makes quick-coloring easy. I have
marked in comments where you should note the color codes.

I also checked for any macros, or other such "My Mud Only" functions
and if I found any I included them so it will work for you just like
it works for me. Only the con_states need to be really worked on in
your case because you may have done things totally different than me.

Other Notes:
    The socket command for my mud Rogue has gone through a million revisions.
I have released snippets of some of the better revisions in the past but I
feel that this is the best version you will ever get. I hate reinventing the
wheel so you will notice I have a lot of macros to keep me from repeating long
if/else crap. Also I steal every bit of code I think is cool and use it ;P


:=Add IS_STAFF in merc.h near these other defines=:

#define IS_NPC(ch)		(IS_SET((ch)->act, ACT_IS_NPC))
#define IS_IMMORTAL(ch)		(get_trust(ch) >= LEVEL_IMMORTAL)
+#define IS_STAFF(ch)		(!IS_NPC(ch) && ((ch)->level >= LEVEL_IMMORTAL))
+#define RealName(ch)		(IS_NPC(ch) ? (ch)->short_descr : (ch)->name)
+#define Original(ch)		((ch)->original ? (ch)->original : (ch)->character)
+#define STATE(d)		((d)->connected)


:=At the top of act_wiz.c put=:

const struct {
    sh_int	state;
    char *	desc;
} socket_table[] = {
 { CON_PLAYING,			"Playing       "},
 { CON_GET_NAME,		"Get Name      "},
 { CON_GET_OLD_PASSWORD,	"Get Old Passwd"},
 { CON_CONFIRM_NEW_NAME,	"Confirm Name  "},
 { CON_GET_NEW_PASSWORD,	"Get New Passwd"},
 { CON_CONFIRM_NEW_PASSWORD,	"Confirm Passwd"},
 { CON_GET_LAST_NAME,		"Get Last Name "},
 { CON_GET_NEW_RACE,		"Get Race      "},
 { CON_GET_NEW_SEX,		"Get Sex       "},
 { CON_GET_NEW_CLASS,		"Get Class     "},
 { CON_GET_ALIGNMENT,		"Get Align     "},
 { CON_CHOOSE_TERM,		"Choose Term   "},
 { CON_DEFAULT_CHOICE,		"Choose Cust   "},
 { CON_GEN_GROUPS,		"Customization "},
 { CON_PICK_WEAPON,		"Choose Weap   "},
 { CON_READ_IMOTD,		"Reading IMOTD "},
 { CON_READ_MOTD,		"Reading MOTD  "},
 { CON_BREAK_CONNECT,		"LinkDead      "},
 { CON_COPYOVER_RECOVER,	"Copyover Recov"},
 { CON_NOTE_TO,			"Note To       "},
 { CON_NOTE_SUBJECT,		"Note Subject  "},
 { CON_NOTE_EXPIRE,		"Note Expire   "},
 { CON_NOTE_TEXT,		"Note Writing  "},
 { CON_NOTE_FINISH,		"Note Finish   "}
};

char *socket_state(int state) {
    sh_int i=0;

    for (i=0;socket_table[i].desc != NULL;i++)
        if (socket_table[i].state == state)
            return socket_table[i].desc;
    return "(UNKNOWN)     ";
}


:=Replace the original do_sockets with this function in act_wiz.c=:

#define USERS_FORMAT \
"format: users [-l minlevel[-maxlevel]] [-n name] [-h host] [-p] [-c] [-m]\n\r"

void do_sockets(CHAR_DATA *ch, char *argument)
/* Enhanced do_sockets by Mendanbar */
{
    CHAR_DATA	*tch;
    DESCRIPTOR_DATA *d, *match;
    SInt32	low = 0, high = MAX_LEVEL, num_can_see = 0;
    bool	playing = FALSE, matching = FALSE, complete = FALSE;
    char	buf[MSL], arg[MIL], name_search[MIL], host_search[MIL];
    char	idletime[10], *timeptr = NULL, mode;
    const char	*state;

    name_search[0] = '\0';
    host_search[0] = '\0';

    while (*argument) {
	argument = one_argument(argument, arg);
	if (*arg == '-') {
		mode = *(arg+1);
		switch (mode) {
			case 'm':	matching = TRUE;	break;
			case 'c':	complete = TRUE;	break;
			case 'p':	playing  = TRUE;	break;
			case 'l':
				playing = TRUE;
				argument = one_argument(argument, arg);
				sscanf(arg, "%d-%d", &low, &high);
				break;
			case 'n':
				playing = TRUE;
				argument = one_argument(argument, name_search);
				break;
			case 'h':
				playing = TRUE;
				argument = one_argument(argument, host_search);
				break;
			default:
				send_to_char(USERS_FORMAT, ch);
				return;
		}
	} else {
		send_to_char(USERS_FORMAT, ch);
		return;
	}
    }
    strcpy(buf, "Num Race      Name         State          Idl Login@   Site\n\r");
    strcat(buf, "--- --------- ------------ -------------- --- -------- ------------------------\n\r");

    one_argument(argument, arg);

    for (d = descriptor_list; d; d = d->next) {
	tch = Original(d);
	if ((STATE(d) == CON_PLAYING)) {
	    if (!tch)						continue;
	    if (*host_search && !strstr(d->host, host_search))	continue;
	    if (*name_search && str_cmp(RealName(tch), name_search))	continue;
	    if (!can_see(ch, tch))				continue;
	    if ((tch->level < low) || (tch->level > high))	continue;
	} else {
	    if (playing)					continue;
	    if (tch && !can_see(ch, tch))			continue;
	}
	if (matching) {
	    if (!d->host)
		continue;

	    for (match = descriptor_list; match; match = match->next) {
		CHAR_DATA *mch = Original(match);
		if (!match->host || (match == d))
			continue;
		if ((tch && !can_see(ch, tch)) || (mch && !can_see(ch, mch)))
			continue;
		if (!str_cmp(match->host, d->host))
			break;
	    }
	    if (!match)
		continue;
	}
	if (tch) {
		timeptr = asctime(localtime(&tch->logon));
		timeptr += 11;
		*(timeptr + 8) = '\0';
	}

	state = ((STATE(d) == CON_PLAYING) && d->original) ? "Switched" :
		socket_state(STATE(d));

	if ((STATE(d) == CON_PLAYING) && d->character && !IS_STAFF(d->character))
		sprintf(idletime, "%3d", tch->timer);
	else
		sprintf(idletime, "   ");

	strcat(buf, STATE(d) == CON_PLAYING ? "`n" : "`G");

	if (tch && tch->name)
		sprintf(buf + strlen(buf), "%3d [%3d %3s] %-12s %-14.14s %-3s %-8s ",
		d->descriptor, tch->level,
		tch->race < MAX_PC_RACE ? pc_race_table[tch->race].who_name : "NULL",
		tch->name, state, idletime, timeptr);
	else
		sprintf(buf + strlen(buf), "%3d     -     %-12s %-14.14s %-3s %-8s ",
		d->descriptor, "UNDEFINED", state, idletime, "00:00:00");
	sprintf(buf + strlen(buf), complete ? "[%-22s]\n\r" : "[%-22.22s]\n\r",
	(d->host && *d->host) ? d->host : "Hostname unknown");
	num_can_see++;
    }
    sprintf(buf + strlen(buf), "\n\r`n%d visible socket%s connected.\n\r",
	num_can_see, num_can_see == 1 ? "" : "s");
    page_to_char(buf, ch);
    return;
}

-------
Compile, reboot, and enjoy!
-Mendanbar <scmud@mad.scientist.com>
telnet://rogue.dyn.dhs.org:3033