phantasia4/
phantasia4/conf/
phantasia4/phantasia/bin/
phantasia4/phantasia/src/utilities/
phantasia4/public_html/cgi-bin/
/*
 * info.c       Routines to retriving information
 */

#include "include.h"

/************************************************************************
/
/ FUNCTION NAME: struct examine_t *Do_create_examine(c)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       struct client_t c - pointer to the main client strcture
/
/ RETURN VALUE: 
/	char - character the describes the character
/
/ MODULES CALLED: strcpy()
/
/ DESCRIPTION:
/       Return a string describing the player type.
/       King, council, valar, supercedes other types.
/       The first character of the string is '*' if the player
/       has a crown.
/       If 'shortflag' is TRUE, return a 3 character string.
/
*************************************************************************/

struct examine_t *Do_create_examine(struct client_t *c, struct game_t *requestor)
{
    struct examine_t *examine_ptr;

	/* create the strcture */
    examine_ptr = (struct examine_t *)Do_malloc(SZ_EXAMINE);

	/* lock the realm for the next two calls */
    Do_lock_mutex(&c->realm->realm_lock);

	/* to titles and specific information */
    Do_make_character_title(c, c->game, &examine_ptr->title);
    strcat(examine_ptr->title, "\n");

	/* copy over the coords or description */
    if (Do_show_character_coords(requestor, c->game)) {

	sprintf(examine_ptr->location, "(%.0lf, %.0lf)\n", c->player.x,
		c->player.y);
    }
    else {
	strcpy(examine_ptr->location, c->player.area);
	strcat(examine_ptr->location, "\n");
    }
    Do_unlock_mutex(&c->realm->realm_lock);

	/* determine if the network is printable */
    if (!c->addressResolved || c->wizard > 2) {
        strcpy(examine_ptr->network, "<unavailable>\n");
    }
    else {
        strcpy(examine_ptr->network, c->network);
	strcat(examine_ptr->network, "\n");
    }

	/* determine when the next level will occur */
    examine_ptr->nextLevel = 1800 * (c->player.level + 1) *
	    (c->player.level + 1);

	/* format player gender */
    if (c->player.gender == MALE) {
	strcpy(examine_ptr->gender, "Male\n");
    }
    else {
	strcpy(examine_ptr->gender, "Female\n");
    }

    Do_format_time(examine_ptr->time_played, c->player.time_played +
	    time(NULL) - c->player.last_load);

    if (c->wizard > 2) {
        strcpy(examine_ptr->account, "<unavailable>\n");
    }
    else if (!strcmp(c->account,"eyhung")) {
        strcpy(examine_ptr->account, c->player.name);
        strcat(examine_ptr->account, "\n");
    }
    else {
        strcpy(examine_ptr->account, c->account);
        strcat(examine_ptr->account, "\n");
    }

    Do_true_false(&examine_ptr->cloaked, c->player.cloaked);
    Do_true_false(&examine_ptr->blind, c->player.blind);
    Do_true_false(&examine_ptr->virgin, c->player.virgin);
    Do_true_false(&examine_ptr->palantir, c->player.palantir);
    Do_true_false(&examine_ptr->blessing, c->player.blessing);
    Do_true_false(&examine_ptr->ring, c->player.ring_type);

    ctime_r(&c->player.last_load, examine_ptr->date_loaded);
    ctime_r(&c->player.date_created, examine_ptr->date_created);

    examine_ptr->channel = c->channel;
    examine_ptr->level = c->player.level;
    examine_ptr->experience = c->player.experience;
    examine_ptr->energy = c->player.energy;
    examine_ptr->max_energy = c->player.max_energy;
    examine_ptr->strength = c->player.strength * 
                            (1 + sqrt(c->player.sword) * N_SWORDPOWER);
    examine_ptr->max_strength = c->player.max_strength;
    examine_ptr->quickness = c->player.quickness;
    examine_ptr->max_quickness = c->player.max_quickness;
    examine_ptr->mana = c->player.mana;
    examine_ptr->brains = c->player.brains;
    examine_ptr->magiclvl = c->player.magiclvl;
    examine_ptr->poison = c->player.poison;
    examine_ptr->sin = c->player.sin;
    examine_ptr->lives = c->player.lives;
    examine_ptr->gold = c->player.gold;
    examine_ptr->gems = c->player.gems;
    examine_ptr->sword = c->player.sword;
    examine_ptr->shield = c->player.shield;
    examine_ptr->quicksilver = c->player.quicksilver;
    examine_ptr->holywater = c->player.holywater;
    examine_ptr->amulets = c->player.amulets;
    examine_ptr->charms = c->player.charms;
    examine_ptr->crowns = c->player.crowns;
    examine_ptr->age = c->player.age;
    examine_ptr->degenerated = c->player.degenerated;

    return examine_ptr;
}


/************************************************************************
/
/ FUNCTION NAME: Do_make_character_title(struct client_t *c, struct game_t *game_ptr, char *theTitle)
/
/ FUNCTION: find location in player file of given name
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       char *name - name of character to look for
/       struct player *playerp - pointer of structure to fill
/
/ RETURN VALUE: location of player if found, -1 otherwise
/
/ MODULES CALLED: fread(), fseek(), strcmp()
/
/ GLOBAL INPUTS: Wizard, *Playersfp
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/       Search the player file for the player of the given name.
/       If player is found, fill structure with player data.
/
*************************************************************************/

