Fixed a bug with character deletion (see changelog)

This commit is contained in:
JamDog 2009-03-13 18:19:38 +00:00
parent 2d52e5cb67
commit 44f59ceff2
3 changed files with 146 additions and 102 deletions

View file

@ -35,6 +35,8 @@ export (QQ's a zone into a tarball)t
Xlist (mlist, olist, rlist, zlist, slist, tlist, qlist) Xlist (mlist, olist, rlist, zlist, slist, tlist, qlist)
(lots of major bugfixes too) (lots of major bugfixes too)
tbaMUD 3.59 tbaMUD 3.59
[Mar 13 2009] - Jamdog
Bug-Fix: Character deletion (remove_player, players.c), where the wrong player was potentially being deleted.
[Mar 08 2009] - Jamdog [Mar 08 2009] - Jamdog
Fixed a possible crash bug in delete_object (genobj.c) (Thanks Slicer) Fixed a possible crash bug in delete_object (genobj.c) (Thanks Slicer)
CAP function now recognises both preceeding color codes and ANSI codes (Thanks Slicer) CAP function now recognises both preceeding color codes and ANSI codes (Thanks Slicer)

View file

@ -1236,66 +1236,67 @@ void nanny(struct descriptor_data *d, char *arg)
char buf[MAX_INPUT_LENGTH], tmp_name[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH], tmp_name[MAX_INPUT_LENGTH];
if ((_parse_name(arg, tmp_name)) || strlen(tmp_name) < 2 || if ((_parse_name(arg, tmp_name)) || strlen(tmp_name) < 2 ||
strlen(tmp_name) > MAX_NAME_LENGTH || !valid_name(tmp_name) || strlen(tmp_name) > MAX_NAME_LENGTH || !valid_name(tmp_name) ||
fill_word(strcpy(buf, tmp_name)) || reserved_word(buf)) { /* strcpy: OK (mutual MAX_INPUT_LENGTH) */ fill_word(strcpy(buf, tmp_name)) || reserved_word(buf)) { /* strcpy: OK (mutual MAX_INPUT_LENGTH) */
write_to_output(d, "Invalid name, please try another.\r\nName: "); write_to_output(d, "Invalid name, please try another.\r\nName: ");
return; return;
} }
if ((player_i = load_char(tmp_name, d->character)) > -1) { if ((player_i = load_char(tmp_name, d->character)) > -1) {
GET_PFILEPOS(d->character) = player_i; GET_PFILEPOS(d->character) = player_i;
if (PLR_FLAGGED(d->character, PLR_DELETED)) { if (PLR_FLAGGED(d->character, PLR_DELETED)) {
/* Make sure old files are removed so the new player doesn't get the /* Make sure old files are removed so the new player doesn't get the
* deleted player's equipment. */ * deleted player's equipment. */
if ((player_i = get_ptable_by_name(tmp_name)) >= 0) if ((player_i = get_ptable_by_name(tmp_name)) >= 0)
remove_player(player_i); remove_player(player_i);
/* We get a false positive from the original deleted character. */ /* We get a false positive from the original deleted character. */
free_char(d->character); free_char(d->character);
/* Check for multiple creations. */
if (!valid_name(tmp_name)) { /* Check for multiple creations. */
write_to_output(d, "Invalid name, please try another.\r\nName: "); if (!valid_name(tmp_name)) {
return; write_to_output(d, "Invalid name, please try another.\r\nName: ");
} return;
CREATE(d->character, struct char_data, 1); }
clear_char(d->character); CREATE(d->character, struct char_data, 1);
CREATE(d->character->player_specials, struct player_special_data, 1); clear_char(d->character);
CREATE(d->character->player_specials, struct player_special_data, 1);
if (GET_HOST(d->character)) if (GET_HOST(d->character))
free(GET_HOST(d->character)); free(GET_HOST(d->character));
GET_HOST(d->character) = strdup(d->host); GET_HOST(d->character) = strdup(d->host);
d->character->desc = d; d->character->desc = d;
CREATE(d->character->player.name, char, strlen(tmp_name) + 1); CREATE(d->character->player.name, char, strlen(tmp_name) + 1);
strcpy(d->character->player.name, CAP(tmp_name)); /* strcpy: OK (size checked above) */ strcpy(d->character->player.name, CAP(tmp_name)); /* strcpy: OK (size checked above) */
GET_PFILEPOS(d->character) = player_i; GET_PFILEPOS(d->character) = player_i;
write_to_output(d, "Did I get that right, %s (Y/N)? ", tmp_name); write_to_output(d, "Did I get that right, %s (Y/N)? ", tmp_name);
STATE(d) = CON_NAME_CNFRM; STATE(d) = CON_NAME_CNFRM;
} else { } else {
/* undo it just in case they are set */ /* undo it just in case they are set */
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING); REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING);
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING); REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING);
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_CRYO); REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_CRYO);
REMOVE_BIT_AR(AFF_FLAGS(d->character), AFF_GROUP); REMOVE_BIT_AR(AFF_FLAGS(d->character), AFF_GROUP);
d->character->player.time.logon = time(0); d->character->player.time.logon = time(0);
write_to_output(d, "Password: "); write_to_output(d, "Password: ");
echo_off(d); echo_off(d);
d->idle_tics = 0; d->idle_tics = 0;
STATE(d) = CON_PASSWORD; STATE(d) = CON_PASSWORD;
} }
} else { } else {
/* player unknown -- make new character */ /* player unknown -- make new character */
/* Check for multiple creations of a character. */ /* Check for multiple creations of a character. */
if (!valid_name(tmp_name)) { if (!valid_name(tmp_name)) {
write_to_output(d, "Invalid name, please try another.\r\nName: "); write_to_output(d, "Invalid name, please try another.\r\nName: ");
return; return;
} }
CREATE(d->character->player.name, char, strlen(tmp_name) + 1); CREATE(d->character->player.name, char, strlen(tmp_name) + 1);
strcpy(d->character->player.name, CAP(tmp_name)); /* strcpy: OK (size checked above) */ strcpy(d->character->player.name, CAP(tmp_name)); /* strcpy: OK (size checked above) */
write_to_output(d, "Did I get that right, %s (Y/N)? ", tmp_name); write_to_output(d, "Did I get that right, %s (Y/N)? ", tmp_name);
STATE(d) = CON_NAME_CNFRM; STATE(d) = CON_NAME_CNFRM;
} }
} }
break; break;

