Re: Changing Player's Name (mem leak in do_set)

From: Michael Buselli (mhbusell@midway.uchicago.edu)
Date: 12/07/95


On 7 Dec 1995, David A. Carver wrote:

> I've modified the table int act.wizard.c in do_set to accept another flag 
> called NAME.  The format of this command is:
> 
> set victim name <new name>
> 
> The function is semi-working.  It changes the name in the player file, but 
> if I try and do a STAT FILE <new name>, it says it cannot find the player 
> in the file.  However, if I shut the mud down and then reboot it can find 
> the player with the new name.
> 
> Here is the simple set of code I'm using:
>    case 48:
>        strncpy(GET_NAME(vict), val_arg, MAX_NAME_LENGTH)
>        
> That is it.   Is there anything else I need to change to get it to take 
> immediate affect on line without rebooting the mud?
> 
> (Yeah, I know this isn't very secure, and that duplicate names could 
> happen, but for now I just want to take care of getting this part of the 
> function working correctly.)

     You need to make sure that you update the table that keeps id numbers
and player names.  The reason things work at boot time is that the mud
creates the table at boot time, adding newbies as needed.  You also should
fix that code too, since it's buggy (messes up id numbers for newbies that
are using the name of an old deleted character).  I told Jeremy of the
bug, but since he responded in disbelief of its existance, I don't know if
he fixed it yet for pl9.  Trust me that if you don't fix that bug, chaos
will emerge from using the set name command on a newbie, since name/id
lookups will fail.

     And no, I haven't forgotten the many hours I blamed my own code for 
the problems before I found the real fix.  Grrrr.

Michael Buselli

P.S. Okay, I've just decided to include parts of my code for it.  Please 
note the memory leak fix in do_set().  Also, I changed rent files on my 
mud to pick a name by id number of the character, which is always 
constant, so you'll have to call Crash_crashdelete and Crash_crashsave or 
whatever those functions are called (I don't always remember these things 
off the top of my head) to make sure duping of eq doesn't occur after the 
name change.  Fun fun.

/* Nice little fix to a nice little memory leak in do_set().
 * I use it everywhere I go in this function. -mhb
 */ 
#define RETURN { if (is_file) free_char(cbuf); return; }

   { "playernam",       LVL_IMPL,       PC,     MISC },    /* 60 */
   { "playername",      LVL_IMPL,       PC,     MISC },

 case 60:
    send_to_char("Changing a player's PLAYERNAME is dangerous... type it 
all out
 if you're sure.\r\n", ch);
    RETURN;
  case 61:
    any_one_arg(val_arg, buf);
    if (buf == NULL || strlen(buf) <= 2) {
      send_to_char("Perhaps a longer name would be nice?\r\n", ch);
      RETURN;
    }
    else if ((i = get_id_by_name(buf)) != -1) {
      send_to_char("A player by that name already exists!", ch);
      RETURN;
    }
    else {
      CAP(buf);
      sprintf(buf1, "%s has been rechristened %s!", vict->player.name, buf);
      infolog(buf1, "", NULL);
      free(vict->player.name);
      vict->player.name = str_dup(buf);
      for (i = 0; i <= top_of_p_table; i++)
        if ((player_table + i)->id == GET_IDNUM(vict))
          break;
     if ((player_table + i)->name)   /* Another redundant check? */
        free((player_table + i)->name);
      CREATE((player_table + i)->name, char, strlen(buf) + 1);
      for (j = 0;
           (*((player_table + i)->name + j) = LOWER(buf[j])); j++);
      sprintf(buf, "Done.  That player will now be known as %s.", 
GET_REAL_NAME(
vict));
      check_autowiz(vict, GET_LEVEL(vict));
    }
    break;



This archive was generated by hypermail 2b30 : 12/07/00 PST