/*
* file.c File manipulation routines
*/
#include "include.h"
/***************************************************************************
/ FUNCTION NAME: Do_purge_characters(void)
/
/ FUNCTION: Handles error messages
/
/ AUTHOR: Brian Kelly, 4/22/99
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
void Do_purge_characters(void)
{
FILE *character_file;
char error_msg[SZ_ERROR_MESSAGE];
/* open the character file */
errno = 0;
if ((character_file=fopen(CHARACTER_FILE, "w")) == NULL) {
sprintf(error_msg,
"[0.0.0.0:?] fopen of %s failed in Do_purge_characters: %s\n",
CHARACTER_FILE, strerror(errno));
Do_log_error(error_msg);
exit(CHARACTER_FILE_ERROR);
}
fclose(character_file);
return;
}
/***************************************************************************
/ FUNCTION NAME: Do_purge_scoreboard(void)
/
/ FUNCTION: Handles error messages
/
/ AUTHOR: Brian Kelly, 4/22/99
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
void Do_purge_scoreboard(void)
{
FILE *scoreboard_file;
char error_msg[SZ_ERROR_MESSAGE];
/* open the scoreboard file */
errno = 0;
if ((scoreboard_file=fopen(SCOREBOARD_FILE, "w")) == NULL) {
sprintf(error_msg,
"[0.0.0.0:?] fopen of %s failed in Do_purge_scoreboard: %s\n",
SCOREBOARD_FILE, strerror(errno));
Do_log_error(error_msg);
exit(SCOREBOARD_FILE_ERROR);
}
fclose(scoreboard_file);
return;
}
/***************************************************************************
/ FUNCTION NAME: Do_scoreboard_add(struct client_t *c, struct scoreboard_t *entry)
/
/ FUNCTION: Handles error messages
/
/ AUTHOR: Brian Kelly, 4/22/99
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
void Do_scoreboard_add(struct client_t *c, struct scoreboard_t *entry, bool showScore)
{
FILE *scoreboard_file, *temp_file; /* for updating various files */
struct scoreboard_t sb;
struct event_t *event_ptr;
char error_msg[SZ_ERROR_MESSAGE];
int location;
bool save_flag;
Do_lock_mutex(&c->realm->scoreboard_lock);
/* open the scoreboard file */
errno = 0;
if ((scoreboard_file=fopen(SCOREBOARD_FILE, "r")) == NULL) {
Do_unlock_mutex(&c->realm->scoreboard_lock);
sprintf(error_msg, "[%s] fopen of %s failed in Do_scoreboard_add: %s\n",
c->connection_id, SCOREBOARD_FILE, strerror(errno));
Do_log_error(error_msg);
return;
}
/* open a tempoary file */
if ((temp_file=fopen(TEMP_SCOREBOARD_FILE, "w")) == NULL) {
fclose(scoreboard_file);
Do_unlock_mutex(&c->realm->scoreboard_lock);
sprintf(error_msg,
"[%s] fopen of %s failed in Do_scoreboard_add(2): %s\n",
c->connection_id, TEMP_SCOREBOARD_FILE, strerror(errno));
Do_log_error(error_msg);
return;
}
save_flag = TRUE;
location = 0;
/* copy records over to the temp file */
while (fread((void *)&sb, SZ_SCOREBOARD, 1, scoreboard_file) == 1) {
/* if our player is higher level than our copy, put him in */
if (save_flag && sb.level <= entry->level) {
if (fwrite((void *)entry, SZ_SCOREBOARD, 1, temp_file) != 1) {
fclose(scoreboard_file);
fclose(temp_file);
remove(TEMP_CHARACTER_FILE);
Do_unlock_mutex(&c->realm->scoreboard_lock);
sprintf(error_msg,
"[%s] fwrite of %s failed in Do_scoreboard_add: %s\n",
c->connection_id, TEMP_SCOREBOARD_FILE,
strerror(errno));
Do_log_error(error_msg);
return;
}
save_flag = FALSE;
}
/* check that the record to save isn't too old */
if (sb.level > SB_KEEP_ABOVE || sb.time > time(NULL) -
SB_KEEP_FOR) {
/* transfer over the record */
if (fwrite((void *)&sb, SZ_SCOREBOARD, 1, temp_file) != 1) {
fclose(scoreboard_file);
fclose(temp_file);
remove(TEMP_CHARACTER_FILE);
Do_unlock_mutex(&c->realm->scoreboard_lock);
sprintf(error_msg,
"[%s] fwrite of %s failed in Do_scoreboard_add(2): %s\n",
c->connection_id, TEMP_SCOREBOARD_FILE, strerror(errno));
Do_log_error(error_msg);
return;
}
}
/* count this record if we haven't saved our character yet */
if (save_flag) {
++location;
}
}
/* if no more scoreboard records, and we haven't written ours yet */
if (save_flag) {
/* write it now */
if (fwrite((void *)entry, SZ_SCOREBOARD, 1, temp_file) != 1) {
fclose(scoreboard_file);
fclose(temp_file);
remove(TEMP_CHARACTER_FILE);
Do_unlock_mutex(&c->realm->scoreboard_lock);
sprintf(error_msg,
"[%s] fwrite of %s failed in Do_scoreboard_add(3): %s\n",
c->connection_id, TEMP_SCOREBOARD_FILE, strerror(errno));
Do_log_error(error_msg);
return;
}
}
/* remove the scoreboard */
remove(SCOREBOARD_FILE);
/* replace the old scoreboard file with the new one */
rename(TEMP_SCOREBOARD_FILE, SCOREBOARD_FILE);
/* close the file handles */
fclose(scoreboard_file);
fclose(temp_file);
Do_unlock_mutex(&c->realm->scoreboard_lock);
/* display the scoreboard */
if (showScore) {
Do_scoreboard(c, location, TRUE);
}
}
/************************************************************************
/
/ FUNCTION NAME: Do_log(char *filename, char *message)
/
/ FUNCTION: reads the next packet type off the socket
/
/ AUTHOR: Brian Kelly, 8/25/99
/
/ ARGUMENTS:
/ int the_socket - the socket to read the packet type
/
/ RETURN VALUE:
/ int - the type of packet next on the socket
/
/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
/ wclrtoeol()
/
/ DESCRIPTION:
/ Read a string from the keyboard.
/
/************************************************************************/
Do_log(char *filename, char *message)
{
FILE *log_file;
time_t time_now;
char error_msg[SZ_ERROR_MESSAGE];
char string_buffer[SZ_LINE];
time_now = time(NULL);
ctime_r(&time_now, string_buffer);
Do_truncstring(string_buffer);
/* open the error log file */
errno = 0;
if ((log_file=fopen(filename, "a")) == NULL) {
/* if the log file won't open, send and error */
if (strcmp(filename, ERROR_LOG)) {
sprintf(error_msg,
"[?:?] Can not open log file %s in Do_log: %s.\n",
filename, strerror(errno));
Do_log_error(error_msg);
}
/* unless it is the error log, then go to stdout */
else {
printf("%s [?:?] Can not open error file %s in Do_log: %s.\n",
string_buffer, ERROR_LOG, strerror(errno));
printf("%s %s", string_buffer, message);
}
return;
}
/* print the error to the logfile */
fprintf(log_file, "%s %s", string_buffer, message);
/* close the logfile */
fclose(log_file);
/* return, regardless of error */
return;
}
/***************************************************************************
/ FUNCTION NAME: Do_log_error(char *message)
/
/ FUNCTION: Handles error messages
/
/ AUTHOR: Brian Kelly, 4/12/99
/
/ ARGUMENTS:
/ int error - the error code to be returned
/ char *message - the error message to be printed
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_log_error(char *message)
{
Do_log(ERROR_LOG, message);
}
/************************************************************************
/
/ FUNCTION NAME: int Do_check_protected(struct client_t *c, char *theNetwork)
/
/ FUNCTION: return a char specifying player type
/
/ AUTHOR: Brian Kelly, 1/3/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.
/
*************************************************************************/
int Do_check_protected(struct client_t *c, char *theNetwork)
{
char error_msg[SZ_ERROR_MESSAGE];
char string_buffer[SZ_LINE];
FILE *theFile;
/* open the protected file */
if ((theFile=fopen(PROTECTED_FILE, "r")) == NULL) {
sprintf(error_msg,
"[0.0.0.0:?] fopen of %s failed in Do_check_protected: %s\n",
PROTECTED_FILE, strerror(errno));
Do_log_error(error_msg);
return FALSE;
}
/* loop through the the addresses */
while (fgets(string_buffer, SZ_FROM, theFile) != NULL) {
Do_truncstring(string_buffer);
if (!strcmp(string_buffer, theNetwork)) {
fclose(theFile);
return TRUE;
}
}
fclose(theFile);
return FALSE;
}
/************************************************************************
/
/ FUNCTION NAME: Do_restore_character(struct client_t *c)
/
/ FUNCTION: find location in player file of given name
/
/ AUTHOR: Brian Kelly, 01/17/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_restore_character(struct client_t *c)
{
struct player_t readPlayer;
struct history_t theHistory;
FILE *character_file;
char characterName[SZ_NAME], lcCharacterName[SZ_NAME];
char error_msg[SZ_ERROR_MESSAGE];
bool char_flag;
if (Do_string_dialog(c, characterName, SZ_NAME - 1,
"What is the name of the character to restore\n")) {
Do_send_clear(c);
return;
}
Do_send_clear(c);
Do_lowercase(&lcCharacterName, &characterName);
if (Do_look_character(c, &lcCharacterName, &readPlayer)) {
sprintf(error_msg,
"A character named %s is already in the character file.\n",
characterName);
Do_send_line(c, error_msg);
Do_more(c);
Do_send_clear(c);
return;
}
errno = 0;
if ((character_file=fopen(SECONDARY_CHAR_FILE, "r")) == NULL) {
sprintf(error_msg, "fopen of %s failed: %s\n",
SECONDARY_CHAR_FILE, strerror(errno));
Do_send_line(c, error_msg);
Do_more(c);
Do_send_clear(c);
return;
}
char_flag = FALSE;
/* read each line of the character file */
while (fread((void *)&readPlayer, SZ_PLAYER, 1, character_file) == 1) {
/* if we find our character, copy it over */
if (strcmp(readPlayer.lcname, lcCharacterName) == 0) {
char_flag = TRUE;
break;
}
}
fclose(character_file);
if (!char_flag) {
sprintf(error_msg, "A character named %s was not found in %s.\n",
characterName, SECONDARY_CHAR_FILE);
Do_send_line(c, error_msg);
Do_more(c);
Do_send_clear(c);
return;
}
/* save the character */
Do_save_character(c, &readPlayer);
/* log this restore */
sprintf(theHistory.description, "%s restored the character named %s\n",
c->modifiedName, readPlayer.name);
theHistory.date = time(NULL);
theHistory.type = T_ACCOUNT;
strcpy(theHistory.name, readPlayer.parent_account);
Do_save_history(c, &theHistory);
theHistory.type = T_ADDRESS;
strcpy(theHistory.name, readPlayer.parent_network);
Do_save_history(c, &theHistory);
sprintf(error_msg, "[%s] %s restored\n", c->connection_id,
readPlayer.lcname);
Do_log(GAME_LOG, error_msg);
Do_send_line(c, "The character has been successfully restored.\n");
Do_more(c);
Do_send_clear(c);
return;
}