To begin, open mud.h, and go down to descriptor_data, at or near line 710.
Into this structure, add the following
char * client;
At the top of comm.c we will need to define the following after the endif following this section:
/*
* Socket and TCP/IP stuff.
*/
#define IS '\x00'
#define TERMINAL_TYPE '\x18'
#define SEND '\x01'
#define SE '\xF0'
Around line 72, after the echo_on and echo_off declaration, add the following:
const unsigned char will_termtype_str [] = { IAC, WILL, TERMINAL_TYPE, '\0' };
const unsigned char wont_termtype_str [] = { IAC, WONT, TERMINAL_TYPE, '\0' };
const unsigned char do_termtype_str [] = { IAC, DO, TERMINAL_TYPE, '\0' };
const unsigned char dont_termtype_str [] = { IAC, DONT, TERMINAL_TYPE, '\0' };
const unsigned char term_call_back_str [] = { IAC, SB, TERMINAL_TYPE, IS };
const unsigned char req_termtype_str [] = { IAC, SB, TERMINAL_TYPE, SEND, IAC, SE, '\0' };
In the function new_descriptor, in comm.c, around line 843 is the descriptor initialization, to which
we must add the following:
dnew->client = STRALLOC("(unknown)");
Then, so that the information will be properly cleared, down in free_desc, around line 929, we
need to add this:
if (d->client)
STRFREE( d->client );
Now we need to establish the actual protocol by which the MUD will ask the client, and the
method in which it will respond. For this we move to the function read_from_descriptor, found
in comm.c, at or near line 1130.
We must add the following to the initial declarations of the function:
unsigned char * p;
Then, just below:
/*
* Hold horses if pending command already.
*/
if ( d->incomm[0] != '\0' )
return;
We add the following chunk:
/*
Look for a client response
*/
for (p = d->inbuf; *p; p++)
if (*p == IAC)
{
if (memcmp (p, will_termtype_str, strlen(will_termtype_str)) == 0)
{
memmove (p, &p [strlen (will_termtype_str)], strlen (&p [strlen (will_termtype_str)]) + 1);
p--;
write_to_buffer(d, req_termtype_str, 0);
}
else if (memcmp (p, wont_termtype_str, strlen(wont_termtype_str)) == 0)
{
memmove (p, &p [strlen (wont_termtype_str)], strlen (&p [strlen (wont_termtype_str)]) + 1);
p--;
}
else if (memcmp (p, term_call_back_str, strlen(term_call_back_str)) == 0)
{
char tempbuf[120];
sprintf( tempbuf, "%s", p+4);
tempbuf[strlen(tempbuf)-2] = '\0';
if (d->client)
STRFREE(d->client);
d->client = STRALLOC( tempbuf);
memmove (p, &p[strlen (p)], strlen (&p [strlen (p)]) + 1);
p--;
}
}
/* end of finding an IAC */
Around line 1599 in comm.c just before
chk = check_reconnect( d, argument, FALSE );
Add:
/* telnet negotiation asking what their client is */
write_to_buffer( d, do_termtype_str, 0 );
(If you are using copyover, or hotboot, or similar, you will have to determine the place appropriate to
place this in your copyover_recover function, most likely shortly after the descriptor initialization.)
Finally, to make our changes visible, open act_info.c, and go to the function, do_whois (line 4238).
Into the immortal only section, add the following or similar:
if ( victim->desc && victim->desc->client[0]!='\0' )
ch_printf (ch, "%s's client is: %s\n\r", victim->name, victim->desc->client);
Due to the addition of the new data to mud.h, you will need to make clean and recompile. Your mud
will now query clients, and you will be able to do with this info as you wish. Immortals will be able
to see a persons client in whois, where-ever you placed the check for it to show up.