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,15 +28,21 @@
#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
* down to be less monolithic, I don't see why the following should be defined * down to be less monolithic, I don't see why the following should be defined
* anywhere but there. * anywhere but there.
struct player_index_element *player_table = NULL; struct player_index_element *player_table = NULL;
int top_of_p_table = 0; int top_of_p_table = 0;
int top_of_p_file = 0; int top_of_p_file = 0;
long top_idnum = 0; long top_idnum = 0;
*/ */
/* local functions */ /* local functions */
@ -47,7 +53,7 @@ static void load_HMVS(struct char_data *ch, const char *line, int mode);
static void write_aliases_ascii(FILE *file, struct char_data *ch); static void write_aliases_ascii(FILE *file, struct char_data *ch);
static void read_aliases_ascii(FILE *file, struct char_data *ch, int count); static void read_aliases_ascii(FILE *file, struct char_data *ch, int count);
/* New version to build player index for ASCII Player Files. Generate index /* New version to build player index for ASCII Player Files. Generate index
* table for the player file. */ * table for the player file. */
void build_player_index(void) void build_player_index(void)
{ {
@ -89,8 +95,8 @@ void build_player_index(void)
top_of_p_file = top_of_p_table = i - 1; top_of_p_file = top_of_p_table = i - 1;
} }
/* Create a new entry in the in-memory index table for the player file. If the /* Create a new entry in the in-memory index table for the player file. If the
* name already exists, by overwriting a deleted character, then we re-use the * name already exists, by overwriting a deleted character, then we re-use the
* old position. */ * old position. */
int create_entry(char *name) int create_entry(char *name)
{ {
@ -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)
{ {
@ -204,7 +245,7 @@ int load_char(const char *name, struct char_data *ch)
char f1[128], f2[128], f3[128], f4[128]; char f1[128], f2[128], f3[128], f4[128];
trig_data *t = NULL; trig_data *t = NULL;
trig_rnum t_rnum = NOTHING; trig_rnum t_rnum = NOTHING;
if ((id = get_ptable_by_name(name)) < 0) if ((id = get_ptable_by_name(name)) < 0)
return (-1); return (-1);
else { else {
@ -265,9 +306,9 @@ int load_char(const char *name, struct char_data *ch)
GET_QUEST_COUNTER(ch) = PFDEF_QUESTCOUNT; GET_QUEST_COUNTER(ch) = PFDEF_QUESTCOUNT;
GET_QUEST(ch) = PFDEF_CURRQUEST; GET_QUEST(ch) = PFDEF_CURRQUEST;
GET_NUM_QUESTS(ch) = PFDEF_COMPQUESTS; GET_NUM_QUESTS(ch) = PFDEF_COMPQUESTS;
GET_LAST_MOTD(ch) = PFDEF_LASTMOTD; GET_LAST_MOTD(ch) = PFDEF_LASTMOTD;
GET_LAST_NEWS(ch) = PFDEF_LASTNEWS; GET_LAST_NEWS(ch) = PFDEF_LASTNEWS;
for (i = 0; i < AF_ARRAY_MAX; i++) for (i = 0; i < AF_ARRAY_MAX; i++)
AFF_FLAGS(ch)[i] = PFDEF_AFFFLAGS; AFF_FLAGS(ch)[i] = PFDEF_AFFFLAGS;
for (i = 0; i < PM_ARRAY_MAX; i++) for (i = 0; i < PM_ARRAY_MAX; i++)
@ -295,8 +336,8 @@ int load_char(const char *name, struct char_data *ch)
AFF_FLAGS(ch)[1] = asciiflag_conv(f2); AFF_FLAGS(ch)[1] = asciiflag_conv(f2);
AFF_FLAGS(ch)[2] = asciiflag_conv(f3); AFF_FLAGS(ch)[2] = asciiflag_conv(f3);
AFF_FLAGS(ch)[3] = asciiflag_conv(f4); AFF_FLAGS(ch)[3] = asciiflag_conv(f4);
} else } else
AFF_FLAGS(ch)[0] = asciiflag_conv(line); AFF_FLAGS(ch)[0] = asciiflag_conv(line);
} }
if (!strcmp(tag, "Affs")) load_affects(fl, ch); if (!strcmp(tag, "Affs")) load_affects(fl, ch);
else if (!strcmp(tag, "Alin")) GET_ALIGNMENT(ch) = atoi(line); else if (!strcmp(tag, "Alin")) GET_ALIGNMENT(ch) = atoi(line);
@ -337,10 +378,10 @@ int load_char(const char *name, struct char_data *ch)
case 'H': case 'H':
if (!strcmp(tag, "Hit ")) load_HMVS(ch, line, LOAD_HIT); if (!strcmp(tag, "Hit ")) load_HMVS(ch, line, LOAD_HIT);
else if (!strcmp(tag, "Hite")) GET_HEIGHT(ch) = atoi(line); else if (!strcmp(tag, "Hite")) GET_HEIGHT(ch) = atoi(line);
else if (!strcmp(tag, "Host")) { else if (!strcmp(tag, "Host")) {
if (GET_HOST(ch)) if (GET_HOST(ch))
free(GET_HOST(ch)); free(GET_HOST(ch));
GET_HOST(ch) = strdup(line); GET_HOST(ch) = strdup(line);
} }
else if (!strcmp(tag, "Hrol")) GET_HITROLL(ch) = atoi(line); else if (!strcmp(tag, "Hrol")) GET_HITROLL(ch) = atoi(line);
else if (!strcmp(tag, "Hung")) GET_COND(ch, HUNGER) = atoi(line); else if (!strcmp(tag, "Hung")) GET_COND(ch, HUNGER) = atoi(line);
@ -356,7 +397,7 @@ int load_char(const char *name, struct char_data *ch)
if (!strcmp(tag, "Last")) ch->player.time.logon = atol(line); if (!strcmp(tag, "Last")) ch->player.time.logon = atol(line);
else if (!strcmp(tag, "Lern")) GET_PRACTICES(ch) = atoi(line); else if (!strcmp(tag, "Lern")) GET_PRACTICES(ch) = atoi(line);
else if (!strcmp(tag, "Levl")) GET_LEVEL(ch) = atoi(line); else if (!strcmp(tag, "Levl")) GET_LEVEL(ch) = atoi(line);
else if (!strcmp(tag, "Lmot")) GET_LAST_MOTD(ch) = atoi(line); else if (!strcmp(tag, "Lmot")) GET_LAST_MOTD(ch) = atoi(line);
else if (!strcmp(tag, "Lnew")) GET_LAST_NEWS(ch) = atoi(line); else if (!strcmp(tag, "Lnew")) GET_LAST_NEWS(ch) = atoi(line);
break; break;
@ -417,13 +458,13 @@ int load_char(const char *name, struct char_data *ch)
else if (!strcmp(tag, "Thr4")) GET_SAVE(ch, 3) = atoi(line); else if (!strcmp(tag, "Thr4")) GET_SAVE(ch, 3) = atoi(line);
else if (!strcmp(tag, "Thr5")) GET_SAVE(ch, 4) = atoi(line); else if (!strcmp(tag, "Thr5")) GET_SAVE(ch, 4) = atoi(line);
else if (!strcmp(tag, "Titl")) GET_TITLE(ch) = strdup(line); else if (!strcmp(tag, "Titl")) GET_TITLE(ch) = strdup(line);
else if (!strcmp(tag, "Trig") && CONFIG_SCRIPT_PLAYERS) { else if (!strcmp(tag, "Trig") && CONFIG_SCRIPT_PLAYERS) {
if ((t_rnum = real_trigger(atoi(line))) != NOTHING) { if ((t_rnum = real_trigger(atoi(line))) != NOTHING) {
t = read_trigger(t_rnum); t = read_trigger(t_rnum);
if (!SCRIPT(ch)) if (!SCRIPT(ch))
CREATE(SCRIPT(ch), struct script_data, 1); CREATE(SCRIPT(ch), struct script_data, 1);
add_trigger(SCRIPT(ch), t, -1); add_trigger(SCRIPT(ch), t, -1);
} }
} }
break; break;
@ -462,7 +503,7 @@ int load_char(const char *name, struct char_data *ch)
void save_char(struct char_data * ch) void save_char(struct char_data * ch)
{ {
FILE *fl; FILE *fl;
char filename[40], buf[MAX_STRING_LENGTH], bits[127], bits2[127], bits3[127], bits4[127]; char filename[40], buf[MAX_STRING_LENGTH], bits[127], bits2[127], bits3[127], bits4[127];
int i, id, save_index = FALSE; int i, id, save_index = FALSE;
struct affected_type *aff, tmp_aff[MAX_AFFECT]; struct affected_type *aff, tmp_aff[MAX_AFFECT];
struct obj_data *char_eq[NUM_WEARS]; struct obj_data *char_eq[NUM_WEARS];
@ -554,9 +595,9 @@ void save_char(struct char_data * ch)
fprintf(fl, "Plyd: %d\n", ch->player.time.played); fprintf(fl, "Plyd: %d\n", ch->player.time.played);
fprintf(fl, "Last: %ld\n", (long)ch->player.time.logon); fprintf(fl, "Last: %ld\n", (long)ch->player.time.logon);
if (GET_LAST_MOTD(ch) != PFDEF_LASTMOTD) if (GET_LAST_MOTD(ch) != PFDEF_LASTMOTD)
fprintf(fl, "Lmot: %d\n", (int)GET_LAST_MOTD(ch)); fprintf(fl, "Lmot: %d\n", (int)GET_LAST_MOTD(ch));
if (GET_LAST_NEWS(ch) != PFDEF_LASTNEWS) if (GET_LAST_NEWS(ch) != PFDEF_LASTNEWS)
fprintf(fl, "Lnew: %d\n", (int)GET_LAST_NEWS(ch)); fprintf(fl, "Lnew: %d\n", (int)GET_LAST_NEWS(ch));
if (GET_HOST(ch)) fprintf(fl, "Host: %s\n", GET_HOST(ch)); if (GET_HOST(ch)) fprintf(fl, "Host: %s\n", GET_HOST(ch));
@ -565,24 +606,24 @@ void save_char(struct char_data * ch)
if (GET_ALIGNMENT(ch) != PFDEF_ALIGNMENT) fprintf(fl, "Alin: %d\n", GET_ALIGNMENT(ch)); if (GET_ALIGNMENT(ch) != PFDEF_ALIGNMENT) fprintf(fl, "Alin: %d\n", GET_ALIGNMENT(ch));
sprintascii(bits, PLR_FLAGS(ch)[0]); sprintascii(bits, PLR_FLAGS(ch)[0]);
sprintascii(bits2, PLR_FLAGS(ch)[1]); sprintascii(bits2, PLR_FLAGS(ch)[1]);
sprintascii(bits3, PLR_FLAGS(ch)[2]); sprintascii(bits3, PLR_FLAGS(ch)[2]);
sprintascii(bits4, PLR_FLAGS(ch)[3]); sprintascii(bits4, PLR_FLAGS(ch)[3]);
fprintf(fl, "Act : %s %s %s %s\n", bits, bits2, bits3, bits4); fprintf(fl, "Act : %s %s %s %s\n", bits, bits2, bits3, bits4);
sprintascii(bits, AFF_FLAGS(ch)[0]); sprintascii(bits, AFF_FLAGS(ch)[0]);
sprintascii(bits2, AFF_FLAGS(ch)[1]); sprintascii(bits2, AFF_FLAGS(ch)[1]);
sprintascii(bits3, AFF_FLAGS(ch)[2]); sprintascii(bits3, AFF_FLAGS(ch)[2]);
sprintascii(bits4, AFF_FLAGS(ch)[3]); sprintascii(bits4, AFF_FLAGS(ch)[3]);
fprintf(fl, "Aff : %s %s %s %s\n", bits, bits2, bits3, bits4); fprintf(fl, "Aff : %s %s %s %s\n", bits, bits2, bits3, bits4);
sprintascii(bits, PRF_FLAGS(ch)[0]); sprintascii(bits, PRF_FLAGS(ch)[0]);
sprintascii(bits2, PRF_FLAGS(ch)[1]); sprintascii(bits2, PRF_FLAGS(ch)[1]);
sprintascii(bits3, PRF_FLAGS(ch)[2]); sprintascii(bits3, PRF_FLAGS(ch)[2]);
sprintascii(bits4, PRF_FLAGS(ch)[3]); sprintascii(bits4, PRF_FLAGS(ch)[3]);
fprintf(fl, "Pref: %s %s %s %s\n", bits, bits2, bits3, bits4); fprintf(fl, "Pref: %s %s %s %s\n", bits, bits2, bits3, bits4);
if (GET_SAVE(ch, 0) != PFDEF_SAVETHROW) fprintf(fl, "Thr1: %d\n", GET_SAVE(ch, 0)); if (GET_SAVE(ch, 0) != PFDEF_SAVETHROW) fprintf(fl, "Thr1: %d\n", GET_SAVE(ch, 0));
if (GET_SAVE(ch, 1) != PFDEF_SAVETHROW) fprintf(fl, "Thr2: %d\n", GET_SAVE(ch, 1)); if (GET_SAVE(ch, 1) != PFDEF_SAVETHROW) fprintf(fl, "Thr2: %d\n", GET_SAVE(ch, 1));
if (GET_SAVE(ch, 2) != PFDEF_SAVETHROW) fprintf(fl, "Thr3: %d\n", GET_SAVE(ch, 2)); if (GET_SAVE(ch, 2) != PFDEF_SAVETHROW) fprintf(fl, "Thr3: %d\n", GET_SAVE(ch, 2));
@ -633,11 +674,11 @@ void save_char(struct char_data * ch)
} }
if (GET_QUEST(ch) != PFDEF_CURRQUEST) fprintf(fl, "Qcur: %d\n", GET_QUEST(ch)); if (GET_QUEST(ch) != PFDEF_CURRQUEST) fprintf(fl, "Qcur: %d\n", GET_QUEST(ch));
if (SCRIPT(ch)) { if (SCRIPT(ch)) {
for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next) for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next)
fprintf(fl, "Trig: %d\n",GET_TRIG_VNUM(t)); fprintf(fl, "Trig: %d\n",GET_TRIG_VNUM(t));
} }
/* Save skills */ /* Save skills */
if (GET_LEVEL(ch) < LVL_IMMORT) { if (GET_LEVEL(ch) < LVL_IMMORT) {
fprintf(fl, "Skil:\n"); fprintf(fl, "Skil:\n");
@ -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++) {
@ -766,11 +807,11 @@ void clean_pfiles(void)
int i, ci; int i, ci;
for (i = 0; i <= top_of_p_table; i++) { for (i = 0; i <= top_of_p_table; i++) {
/* We only want to go further if the player isn't protected from deletion /* We only want to go further if the player isn't protected from deletion
* and hasn't already been deleted. */ * and hasn't already been deleted. */
if (!IS_SET(player_table[i].flags, PINDEX_NODELETE) && if (!IS_SET(player_table[i].flags, PINDEX_NODELETE) &&
*player_table[i].name) { *player_table[i].name) {
/* If the player is already flagged for deletion, then go ahead and get /* If the player is already flagged for deletion, then go ahead and get
* rid of him. */ * rid of him. */
if (IS_SET(player_table[i].flags, PINDEX_DELETED)) { if (IS_SET(player_table[i].flags, PINDEX_DELETED)) {
remove_player(i); remove_player(i);
@ -784,12 +825,12 @@ void clean_pfiles(void)
break; break;
} }
} }
/* If we got this far and the players hasn't been kicked out, then he /* If we got this far and the players hasn't been kicked out, then he
* can stay a little while longer. */ * can stay a little while longer. */
} }
} }
} }
/* After everything is done, we should rebuild player_index and remove the /* After everything is done, we should rebuild player_index and remove the
* entries of the players that were just deleted. */ * entries of the players that were just deleted. */
} }