Do_make_character_title(struct client_t *c, struct game_t *game_ptr, char *theTitle)
{
    char title[20];

/* make sure the realm is locked before calling this function */

    title[0] = '\0';

    if (game_ptr->description->wizard > 2) {
        strcpy(title, "Wizard ");
    } else if (game_ptr->description->wizard == 2) {
        strcpy(title, "Apprentice ");
    }
        

    switch (game_ptr->description->special_type) {

    case SC_KNIGHT:

	if (game_ptr->description->gender == MALE) {
	    strcpy(title, "Sir ");
	}
	else {
	    strcpy(title, "Dame ");
	}
	break;

    case SC_STEWARD:

	strcpy(title, "Steward ");
	break;

    case SC_KING:

	if (game_ptr->description->gender == MALE) {
	    strcpy(title, "King ");
	}
	else {
	    strcpy(title, "Queen ");
	}
	break;

    case SC_COUNCIL:
    case SC_EXVALAR:

	if (game_ptr->description->gender == MALE) {
	    strcpy(title, "Councilman ");
	}
	else {
	    strcpy(title, "Councilwoman ");
	}
	break;

    case SC_VALAR:

	strcpy(title, "Valar ");
        break;
    }

    sprintf(theTitle, "%s%s the %s",  title, game_ptr->description->name,
	    c->realm->charstats[game_ptr->description->type].class_name);

    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_show_character_coords(struct game_t *requestor, struct game *requestee)
/
/ FUNCTION: find location in player file of given name
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       char *name - name of character to look for
/       struct player *playerp - pointer of structure to fill
/
/ RETURN VALUE: location of player if found, -1 otherwise
/
/ MODULES CALLED: fread(), fseek(), strcmp()
/
/ GLOBAL INPUTS: Wizard, *Playersfp
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/       Search the player file for the player of the given name.
/       If player is found, fill structure with player data.
/
*************************************************************************/

int Do_show_character_coords(struct game_t *requestor, struct game_t *requestee)
{

/* the realm should be locked before calling this procedure */

	/* Show name if in place like Valhalla */
    if (requestee->useLocationName) {
	return FALSE;
    }

	/* Show coords if requestee is requestor */
    if (requestee == requestor) {
	return TRUE;
    }

	/* Show name if requestor descriptionless */
    if (requestor->description == NULL) {
	return FALSE;
    }

	/* Show name if requestee is virtual */
    if (requestee->virtual) {
	return FALSE;
    }

	/* Show coords if the requestor is a game wizard */
    if (requestor->description->wizard > 2) {
	return TRUE;
    }

	/* Show name if requestor is blind */
    if (requestor->description->blind) {
	return FALSE;
    }

	/* Show coords if requestor has a palantir */
    if (requestor->description->palantir) {
	return TRUE;
    }

	/* Show name if requestee is not special and outside requestor */
    if (requestee->description->special_type == SC_NONE &&
	    requestee->circle > requestor->circle) {

	return FALSE;
    }

	/* Show name if requestee is special and far out */
    if (requestee->description->special_type != SC_NONE &&
	    requestee->circle > 400) {
	return FALSE;
    }

	/* Show name if requestee is cloaked */
    if (requestee->description->cloaked) {
	return FALSE;
    }

        /* Show name if requestor is experimento and low-level */
    if ((requestor->description->type == C_EXPER) && 
        (requestor->description->level < 50)) {
        return FALSE;
    }

	/* Otherwise show coords (Got all that?) */
    return TRUE;
}


/************************************************************************
/
/ FUNCTION NAME: Do_format_time(struct client_t *c, char *theString, int theTime)
/
/ FUNCTION: find location in player file of given name
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       char *name - name of character to look for
/       struct player *playerp - pointer of structure to fill
/
/ RETURN VALUE: location of player if found, -1 otherwise
/
/ MODULES CALLED: fread(), fseek(), strcmp()
/
/ GLOBAL INPUTS: Wizard, *Playersfp
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/       Search the player file for the player of the given name.
/       If player is found, fill structure with player data.
/
*************************************************************************/

Do_format_time(char *theString, int theTime)
{
    int minutes, hours;

    hours = theTime / 3600;
    theTime -= hours * 3600;

    minutes = theTime / 60;
    theTime -= minutes * 60;

    sprintf(theString, "%2.2d:%2.2d:%2.2d\n", hours, minutes, theTime);

    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_true_false(char *theString, int theBool)
/
/ FUNCTION: find location in player file of given name
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       char *name - name of character to look for
/       struct player *playerp - pointer of structure to fill
/
/ RETURN VALUE: location of player if found, -1 otherwise
/
/ MODULES CALLED: fread(), fseek(), strcmp()
/
/ GLOBAL INPUTS: Wizard, *Playersfp
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/       Search the player file for the player of the given name.
/       If player is found, fill structure with player data.
/
*************************************************************************/

Do_true_false(char *theString, int theBool)
{
    if (theBool) {
	strcpy(theString, "Yes\n");
    }
    else {
	strcpy(theString, "No\n");
    }
}


/************************************************************************
/
/ FUNCTION NAME: Do_examine_character(c, struct examine_t *theInfo)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 01/04/01
/
/ ARGUMENTS:
/       struct client_t c - pointer to the main client strcture
/
/ RETURN VALUE: 
/	char - character the describes the character
/
/ MODULES CALLED: strcpy()
/
/ DESCRIPTION:
/       Return a string describing the player type.
/       King, council, valar, supercedes other types.
/       The first character of the string is '*' if the player
/       has a crown.
/       If 'shortflag' is TRUE, return a 3 character string.
/
*************************************************************************/

Do_examine_character(struct client_t *c, struct examine_t *theInfo)
{

    Do_send_int(c, PLAYER_INFO_PACKET);

    Do_send_string(c, theInfo->title);
    Do_send_string(c, theInfo->location);

    Do_send_string(c, theInfo->account);
    Do_send_string(c, theInfo->network);
    Do_send_int(c, theInfo->channel);

    Do_send_double(c, theInfo->level);
    Do_send_double(c, theInfo->experience);
    Do_send_double(c, theInfo->nextLevel);

    Do_send_double(c, theInfo->energy);
    Do_send_double(c, theInfo->max_energy);
    Do_send_double(c, theInfo->shield);
    Do_send_double(c, theInfo->strength);
    Do_send_double(c, theInfo->max_strength);
    Do_send_double(c, theInfo->sword);
    Do_send_float(c, theInfo->quickness);
    Do_send_float(c, theInfo->max_quickness);
    Do_send_float(c, theInfo->quicksilver);
    Do_send_double(c, theInfo->brains);
    Do_send_double(c, theInfo->magiclvl);
    Do_send_double(c, theInfo->mana);
    Do_send_string(c, theInfo->gender);
    Do_send_fpfloat(c, theInfo->poison);
    Do_send_fpfloat(c, theInfo->sin);
    Do_send_int(c, theInfo->lives);

    Do_send_double(c, theInfo->gold);
    Do_send_double(c, theInfo->gems);
    Do_send_int(c, theInfo->holywater);
    Do_send_int(c, theInfo->amulets);
    Do_send_int(c, theInfo->charms);
    Do_send_int(c, theInfo->crowns);
    Do_send_string(c, theInfo->virgin);
    Do_send_string(c, theInfo->blessing);
    Do_send_string(c, theInfo->palantir);
    Do_send_string(c, theInfo->ring);

    Do_send_string(c, theInfo->cloaked);
    Do_send_string(c, theInfo->blind);
    Do_send_int(c, theInfo->age);
    Do_send_int(c, theInfo->degenerated);
    Do_send_string(c, theInfo->time_played);
    Do_send_string(c, theInfo->date_loaded);
    Do_send_string(c, theInfo->date_created);

    return;
}



/************************************************************************
/
/ FUNCTION NAME: struct details_t *Do_create_detail(c)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS:
/       struct client_t c - pointer to the main client strcture
/
/ RETURN VALUE: 
/	char - character the describes the character
/
/ MODULES CALLED: strcpy()
/
/ DESCRIPTION:
/       Return a string describing the player type.
/       King, council, valar, supercedes other types.
/       The first character of the string is '*' if the player
/       has a crown.
/       If 'shortflag' is TRUE, return a 3 character string.
/
*************************************************************************/

struct detail_t *Do_create_detail(struct client_t *c)
{
    struct detail_t *detail_ptr;
    struct account_t theAccount;

	/* create the strcture */
    detail_ptr = (struct detail_t *)Do_malloc(SZ_DETAIL);

	/* character information */
    strcpy(detail_ptr->modifiedName, c->modifiedName);
    strcat(detail_ptr->modifiedName, "\n");
    strcpy(detail_ptr->name, c->player.name);
    strcat(detail_ptr->name, "\n");
    Do_true_false(detail_ptr->faithful, c->player.faithful);
    strcpy(detail_ptr->parentAccount, c->player.parent_account);
    strcat(detail_ptr->parentAccount, "\n");
    strcpy(detail_ptr->charParentNetwork, c->player.parent_network);
    strcat(detail_ptr->charParentNetwork, "\n");
    Do_look_account(c, &(c->account), &theAccount);
    detail_ptr->playerMutes = theAccount.muteCount;

	/* account information */
    strcpy(detail_ptr->account, c->account);
    strcat(detail_ptr->account, "\n");
    strcpy(detail_ptr->email, c->email);
    strcat(detail_ptr->email, "\n");
    strcpy(detail_ptr->accParentNetwork, c->parentNetwork);
    strcat(detail_ptr->accParentNetwork, "\n");

	/* connection information */
    strcpy(detail_ptr->IP, c->IP);
    strcat(detail_ptr->IP, "\n");
    strcpy(detail_ptr->network, c->network);
    strcat(detail_ptr->network, "\n");
    detail_ptr->machineID = c->machineID;
    ctime_r(&c->date_connected, detail_ptr->dateConnected);
    
    return detail_ptr;
}


/************************************************************************
/
/ FUNCTION NAME: Do_detail_connection(c, struct detail_t *theInfo)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS:
/       struct client_t c - pointer to the main client strcture
/
/ RETURN VALUE: 
/	char - character the describes the character
/
/ MODULES CALLED: strcpy()
/
/ DESCRIPTION:
/       Return a string describing the player type.
/       King, council, valar, supercedes other types.
/       The first character of the string is '*' if the player
/       has a crown.
/       If 'shortflag' is TRUE, return a 3 character string.
/
*************************************************************************/

Do_detail_connection(struct client_t *c, struct detail_t *theInfo)
{ 

    Do_send_int(c, CONNECTION_DETAIL_PACKET);

    Do_send_string(c, theInfo->modifiedName);
    Do_send_string(c, theInfo->name);
    Do_send_string(c, theInfo->faithful);
    Do_send_string(c, theInfo->parentAccount);
    Do_send_string(c, theInfo->charParentNetwork);
    Do_send_int(c, theInfo->playerMutes);

    Do_send_string(c, theInfo->account);
    Do_send_string(c, theInfo->email);
    Do_send_string(c, theInfo->accParentNetwork);

    Do_send_string(c, theInfo->IP);
    Do_send_string(c, theInfo->network);
    Do_send_int(c, theInfo->machineID);
    Do_send_string(c, theInfo->dateConnected);

    return;
}


/***************************************************************************
/ FUNCTION NAME: Do_last_load_info(struct client_t *c)
/
/ FUNCTION: Default activity when no events are pending
/
/ AUTHOR:  Brian Kelly, 01/04/01
/
/ ARGUMENTS: 
/	struct client_t *c - structure containing all thread info
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/       Process arguments, initialize program, and loop forever processing
/       player input.
/
****************************************************************************/

Do_last_load_info(struct client_t *c)
{
    char string_buffer[SZ_LINE];
    char string_buffer2[SZ_LINE];
    long answer;
    int exceptionFlag, wizType = 0;
    char wizNetwork[SZ_FROM], wizAccount[SZ_NAME], wizCharacter[SZ_NAME];
    FILE *wizard_file;

	/* quick character report */
    if (c->player.bad_passwords) {

        sprintf(string_buffer, "There have been %d failed login attempts with this character since last successful login.\n", c->player.bad_passwords);

        Do_send_line(c, string_buffer);
    }

    if (c->player.load_count == 0) {

        sprintf(string_buffer, "Welcome %s.  If this is your first journey into the realm, there is a good quick overview under the \"Help\" button that will appear after you hit \"More\".\n", c->player.name);

    }
    else {

            /* convert the last time and remove the "\n". */
	ctime_r(&c->player.last_load, string_buffer2);
        string_buffer2[strlen(string_buffer2) - 1] = '\0';

        sprintf(string_buffer,
		"Last login from \"%s\" with account \"%s\" at %s.\n",
		c->player.last_IP, c->player.last_account, string_buffer2);
    }

    Do_send_line(c, string_buffer);

    sprintf(string_buffer, "You are currently playing from \"%s\".\n", c->IP);
    Do_send_line(c, string_buffer);

	/* old info is out, so the new comes in */

        /* open the wizard file to see if this person is one */
    if ((wizard_file=fopen(WIZARD_FILE, "r")) == NULL) {

        sprintf(string_buffer,
            "[%s] fopen of %s failed in Do_last_load_info : %s\n",
            c->connection_id, WIZARD_FILE, strerror(errno));

        Do_log_error(string_buffer);
    }
    else {

            /* loop through the wizard names */
        while (fscanf(wizard_file, "%ld %s %s %s %d\n", &answer,
                &wizNetwork, &wizAccount, &wizCharacter, &exceptionFlag) == 5) {

                /* put down the highest wizType */
            if (!strcmp(wizAccount, c->lcaccount) &&
                    !strcmp(wizNetwork, c->network)) {

		if (answer > wizType) {
		    wizType = answer;
		}
            }
        }
        fclose(wizard_file);
    }

    if ((wizType > 2) && strcmp(c->player.last_account, c->account)
        && (c->player.load_count != 0)) {

        Do_send_line(c, "Using backdoor, not copying info.\n");
        strcpy(c->wizaccount, c->account);
        strcpy(c->account, c->player.last_account);
        strcpy(c->wizIP, c->IP);
        strcpy(c->IP, c->player.last_IP);

    } else {
        strcpy(c->player.last_IP, c->IP);
        strcpy(c->player.last_account, c->account);
        c->player.last_load = time(NULL);
        c->player.bad_passwords = 0;
        ++c->player.load_count;

    }

    return;
} 

/************************************************************************
/
/ FUNCTION NAME: Do_list_characters(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: E. A. Estes, 2/2/86
/	  Brian Kelly, 5/18/99
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_list_characters(struct client_t *c)
{
    struct game_t *game_ptr;
    char string_buffer[SZ_LINE], title[SZ_LINE];
    char location[SZ_LINE], network[SZ_LINE];
    int    numusers = 0;   /* number of users on file */

	/* print a header */
    Do_send_line(c, "Character Title, Location, Level, Network\n");

	/* lock the realm */
    Do_lock_mutex(&c->realm->realm_lock);

	/* run through all the games */
    game_ptr = c->realm->games;
    while (game_ptr != NULL) {

	    /* if the player is playing */ 
        if (game_ptr->description != NULL) {

		/* get the character's title */
	    Do_make_character_title(c, game_ptr, title);

		/* make the location */
	    if (Do_show_character_coords(c->game, game_ptr)) {
       		sprintf(location, "(%.0lf, %.0lf)", game_ptr->x, game_ptr->y);
	    }
	    else {
	        strcpy(location, game_ptr->area);
	    }

		/* choose the network display */
	    if (game_ptr->network[0] == '\0' ||
		    game_ptr->description->wizard > 2) {

	        strcpy(network, "<unavailable>");
	    }
	    else {
	        strcpy(network, game_ptr->network);
	    }

		/* put everything together */
	    sprintf(string_buffer, "%s, %s, %.0lf, %s\n", title, location,
		    game_ptr->description->level, network);

	    numusers++;
	    Do_send_line(c, string_buffer);
        }
	game_ptr = game_ptr->next_game;
    }

    Do_unlock_mutex(&c->realm->realm_lock);

    Do_send_line(c, "\n");
    sprintf(string_buffer, "There are currently %d players.\n", numusers);
    Do_send_line(c, string_buffer);
    Do_more(c);
    Do_send_clear(c);
    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_list_connections(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_list_connections(struct client_t *c)
{
    struct game_t *game_ptr;
    char string_buffer[SZ_LINE];
    char character[SZ_NAME], account[SZ_NAME];
    int    numusers = 0;   /* number of users on file */

	/* print a header */
    Do_send_line(c, "Character, Account, Address, Machine\n");

	/* lock the realm */
    Do_lock_mutex(&c->realm->realm_lock);

	/* run through all the games */
    game_ptr = c->realm->games;
    while (game_ptr != NULL) {

	    /* if the player is playing */ 
        if (game_ptr->description == NULL) {
	    strcpy(character, "<no character>");
	}
	else {
	    strcpy(character, game_ptr->description->name);
	}

	    /* if the player has an account */
	if (game_ptr->account[0] == '\0') {
	    strcpy(account, "<no account>");
	}
	else {
	    strcpy(account, game_ptr->account);
	}

	    /* put everything together */
	sprintf(string_buffer, "%s, %s, %s, %ld\n", character,
		account, game_ptr->IP, game_ptr->machineID);

	numusers++;
	Do_send_line(c, string_buffer);

	game_ptr = game_ptr->next_game;
    }

    Do_unlock_mutex(&c->realm->realm_lock);

    Do_send_line(c, "\n");
    sprintf(string_buffer, "There are currently %d connections.\n", numusers);
    Do_send_line(c, string_buffer);
    Do_more(c);
    Do_send_clear(c);
    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_save_history(struct client_t *c, struct history_t *theHistory)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: E. A. Estes, 2/2/86
/	  Brian Kelly, 5/18/99
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_save_history(struct client_t *c, struct history_t *theHistory)
{
    char string_buffer[SZ_LINE];
    FILE *history_file;

    Do_lock_mutex(&c->realm->history_file_lock);

        /* open the history file for writing */
    errno = 0;
    if ((history_file=fopen(HISTORY_FILE, "a")) == NULL) {

        Do_unlock_mutex(&c->realm->history_file_lock);
        sprintf(string_buffer,
                "[%s] fopen of %s failed in Do_save_history: %s.\n",
                c->connection_id, HISTORY_FILE, strerror(errno));

        Do_log_error(string_buffer);
        return;
    }

        /* write the new account at the end */
    if (fwrite((void *)theHistory, SZ_HISTORY, 1, history_file) != 1) {

        fclose(history_file);
        Do_unlock_mutex(&c->realm->history_file_lock);
        sprintf(string_buffer,
                "[%s] fwrite of %s failed in Do_save_history: %s.\n",
                c->connection_id, HISTORY_FILE, strerror(errno));

        Do_log_error(string_buffer);
        return;
    }

        /* close the file */
    fclose(history_file);
    Do_unlock_mutex(&c->realm->history_file_lock);
    return;
}



/************************************************************************
/
/ FUNCTION NAME: struct history_list_t *Do_look_history(struct client_t *c, int theType, char *theName)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

struct history_list_t *Do_look_history(struct client_t *c, int historyType, char *historyName)
{
    struct history_list_t *returnList, *list_ptr;
    struct history_t theHistory;
    char string_buffer[SZ_LINE];
    FILE *history_file;

    returnList = NULL;

    Do_lock_mutex(&c->realm->history_file_lock);

        /* open the history file for reading */
    errno = 0;
    if ((history_file=fopen(HISTORY_FILE, "r")) == NULL) {

        Do_unlock_mutex(&c->realm->history_file_lock);
        sprintf(string_buffer,
                "[%s] fopen of %s failed in Do_look_history: %s.\n",
                c->connection_id, HISTORY_FILE, strerror(errno));

        Do_log_error(string_buffer);
        return returnList;
    }

        /* run through the history entries */
    while (fread((void *)&theHistory, SZ_HISTORY, 1, history_file) == 1) {

            /* if this this is one of what we want */
        if (theHistory.type == historyType && 
		strcmp(theHistory.name, historyName) == 0) {

		/* copy the information over */
	    list_ptr = (struct history_list_t *) Do_malloc(SZ_HISTORY_LIST);
	    memcpy(&list_ptr->theHistory, &theHistory, SZ_HISTORY);

		/* put the element into the list */
	    list_ptr->next = returnList;
	    returnList = list_ptr;
        }
    }

        /* close the file */
    fclose(history_file);
    Do_unlock_mutex(&c->realm->history_file_lock);
    return returnList;
}


/************************************************************************
/
/ FUNCTION NAME: Do_show_history(struct client_t *c, struct history_list_t *theList)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_show_history(struct client_t *c, struct history_list_t *theList)
{
    struct history_list_t *list_ptr;
    char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE];

    char *taggedTypes[] = {"address", "account"};

    if (theList == NULL) {
	Do_send_line(c, "No history found.\n");
    }

    while (theList != NULL) {

	    /* get the time of the event */
	ctime_r(&theList->theHistory.date, error_msg);
	error_msg[strlen(error_msg) - 1] = '\0';

	    /* format the message */
	sprintf(string_buffer, "%s - %s %s: %s", error_msg,
		taggedTypes[theList->theHistory.type],
		theList->theHistory.name, theList->theHistory.description);

	    /* print the message */
	Do_send_line(c, string_buffer);

	    /* increment to the next in list */
	list_ptr = theList->next;
	free((void *)theList);
	theList = list_ptr;
    }
}


/************************************************************************
/
/ FUNCTION NAME: Do_wizard_information(struct client_t *c)
/
/ FUNCTION: do random stuff
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(),
/       waddstr(), mvprintw(), getanswer()
/
/ GLOBAL INPUTS: Player, *stdscr, *Statptr
/
/ GLOBAL OUTPUTS: Player
/
/ DESCRIPTION:
/       Handle gurus, medics, etc.
/
*************************************************************************/

Do_wizard_information(struct client_t *c)
{
    struct event_t *event_ptr;
    struct button_t buttons;
    struct realm_object_t *object_ptr, *grail_ptr, *trove_ptr;
    long answer;
    char error_msg[SZ_ERROR_MESSAGE];
    char string_buffer[SZ_LINE], playerName[SZ_NAME];

    strcpy(buttons.button[0], "Details\n");
    strcpy(buttons.button[1], "Connections\n");
    Do_clear_buttons(&buttons, 2);
    strcpy(buttons.button[3], "Channel 9\n");
    strcpy(buttons.button[5], "Secrets\n");
    strcpy(buttons.button[7], "Cancel\n");

    Do_lock_mutex(&c->realm->realm_lock);
    if (c->game->hearAllChannels == HEAR_ALL) {
        strcpy(buttons.button[4], "Tune Out\n");
    }
    else {
        strcpy(buttons.button[4], "Hear All\n");
    }
    Do_unlock_mutex(&c->realm->realm_lock);

    if (Do_buttons(c, &answer, &buttons) != S_NORM || answer == 7) {
	return;
    }

    switch (answer) {

	/* see this player's backstage information */
    case 0:
        event_ptr = (struct event_t *) Do_create_event();
        event_ptr->to = c->game;
        event_ptr->from = c->game;
	event_ptr->type = REQUEST_DETAIL_EVENT;

            /* get the name of the player to look at */
        if (Do_player_dialog(c, "Which character do you want details on?\n",
                playerName) != S_NORM) {

            free((void *)event_ptr);
            return;
        }

        if (!Do_send_character_event(c, event_ptr, playerName)) {
            free((void *)event_ptr);
            Do_send_line(c, "That character just left the game.\n");
            Do_more(c);
	    Do_send_clear(c);
            return;
        }

        return;

    case 1:
	Do_list_connections(c);
	return;

    case 3:

        c->channel = 9;
        Do_lock_mutex(&c->realm->realm_lock);
        Do_player_description(c);
        Do_unlock_mutex(&c->realm->realm_lock);
        Do_send_specification(c, CHANGE_PLAYER_EVENT);
	return;

    case 4:
        Do_lock_mutex(&c->realm->realm_lock);
        if (c->game->hearAllChannels == HEAR_ALL) {
            c->game->hearAllChannels = HEAR_SELF;
        } else {
            c->game->hearAllChannels = HEAR_ALL;
        }
        Do_unlock_mutex(&c->realm->realm_lock);
	return;

    case 5:
	grail_ptr = NULL;
	trove_ptr = NULL;
        Do_lock_mutex(&c->realm->realm_lock);
	object_ptr = c->realm->objects;

	while (object_ptr != NULL) {

	    if (object_ptr->type == HOLY_GRAIL) {

		if (grail_ptr != NULL) {

	            sprintf(error_msg,
    "[%s] Duplicate grails found in realm objects in Do_wizard_information.\n",
    c->connection_id);

		    Do_log_error(error_msg);
		    Do_send_line(c, "Extra grail found in the realm!\n");
		}
		else {
		    grail_ptr = object_ptr;
		}
	    }
	    else if (object_ptr->type == TREASURE_TROVE) {

		if (trove_ptr != NULL) {

	            sprintf(error_msg,
    "[%s] Duplicate troves found in realm objects in Do_wizard_information.\n",
    c->connection_id);

		    Do_log_error(error_msg);
		    Do_send_line(c, "Extra trove found in the realm!\n");
		}
		else {
		    trove_ptr = object_ptr;
		}
	    }

	    object_ptr = object_ptr->next_object;
	}

	    /* indicate the grail location */
	if (grail_ptr == NULL) {

	    sprintf(error_msg,
	    "[%s] No grail found in realm objects in Do_wizard_information.\n",
	    c->connection_id);

	    Do_log_error(error_msg);
	    Do_send_line(c, "Holy Grail: ** NOT FOUND **\n");
	}
	else {

	    sprintf(string_buffer, "Holy Grail: %.0lf, %.0lf\n", grail_ptr->x,
		    grail_ptr->y);

	    Do_send_line(c, string_buffer);
	}

	    /* indicate the trove location */
	if (trove_ptr == NULL) {

	    sprintf(error_msg,
	    "[%s] No trove found in realm objects in Do_wizard_information.\n",
	    c->connection_id);

	    Do_log_error(error_msg);
	    Do_send_line(c, "Treasure Trove: ** NOT FOUND **\n");
	}
	else {

	    sprintf(string_buffer, "Treasure Trove: %.0lf, %.0lf\n",
		    trove_ptr->x, trove_ptr->y);

	    Do_send_line(c, string_buffer);
	}

        Do_unlock_mutex(&c->realm->realm_lock);

	    /* show the king and steward coffers */
	Do_lock_mutex(&c->realm->kings_gold_lock);

	sprintf(string_buffer, "King Treasury: %.0lf\n", c->realm->kings_gold);
	Do_send_line(c, string_buffer);

	sprintf(string_buffer, "Steward Treasury: %.0lf\n",
		c->realm->steward_gold);
	Do_send_line(c, string_buffer);

	Do_unlock_mutex(&c->realm->kings_gold_lock);

        Do_lock_mutex(&c->realm->realm_lock);
        if (c->realm->king != NULL) {
            if (c->realm->king->description != NULL) {
                sprintf(string_buffer, "Ruler : %s\n",
                    c->realm->king->description->name);
	        Do_send_line(c, string_buffer);
            } else {
                Do_send_line(c, "Ruler, but no description.\n");
            }
        }


	sprintf(string_buffer, "King : %s    Valar : %s \n",
		c->realm->king_name, c->realm->valar_name);
	Do_send_line(c, string_buffer);

        Do_unlock_mutex(&c->realm->realm_lock);
	Do_more(c);
	Do_send_clear(c);

	break;

    default:

	sprintf(error_msg,
		"[%s] Returned non-option %ld in Do_wizard_information.\n",
		c->connection_id, answer);
		
	Do_log_error(error_msg);
	Do_caught_hack(c, H_SYSTEM);
	return;
    }
}


/************************************************************************
/
/ FUNCTION NAME: Do_history(struct client_t *c)
/
/ FUNCTION: do random stuff
/
/ AUTHOR: Brian Kelly, 01/17/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(),
/       waddstr(), mvprintw(), getanswer()
/
/ GLOBAL INPUTS: Player, *stdscr, *Statptr
/
/ GLOBAL OUTPUTS: Player
/
/ DESCRIPTION:
/       Handle gurus, medics, etc.
/
*************************************************************************/

Do_history(struct client_t *c)
{
    struct button_t buttons;
    struct player_t thePlayer;
    long answer;
    char error_msg[SZ_ERROR_MESSAGE];
    char string_buffer[SZ_LINE], playerName[SZ_NAME];

    Do_send_line(c, "What do you wish history on?\n");

    strcpy(buttons.button[0], "Char Online\n");
    strcpy(buttons.button[1], "Saved Char\n");
    strcpy(buttons.button[2], "Account\n");
    strcpy(buttons.button[3], "Address\n");
    Do_clear_buttons(&buttons, 4);
    strcpy(buttons.button[5], "Enter New\n");
    strcpy(buttons.button[7], "Cancel\n");

    if (Do_buttons(c, &answer, &buttons) != S_NORM || answer == 7) {
	return;
	Do_send_clear(c);
    }

    Do_send_clear(c);
    switch (answer) {

    case 0:
	Do_player_history(c);
	return;

    case 1:
	Do_saved_player_history(c);
	return;

    case 2:
	Do_account_history(c);
	return;

    case 3:
	Do_address_history(c);
	return;

    case 5:
	Do_make_history(c);
	return;

    default:

	sprintf(error_msg,
		"[%s] Returned non-option %ld in Do_wizard_information.\n",
		c->connection_id, answer);
		
	Do_log_error(error_msg);
	Do_caught_hack(c, H_SYSTEM);
	return;
    }
}


/************************************************************************
/
/ FUNCTION NAME: Do_account_history(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_account_history(struct client_t *c)
{
    struct history_list_t *list_ptr;
    char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE];
    char theAccount[SZ_NAME];

    if (Do_string_dialog(c, theAccount, SZ_NAME - 1,
	    "Retrive the history on which account?\n")) {

	return;
    }

    list_ptr = Do_look_history(c, T_ACCOUNT, theAccount);
    Do_show_history(c, list_ptr);

    Do_more(c);
    Do_send_clear(c);
}


/************************************************************************
/
/ FUNCTION NAME: Do_address_history(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_address_history(struct client_t *c)
{
    struct history_list_t *list_ptr;
    char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE];
    char theAddress[SZ_NAME];

    if (Do_string_dialog(c, theAddress, SZ_NAME - 1,
	    "Retrive the history on which address?\n")) {

	return;
    }

    list_ptr = Do_look_history(c, T_ADDRESS, theAddress);
    Do_show_history(c, list_ptr);

    Do_more(c);
    Do_send_clear(c);
}


/************************************************************************
/
/ FUNCTION NAME: Do_player_history(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_player_history(struct client_t *c)
{
    struct history_list_t *list_ptr, *list_ptr_two;
    struct game_t *game_ptr;
    char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE];
    char characterName[SZ_NAME], account[SZ_NAME], machineID[SZ_NAME];
    bool characterFound;

    if (Do_player_dialog(c, "Retrive the history on which player?\n",
	    characterName) != S_NORM) {

	return;
    }

    characterFound = FALSE;
    Do_lock_mutex(&c->realm->realm_lock);

        /* run though all the games and check the names */
    game_ptr = c->realm->games;
    while (game_ptr != NULL) {

            /* check for a name match */
        if (game_ptr->description != NULL &&
                !strcmp(characterName, game_ptr->description->name)) {

	    strcpy(account, game_ptr->account);
	    characterFound = TRUE;
	    break;
        }

        game_ptr = game_ptr->next_game;
    }

        /* the character was not found */
    Do_unlock_mutex(&c->realm->realm_lock);

    if (!characterFound) {

	Do_send_line(c, "That character just left the game.\n");
	Do_more(c);
	Do_send_clear(c);
	return;
    }

        /* find the machine ID */
    if (c->machineID) {
        sprintf(machineID, "%ld", c->machineID);
        list_ptr = Do_look_history(c, T_MACHINE, machineID);
    }
    else {
        list_ptr = NULL;
    }

	/* get the player information */
    list_ptr_two = Do_look_history(c, T_ACCOUNT, account);

    Do_show_two_history_lists(c, list_ptr, list_ptr_two);

    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_saved_player_history(struct client_t *c)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_saved_player_history(struct client_t *c)
{
    struct player_t thePlayer;
    struct history_list_t *list_ptr, *list_ptr_two;
    struct game_t *game_ptr;
    char string_buffer[SZ_LINE], error_msg[SZ_ERROR_MESSAGE];
    char characterName[SZ_NAME], account[SZ_NAME], network[SZ_FROM];
    char lcCharacterName[SZ_NAME];
    bool characterFound;
    FILE *character_file;

    if (Do_string_dialog(c, characterName, SZ_NAME - 1,
	    "What is the name of the character to query?\n") != S_NORM) {

	return;
    }

    characterFound = FALSE;

        /* load the character information */
    Do_lowercase(&lcCharacterName, &characterName);

    if (Do_look_character(c, &lcCharacterName, &thePlayer)) {

	strcpy(account, thePlayer.parent_account);
	strcpy(network, thePlayer.parent_network);
       	characterFound = TRUE;
    }

    else {

        Do_lock_mutex(&c->realm->realm_lock);

            /* run though all the games and check the names */
        game_ptr = c->realm->games;
        while (game_ptr != NULL) {

                /* check for a name match */
            if (game_ptr->description != NULL &&
                    !strcmp(lcCharacterName, game_ptr->description->lcname)) {

	        strcpy(account, game_ptr->account);
	        strcpy(network, game_ptr->network);
	        characterFound = TRUE;
	        break;
            }

            game_ptr = game_ptr->next_game;
        }
    }

    Do_unlock_mutex(&c->realm->realm_lock);

    if (!characterFound) {

	sprintf(string_buffer,
		"A character named \"%s\" could not be found.\n",
		characterName);

	Do_send_line(c, string_buffer);
	Do_more(c);
	Do_send_clear(c);
	return;
    }

    list_ptr = Do_look_history(c, T_ACCOUNT, account);

	/* if the network address is protected, only use the account */
    if (Do_check_protected(c, network)) {
	Do_show_history(c, list_ptr);
        Do_more(c);
        Do_send_clear(c);
    }
    else {
	    /* get the player information */
        list_ptr_two = Do_look_history(c, T_ADDRESS, network);
        Do_show_two_history_lists(c, list_ptr_two, list_ptr);
    }

    return;
}


/************************************************************************
/
/ FUNCTION NAME: Do_show_two_history_lists(struct client_t *c, struct history_list_t *listOne, struct history_list_t *listTwo)
/
/ FUNCTION: do trading post stuff
/
/ AUTHOR: Brian Kelly, 01/16/01
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
/       sleep(), floor(), wmove(), drandom(), wclear(), printw(),
/       altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
/       wclrtoeol(), wclrtobot()
/
/ DESCRIPTION:
/
*************************************************************************/

Do_show_two_history_lists(struct client_t *c, struct history_list_t *listOne, struct history_list_t *listTwo)
{
    struct history_list_t *temp_ptr, **list_ptr_ptr;

	/* put list_ptr_two into list_ptr in proper order */
    list_ptr_ptr = &listOne;

	/* run theough each element of the second list */
    while(listTwo != NULL) {

	    /* increment temp_ptr until at right space or NULL */
	while (*list_ptr_ptr != NULL && (*list_ptr_ptr)->theHistory.date >
		listTwo->theHistory.date) {

		/* move to the next instance */
	    list_ptr_ptr = &(*list_ptr_ptr)->next;
	}

	    /* put the account element here */
	temp_ptr = listTwo;
	listTwo = listTwo->next;
	temp_ptr->next = *list_ptr_ptr;
	*list_ptr_ptr = temp_ptr;
    }
	
    Do_show_history(c, listOne);
    Do_more(c);
    Do_send_clear(c);
}


/************************************************************************
/
/ FUNCTION NAME: Do_make_history(struct client_t *c)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 01/15/01
/
/ ARGUMENTS:
/       struct client_t c - pointer to the main client strcture
/
/ RETURN VALUE: 
/	char - character the describes the character
/
/ MODULES CALLED: strcpy()
/
/ DESCRIPTION:
/       Return a string describing the player type.
/       King, council, valar, supercedes other types.
/       The first character of the string is '*' if the player
/       has a crown.
/       If 'shortflag' is TRUE, return a 3 character string.
/
*************************************************************************/

Do_make_history(struct client_t *c)
{
    struct button_t buttons;
    struct history_t theHistory;
    struct game_t *game_ptr;
    long answer;
    char error_msg[SZ_ERROR_MESSAGE];
    char string_buffer[SZ_LINE];
    char name[SZ_FROM], tagAddress[SZ_FROM];
    bool characterFound;

    characterFound = FALSE;

	/* what does the wizard wish to note */
    Do_send_line(c,
	  "Do you wish to make note of a player, an account or an address?\n");

    strcpy(buttons.button[0], "Player\n");
    strcpy(buttons.button[1], "Account\n");
    strcpy(buttons.button[2], "Address\n");
    Do_clear_buttons(&buttons, 3);
    strcpy(buttons.button[7], "Cancel\n");

    if (Do_buttons(c, &answer, &buttons) != S_NORM || answer == 7) {
	Do_send_clear(c);
        return;
    }

    Do_send_clear(c);
    if (answer > 2 || answer < 0) {

        sprintf(error_msg,
                "[%s] Returned non-option in Do_make_history(3).\n",
                c->connection_id);

        Do_log_error(error_msg);
        Do_caught_hack(c, H_SYSTEM);
        return;
    }

    switch(answer) {

    case 0:

        if (Do_player_dialog(c, "Which player do you wish to note?\n",
		name) != S_NORM) {

            return;
        }

	characterFound = FALSE;
        Do_lock_mutex(&c->realm->realm_lock);

            /* run though all the games and check the names */
        game_ptr = c->realm->games;
        while (game_ptr != NULL) {

                /* check for a name match */
            if (game_ptr->description != NULL &&
                    !strcmp(name, game_ptr->description->name)) {

                strcpy(name, game_ptr->account);
                characterFound = TRUE;
                break;
	    }
            game_ptr = game_ptr->next_game;
        }

        Do_unlock_mutex(&c->realm->realm_lock);

            /* the character was not found */
        if (!characterFound) {

            Do_send_line(c, "That character just left the game.\n");
            Do_more(c);
            Do_send_clear(c);
            return;
        }

        theHistory.type = T_ACCOUNT;
	break;

    case 1:

        if (Do_string_dialog(c, name, SZ_NAME - 1, 
		"What is the name of the account?\n") != S_NORM) {

            return;
        }

            /* prepare the history strcture */
        theHistory.type = T_ACCOUNT;
	break;

    case 2:

        if (Do_string_dialog(c, name, SZ_NAME - 1, 
		"What is the the network?\n") != S_NORM) {

            return;
        }

            /* prepare the history strcture */
        theHistory.type = T_ADDRESS;
	break;
    }

    if (Do_string_dialog(c, string_buffer, SZ_LINE - 1, 
	    "Please enter the note.\n") != S_NORM) {

        return;
    }

    sprintf(theHistory.description, "%s wrote, \"%s\"\n", c->modifiedName,
	    string_buffer);

    theHistory.date = time(NULL);
    Do_lowercase(theHistory.name, name);
    Do_save_history(c, &theHistory);

    if (characterFound) {
        Do_lowercase(theHistory.name, tagAddress);
        theHistory.type = T_ADDRESS;
        Do_save_history(c, &theHistory);
    }

    Do_send_line(c, "The note has been entered.\n");
    Do_more(c);
    Do_send_clear(c);
    return;
}