View file

@ -28,6 +28,12 @@
#define LOAD_MOVE 2 #define LOAD_MOVE 2
#define LOAD_STRENGTH 3 #define LOAD_STRENGTH 3
#define PT_PNAME(i) (player_table[(i)].name)
#define PT_IDNUM(i) (player_table[(i)].id)
#define PT_LEVEL(i) (player_table[(i)].level)
#define PT_FLAGS(i) (player_table[(i)].flags)
#define PT_LLAST(i) (player_table[(i)].last)
/* 'global' vars defined here and used externally */ /* 'global' vars defined here and used externally */
/** @deprecated Since this file really is basically a functional extension /** @deprecated Since this file really is basically a functional extension
* of the database handling in db.c, until the day that the mud is broken * of the database handling in db.c, until the day that the mud is broken
@ -118,6 +124,41 @@ int create_entry(char *name)
return (pos); return (pos);
} }
/* Remove an entry from the in-memory player index table. *
* Requires the 'pos' value returned by the get_ptable_by_name function */
void remove_player_from_index(int pos)
{
int i;
if (pos < 0 || pos > top_of_p_table)
return;
/* We only need to free the name string */
free(PT_PNAME(pos));
/* Move every other item in the list down the index */
for (i = pos+1; i <= top_of_p_table; i++) {
PT_PNAME(i-1) = PT_PNAME(i);
PT_IDNUM(i-1) = PT_IDNUM(i);
PT_LEVEL(i-1) = PT_LEVEL(i);
PT_FLAGS(i-1) = PT_FLAGS(i);
PT_LLAST(i-1) = PT_LLAST(i);
}
PT_PNAME(top_of_p_table) = NULL;
/* Reduce the index table counter */
top_of_p_table--;
/* And reduce the size of the table */
if (top_of_p_table >= 0)
RECREATE(player_table, struct player_index_element, (top_of_p_table+1));
else {
free(player_table);
player_table = NULL;
}
}
/* This function necessary to save a seperate ASCII player index */ /* This function necessary to save a seperate ASCII player index */
void save_player_index(void) void save_player_index(void)
{ {
@ -745,8 +786,8 @@ void remove_player(int pfilepos)
if (!*player_table[pfilepos].name) if (!*player_table[pfilepos].name)
return; return;
/* Update top_of_p_table. */ /* Update index table. */
top_of_p_table -= 1; remove_player_from_index(pfilepos);
/* Unlink all player-owned files */ /* Unlink all player-owned files */
for (i = 0; i < MAX_FILES; i++) { for (i = 0; i < MAX_FILES; i++) {