/* * 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; }