/*
 * Deal with sockets that haven't logged in yet.
 */
void nanny ( DESCRIPTOR_DATA * d, char *argument )
{
  DESCRIPTOR_DATA *d_old, *d_next;

  static char abuf[MSL];
  char buf[MAX_STRING_LENGTH];
  char arg[MAX_INPUT_LENGTH];
  CHAR_DATA *ch;
  CHAR_DATA *victim;
  char *pwdnew;

  //char *p;
  int iClass, race, i, weapon;
  int pos = 0;
  bool fOld;
  bool newbie = FALSE;
  int j = 0;

  while ( isspace ( *argument ) )
    argument++;

  ch = d->character;

  if ( acopy_stage > ACOPY_NONE )
  {
    write_to_buffer ( d,
      "Sorry, the mud is getting ready for a copyover/reboot. Disconnecting...\n\r",
      0 );
    close_socket ( d );
    return;
  }

  switch ( d->connected )
  {

  default:
    bug ( "Nanny: bad d->connected %d.", d->connected );
    close_socket ( d );
    return;

  case CON_GET_NAME:
    if ( argument[0] == '\0' )
    {
      close_socket ( d );
      return;
    }

    argument[0] = UPPER ( argument[0] );
    if ( !check_parse_name ( argument ) )
    {
      write_to_buffer ( d,
        "That is not an acceptable name!\n\rTry another...\n\r", 0 );
      write_to_buffer ( d, "\n\rName: ", 0 );
      return;
    }

    fOld = load_char_obj ( d, argument );
    ch = d->character;

    if ( IS_SET ( ch->act, PLR2_GMUD ) )
      d->gmud = TRUE;
    else
      d->gmud = FALSE;

    if ( IS_SET ( ch->act, PLR2_PUTTY ) )
      d->putty = TRUE;
    else
      d->putty = FALSE;

    if ( IS_SET ( ch->act, PLR_NOCOLOUR ) )
      d->ansi = FALSE;
    else
      d->ansi = TRUE;

    if ( IS_SET ( ch->act, PLR_DENY ) )
    {
      sprintf ( log_buf, "Denying access to %s@%s.", argument, d->host );
      log_string ( log_buf );
      wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, 0 );
      write_to_buffer ( d, "You are denied access! Get outta here!\n\r", 0 );
      close_socket ( d );
      return;
    }

    if ( check_ban ( d->host, BAN_PERMIT ) && !IS_SET ( ch->act, PLR_PERMIT ) )
    {
      write_to_buffer ( d, "Your site has been banned! SHOVE OFF!\n\r", 0 );
      close_socket ( d );
      return;
    }
    if ( IS_SET ( ch->act2, PLR2_WIPED ) )
    {
      close_socket ( d );
      return;
    }

    if ( check_reconnect ( d, argument, FALSE ) )
    {
      fOld = TRUE;
    }
    else
    {
      if ( wizlock && ( !IS_IMMORTAL ( ch ) ) )
      {
        write_to_buffer ( d,
          "\n\rOnly gods are allowed in here right now... Sorry buddy.\n\r",
          0 );
        if ( !IS_IMMORTAL ( ch ) )
        {
          close_socket ( d );
          return;
        }
      }
    }

    if ( fOld )
    {
      write_to_buffer ( d, "\n\rWhat is your password? ", 0 );
      write_to_buffer ( d, echo_off_str, 0 );
      d->connected = CON_GET_OLD_PASSWORD;
      return;
    }
    else
    {
      if ( newlock )
      {
        write_to_buffer ( d,
          "We'\re not taking in any new faces right now... (Newlock)\n\r", 0 );
        close_socket ( d );
        return;
      }

      if ( check_ban ( d->host, BAN_NEWBIES ) )
      {
        write_to_buffer ( d,
          "Boss told me no new faces from those parts of the internet. (Newban)\n\r",
          0 );
        close_socket ( d );
        return;
      }

      sprintf ( buf,
        "\n\rDid I get that right, you want to known as %s {D({GY{D/{RN{D){x? ",
        argument );
      write_to_buffer ( d, buf, 0 );
      d->connected = CON_CONFIRM_NEW_NAME;
      return;
    }
    break;

  case CON_GET_OLD_PASSWORD:
    write_to_buffer ( d, "\n\r", 2 );

    if ( str_cmp ( crypt ( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
    {
      sprintf ( log_buf, "Invalid password by: %s@%s.", ch->name, d->host );
      log_string ( log_buf );
      wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, 0 );

      write_to_buffer ( d,
        "That isn't the password! Get outta here!\n\r\n\rYou have been thrown out the front door!\n\r",
        0 );
      write_to_buffer ( d, echo_on_str, 0 );
      close_socket ( d );
      return;
    }

    write_to_buffer ( d, echo_on_str, 0 );

    if ( check_playing ( d, ch->name ) )
      return;

    ch->pcdata->socket = str_dup ( d->host );
    if ( check_reconnect ( d, ch->name, TRUE ) )
      return;

    sprintf ( log_buf, "%s@%s has logged in.", ch->name, d->host );
    log_string ( log_buf );
    wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, get_trust ( ch ) );

    free_string ( ch->pcdata->socket );
    ch->pcdata->socket = str_dup ( d->host );
    if ( IS_IMMORTAL ( ch ) )
    {
      write_to_buffer ( d,
        "{DWould you like to login {r({WW{r){Dizinvis, {r({WI{r){Dncognito, or {r({WN{r){Dormal?{x",
        0 );
      d->connected = CON_WIZ;
    }

    else
    {
      do_help ( ch, "motd" );
      WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );

      strcpy ( d->inbuf, "blah\n\r" );
      read_from_buffer ( d );

      d->connected = CON_READ_MOTD;
    }

    for ( pos = 0; pos < MAX_DUPES; pos++ )
    {
      if ( ch->pcdata->dupes[pos] == NULL )
        break;

      if ( ( victim = get_char_mortal ( ch, ch->pcdata->dupes[pos] ) ) != NULL )
        force_quit ( victim, "" );
    }

    break;
  case CON_WIZ:
    write_to_buffer ( d, "\n\r", 2 );
    switch ( *argument )
    {
    case 'w':
    case 'W':
      ( ch->invis_level = ch->level );
      do_help ( ch, "imotd" );
      d->connected = CON_READ_MOTD;
      break;
    case 'i':
    case 'I':
      ( ch->incog_level = ch->level );
      do_help ( ch, "imotd" );
      d->connected = CON_READ_MOTD;
      break;
    case 'n':
    case 'N':
      ( ch->incog_level = 0 );
      ( ch->invis_level = 0 );
      do_help ( ch, "imotd" );
      d->connected = CON_READ_MOTD;
      break;
    default:
      write_to_buffer ( d,
        "{RInvalid {Dchoice, entering in {Wnormal{D mode.{x\n\r\n\r", 0 );
      do_help ( ch, "imotd" );
      d->connected = CON_READ_MOTD;
      break;
    }
    break;

  case CON_BREAK_CONNECT:
    switch ( *argument )
    {
    case 'y':
    case 'Y':
      for ( d_old = descriptor_list; d_old != NULL; d_old = d_next )
      {
        d_next = d_old->next;
        if ( d_old == d || d_old->character == NULL )
          continue;

        if ( str_cmp ( ch->name,
            d_old->original ? d_old->original->name : d_old->character->name ) )
          continue;

        close_socket ( d_old );
      }
      free_string ( ch->pcdata->socket );
      ch->pcdata->socket = str_dup ( d->host );
      if ( check_reconnect ( d, ch->name, TRUE ) )
        return;
      write_to_buffer ( d, "\n\rReconnect attempt failed.\n\rName: ", 0 );
      if ( d->character != NULL )
      {
        free_char ( d->character );
        d->character = NULL;
      }
      d->connected = CON_GET_NAME;
      break;

    case 'n':
    case 'N':
      write_to_buffer ( d, "\n\rName: ", 0 );
      if ( d->character != NULL )
      {
        free_char ( d->character );
        d->character = NULL;
      }
      d->connected = CON_GET_NAME;
      break;

    default:
      write_to_buffer ( d, "\n\rPlease type Y or N? ", 0 );
      break;
    }
    break;

  case CON_CONFIRM_NEW_NAME:
    switch ( *argument )
    {
    case 'y':
    case 'Y':
      sprintf ( buf,
        "\n\r\n\rPlease consider using one of these random passwords for your security:\n\r" );
      write_to_buffer ( d, buf, 0 );

      buf[0] = '\0';
      for ( i = 0; i < 15; i++ )
      {
        sprintf ( buf, "%s\n\r", gen_random_pass (  ) );
        write_to_buffer ( d, buf, 0 );
      }

      sprintf ( buf,
        "\n\rWelcome newcomer!\n\rWhat shall your password be, %s? %s",
        ch->name, echo_off_str );
      free_string ( ch->pcdata->socket );
      ch->pcdata->socket = str_dup ( d->host );
      write_to_buffer ( d, buf, 0 );
      d->connected = CON_GET_NEW_PASSWORD;
      break;

    case 'n':
    case 'N':
      write_to_buffer ( d, "\n\rNo? Okay, what DID you want to be known as? ",
        0 );
      free_char ( d->character );
      d->character = NULL;
      d->connected = CON_GET_NAME;
      break;

    default:
      write_to_buffer ( d, "Yes or No? ", 0 );
      break;
    }
    break;

  case CON_BEGIN_REROLL:
    write_to_buffer ( d, "{RThese are the races we know of here:{x\n\r", 0 );
    pos = 0;
    do_help ( ch, "RACES" );
    write_to_buffer ( d, "\n\r", 0 );
    write_to_buffer ( d,
      "What is your race ({Dhelp {r<{Drace{r>{W for more information)? ", 0 );
    d->connected = CON_GET_NEW_RACE;
    break;

  case CON_GET_NEW_PASSWORD:
    sprintf ( log_buf, "%s@%s new player.", ch->name, d->host );
    log_string ( log_buf );
    wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, get_trust ( ch ) );
    write_to_buffer ( d, "\n\r", 2 );

    pwdnew = crypt ( argument, ch->name );
    if ( password_unclean ( argument ) )
    {
      write_to_buffer ( d, "( 0-9, A-Z, 5 to 30 characters )\n\r", 0 );
      write_to_buffer ( d,
        "Look, give me a real password or forget about it!\n\rNow then, what did you want your password to be? ",
        0 );
      return;
    }

    free_string ( ch->pcdata->pwd );
    ch->pcdata->pwd = str_dup ( pwdnew );
    write_to_buffer ( d,
      "Give that to me again, just to make sure I got that right: ", 0 );
    d->connected = CON_CONFIRM_NEW_PASSWORD;
    break;

  case CON_CONFIRM_NEW_PASSWORD:

    if ( password_unclean ( argument ) )
    {
      write_to_buffer ( d, "( 0-9, A-Z, 5 to 30 characters )\n\r", 0 );
      write_to_buffer ( d,
        "Look, give me a real password or forget about it!\n\rNow then, what did you want your password to be? ",
        0 );
      d->connected = CON_GET_NEW_PASSWORD;
      return;
    }
    if ( str_cmp ( crypt ( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
    {
      write_to_buffer ( d,
        "\n\rWhat? Thats not what you said the first time! Bah!\n\rWhat did you want your password to be ya half-wit? ",
        0 );
      d->connected = CON_GET_NEW_PASSWORD;
      return;
    }

    free_string ( ch->pcdata->socket );
    ch->pcdata->socket = str_dup ( d->host );
    write_to_buffer ( d, echo_on_str, 0 );

    write_to_buffer ( d,
      "\n\rDo you want to turn {ROFF{x all the pretty {rc{yo{gl{co{br{ms {D({GY{D/{RN{D){x? ",
      0 );
    d->connected = CON_GET_ANSI;
    break;

  case CON_GET_ANSI:
    switch ( argument[0] )
    {
    case 'y':
    case 'Y':
      d->ansi = FALSE;
      SET_BIT ( ch->act, PLR_NOCOLOUR );
      break;
    case 'n':
    case 'N':
      d->ansi = TRUE;
      REMOVE_BIT ( ch->act, PLR_NOCOLOUR );
      break;
    default:
      write_to_buffer ( d,
        "\n\rI said {GYES{x or {RNO{x, are ya deaf or somethin?! ", 0 );
      return;
    }
    write_to_buffer ( d, "\n\rWhat is your sex? {D({CM{D/{MF{D/{WN{D){x ", 0 );
    d->connected = CON_GET_NEW_SEX;
    break;

  case CON_GET_NEW_RACE:
    one_argument ( argument, arg );

    if ( !str_cmp ( arg, "help" ) )
    {
      argument = one_argument ( argument, arg );
      if ( argument[0] == '\0' )
        do_help ( ch, "race help" );
      else
        do_help ( ch, argument );
      write_to_buffer ( d,
        "What race are ya? ({Dhelp {r<{Drace{r>{W for more information){x ",
        0 );
      break;
    }

    race = race_lookup ( argument );

    if ( race == 0 || !race_table[race].pc_race
      || !IS_SET ( ch->pcdata->ctier, pc_race_table[race].tier ) )
    {
      write_to_buffer ( d, "\n\r{RI've never heard of such a thing!{x\n\r", 0 );
      write_to_buffer ( d,
        "What is yer race? ({Dhelp {r<{Drace{r>{W for more information) ", 0 );
      break;
    }

    ch->race = race;
    
    int x = 0;

    for ( x = 0; x < MAX_STATS; x++ )
    {
      ch->temp_stat[x] = pc_race_table[ch->race].rec_stats[x];
      ch->max_stat[x] = pc_race_table[ch->race].rec_stats[x];
      ch->perm_stat[x] = pc_race_table[ch->race].min_stats[x];
    }
    ch->act = ch->act | race_table[race].act;
    ch->act2 = ch->act2 | race_table[race].act2;
    ch->affected_by = ch->affected_by | race_table[race].aff;
    ch->shielded_by = ch->shielded_by | race_table[race].shd;
    ch->imm_flags = ch->imm_flags | race_table[race].imm;
    ch->res_flags = ch->res_flags | race_table[race].res;
    ch->vuln_flags = ch->vuln_flags | race_table[race].vuln;
    ch->form = race_table[race].form;
    ch->parts = race_table[race].parts;
    ch->gne = race_table[race].gne;
    ch->ethos = race_table[race].ethos;

    for ( i = 0; i < 5; i++ )
    {
      if ( pc_race_table[race].skills[i] == NULL )
        break;
      group_add ( ch, pc_race_table[race].skills[i], FALSE );
    }

    ch->pcdata->points = pc_race_table[race].points;
    ch->size = pc_race_table[race].size;

    write_to_buffer ( d, "\n\r\n\r{x", 0 );
    int t = 0;
    int z = 0;
    bool cfound = FALSE;
    char buf[MSL];
    char classname[MSL];
    char bright[MSL];
    char dark[MSL];
    char sep[MSL];

    sprintf ( sep,
      "{D+{r---------------{D+{r---------------{D+{r---------------{D+{r---------------{D+{x\n\r" );
    write_to_buffer ( d, sep, 0 );

    for ( i = 4; i < MAX_CLASS; i++ )
      for ( x = 0; x <= 4; x++ )
      {
        if ( IS_SET ( class_table[i].tier, TIER_01 ) )
        {
          sprintf ( bright, "{G" );
          sprintf ( dark, "{g" );
          t = 1;
        }
        if ( IS_SET ( class_table[i].tier, TIER_02 ) )
        {
          sprintf ( bright, "{C" );
          sprintf ( dark, "{c" );
          t = 2;
        }
        if ( IS_SET ( class_table[i].tier, TIER_03 ) )
        {
          sprintf ( bright, "{M" );
          sprintf ( dark, "{m" );
          t = 3;
        }
        if ( IS_SET ( class_table[i].tier, TIER_04 ) )
        {
          sprintf ( bright, "{R" );
          sprintf ( dark, "{r" );
          t = 4;
        }

        if ( t == x )
        {
          classname[0] = '\0';
          for ( z = 0; class_table[i].name[z] != '\0'; z++ )
          {
            sprintf ( buf, "%s%s%s%c", z == 0 ? bright : dark,
              i == ( ch->class + 1 )
              && x != 4 ? bright : "", !IS_SET ( ch->pcdata->ctier,
                class_table[i].tier ) ? "{D" : "", class_table[i].name[z] );

            strcat ( classname, buf );
          }
          sprintf ( buf, "{r| %s%s", calign_text ( classname, just_left, 13 ),
            x == 4 ? "{r|\n\r" : "" );
          write_to_buffer ( d, buf, 0 );
          cfound = TRUE;
        }
      }
    if ( !cfound )
      do_help ( ch, "NEWCHARTIER" );
    else
      write_to_buffer ( d, sep, 0 );

    write_to_buffer ( d,
      "{x\n\r\n\rThose are the classes available here...{x\n\r", 0 );
    write_to_buffer ( d, "{xWhat class do ya wanna be? ", 0 );
    d->connected = CON_GET_NEW_CLASS;
    break;

  case CON_GET_NEW_SEX:
    switch ( argument[0] )
    {
    case 'm':
    case 'M':
      ch->sex = SEX_MALE;
      ch->pcdata->true_sex = SEX_MALE;
      break;
    case 'f':
    case 'F':
      ch->sex = SEX_FEMALE;
      ch->pcdata->true_sex = SEX_FEMALE;
      break;
    case 'n':
    case 'N':
      ch->sex = SEX_NEUTRAL;
      ch->pcdata->true_sex = SEX_NEUTRAL;
      break;
    default:
      write_to_buffer ( d,
        "\n\r{xAre you some kind of freak? That isn't a sex!\n\rWhat is your sex? ",
        0 );
      return;
    }

    write_to_buffer ( d,
      "\n\rAlright, you\'re all done. Off you go now...\n\r\n\r", 0 );
    do_help ( ch, "motd" );
    WAIT_STATE ( ch, PULSE_PER_SECOND * 15 );

    strcpy ( d->inbuf, "blah\n\r" );
    read_from_buffer ( d );

    d->connected = CON_READ_MOTD;
    break;

  case CON_GET_NEW_CLASS:
    one_argument ( argument, arg );

    if ( !str_cmp ( arg, "help" ) )
    {
      argument = one_argument ( argument, arg );
      if ( argument[0] == '\0' )
        do_help ( ch, "race help" );
      else
        do_help ( ch, argument );
      write_to_buffer ( d,
        "What class did ya wanna be? ({Dhelp {r<{Dclass{r>{x for more information){x ",
        0 );
      break;
    }

    iClass = class_lookup ( argument );

    if ( iClass == -1 )
    {
      write_to_buffer ( d,
        "\n\rI've never heard of that class... You'll have to tell me one I know!\n\rWhat damn class do ya want to be!?! ",
        0 );
      return;
    }
    if ( !IS_SET ( ch->pcdata->ctier, class_table[iClass].tier ) )
    {
      write_to_buffer ( d,
        "\n\rNice try, but I wasn\'t born yesterday. Try a class in YOUR tier!\n\rWhat class do ya want? ",
        0 );
      return;
    }
    ch->class = iClass;

    write_to_buffer ( d, "\n\r", 0 );
    group_add ( ch, "rom basics", FALSE );
    group_add ( ch, class_table[ch->class].base_group, FALSE );
    ch->pcdata->learned[gsn_recall] = 50;
    write_to_buffer ( d,
      "\n\rHere at {YD{yawn {Dof {RA{rcheron{x we advise only veteran mudders to customize.{x\n\r",
      0 );
    write_to_buffer ( d,
      "Do you wish to customize this character's skills? {D({GY{D/{RN{D){x? ",
      0 );
    d->connected = CON_DEFAULT_CHOICE;
    break;

  case CON_DEFAULT_CHOICE:
    j = 0;
    write_to_buffer ( d, "\n\r", 2 );
    switch ( argument[0] )
    {
    case 'y':
    case 'Y':
      ch->gen_data = new_gen_data (  );
      ch->gen_data->points_chosen = ch->pcdata->points;
      write_to_buffer ( d, "\n\r", 2 );
      do_help ( ch, "group header" );
      list_group_costs ( ch );
      write_to_buffer ( d, "You already have the following skills:\n\r", 0 );
      do_skills ( ch, "" );
      send_to_char
        ( "{WChoices are: list,learned,premise,add,drop,info,help, and done.{x\n\r",
        ch );
      d->connected = CON_GEN_GROUPS;
      break;
    case 'n':
    case 'N':
      group_add ( ch, class_table[ch->class].default_group, TRUE );
      write_to_buffer ( d, "\n\r", 2 );
      write_to_buffer ( d,
        "What weapon do you want to be most proficiant with?\n\r", 0 );
      buf[0] = '\0';
      for ( i = 0; weapon_table[i].name != NULL; i++ )
        if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
        {
          strcat ( buf, weapon_table[i].name );
          strcat ( buf, " " );
          j++;
        }

      if ( j == 0 )
      {
        write_to_buffer ( d,
          "Sorry, for some reason there are none for you to choose from!\n\r",
          0 );

        write_to_buffer ( d, "\n\r\n\r", 2 );
        do_help ( ch, "motd" );

        WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );
        strcpy ( d->inbuf, "blah\n\r" );
        read_from_buffer ( d );

        d->connected = CON_READ_MOTD;
        break;
      }

      strcat ( buf, "\n\r\n\rWhat is your choice? " );
      write_to_buffer ( d, buf, 0 );
      d->connected = CON_PICK_WEAPON;
      break;
    default:
      write_to_buffer ( d,
        "What kinda answer is that? Yes, or no? {D({YY{D/{RN{D){x ", 0 );
      return;
    }
    break;

  case CON_PICK_WEAPON:
    j = 0;
    write_to_buffer ( d, "{x \n\r", 2 );
    weapon = weapon_lookup ( argument );
    if ( weapon == -1 || ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0 )
    {
      write_to_buffer ( d,
        "\n\rThat wasn't one of yer choices! Ya can choose:\n\r", 0 );

      buf[0] = '\0';
      for ( i = 0; weapon_table[i].name != NULL; i++ )
        if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
        {
          strcat ( buf, weapon_table[i].name );
          strcat ( buf, " " );
          j++;
        }
      if ( j == 0 )
      {
        write_to_buffer ( d,
          "Sorry, for some reason there are none for you to choose from!\n\r",
          0 );

        write_to_buffer ( d, "\n\r\n\r", 2 );
        do_help ( ch, "motd" );

        WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );
        strcpy ( d->inbuf, "blah\n\r" );
        read_from_buffer ( d );

        d->connected = CON_READ_MOTD;
        break;
      }
      else
      {
        strcat ( buf, "\n\rSo, what is your choice? " );
        write_to_buffer ( d, buf, 0 );
        return;
      }
    }

    if ( j > 0 )
      ch->pcdata->learned[*weapon_table[weapon].gsn] = 40;

    write_to_buffer ( d,
      "\n\r\n\rHere at {YD{yawn {Dof {RA{rcheron{x we advise only veteran mudders to customize.\n\r",
      0 );
    write_to_buffer ( d,
      "Do you wish to customize this character's stats? {D({GY{D/{RN{D){x ",
      0 );
    d->connected = CON_CUSTOMIZE;
    break;

  case CON_CUSTOMIZE:

    switch ( argument[0] )
    {
    case 'y':
    case 'Y':
      print_char_stats ( ch );
      d->connected = CON_CUSTOMIZE_STATS;
      send_to_char
        ( "{wCommands{R:  {whelp{r, {wrevert{r, {wcancel{r, {wshow{r, {wdone{R.{x\n\r",
        ch );
      break;
    case 'n':
    case 'N':
      write_to_buffer ( d, "\n\r\n\r", 2 );
      do_help ( ch, "motd" );
      WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );
      strcpy ( d->inbuf, "blah\n\r" );
      read_from_buffer ( d );
      d->connected = CON_READ_MOTD;
      break;
    default:
      write_to_buffer ( d, "\n\rWhat? I said yes, or no! {D({GY{D/{RN{D){x ",
        0 );
      break;
    }
    break;

  case CON_CUSTOMIZE_STATS:
    if ( parse_custom_stats ( ch, argument ) )
    {
      if ( d->connected == CON_READ_MOTD )
      {
        send_to_char ( "\n\r\n\r", ch );
        do_help ( ch, "motd" );
        WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );
        strcpy ( ch->desc->inbuf, "blah\n\r" );
        read_from_buffer ( ch->desc );
        break;
      }
      print_char_stats ( ch );
    }
    send_to_char
      ( "{wCommands{R:  {whelp{r, {wrevert{r, {wcancel{r, {wshow{r, {wdone{R.{x\n\r",
      ch );
    break;

  case CON_GEN_GROUPS:
    j = 0;
    send_to_char ( "\n\r", ch );
    if ( !str_cmp ( argument, "done" ) )
    {
      sprintf ( buf, "{WCreation points: {b%d{x\n\r", ch->pcdata->points );
      send_to_char ( buf, ch );
      sprintf ( buf, "{WExperience per level: {Y%ld{x\n\r",
        ( long ) exp_per_level ( ch, ch->gen_data->points_chosen ) );
      if ( ch->pcdata->points < 40 )
        ch->train = ( 40 - ch->pcdata->points + 1 ) / 2;
      free_gen_data ( ch->gen_data );
      ch->gen_data = NULL;
      send_to_char ( buf, ch );
      write_to_buffer ( d, " \n\r", 2 );
      write_to_buffer ( d,
        "{WWhat weapon do you want to be most proficiant with?{x\n\r", 0 );
      buf[0] = '\0';
      for ( i = 0; weapon_table[i].name != NULL; i++ )
        if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
        {
          strcat ( buf, weapon_table[i].name );
          strcat ( buf, " " );
          j++;
        }
      if ( j == 0 )
      {
        write_to_buffer ( d,
          "Sorry, for some reason there are none for you to choose from!\n\r",
          0 );

        write_to_buffer ( d, "\n\r\n\r", 2 );
        do_help ( ch, "motd" );

        WAIT_STATE ( ch, PULSE_PER_SECOND * 5 );
        strcpy ( d->inbuf, "blah\n\r" );
        read_from_buffer ( d );

        d->connected = CON_READ_MOTD;
        break;
      }
      strcat ( buf, "\n\r{WWhat is your choice?{x " );
      write_to_buffer ( d, buf, 0 );
      d->connected = CON_PICK_WEAPON;
      break;
    }

    if ( !parse_gen_groups ( ch, argument ) )
    {
      sprintf ( buf, "{WCreation points: {R%d{x\n\r", ch->pcdata->points );
      send_to_char ( buf, ch );
      sprintf ( buf, "{WExperience per level: {B%ld{x\n\r", exp_per_level ( ch,
          ch->gen_data->points_chosen ) );
      send_to_char ( buf, ch );
    }

    send_to_char
      ( "{WChoices are: list,learned,premise,add,drop,info,help, and done.{x\n\r",
      ch );
    break;

  case CON_READ_IMOTD:
    write_to_buffer ( d, "\n\r", 2 );
    do_help ( ch, "motd" );

    strcpy ( d->inbuf, "blah\n\r" );
    read_from_buffer ( d );

    d->connected = CON_READ_MOTD;
    break;

  case CON_READ_MOTD:

    if ( IS_QUESTOR ( ch ) )
    {
      do_quest ( ch, "info" );
      if ( ch->pcdata->questobj > 0 )
      {
        OBJ_INDEX_DATA *pObj = NULL;
        OBJ_DATA *obj = NULL;
        ROOM_INDEX_DATA *pRoom = NULL;

        if ( ( pObj = get_obj_index ( ch->pcdata->questobj ) ) == NULL )
          end_quest ( ch, 0 );
        else
          obj = create_object ( pObj, ch->level );

        if ( ( pRoom = get_room_index ( ch->pcdata->questloc ) ) == NULL )
          pRoom = get_random_room ( ch );

        obj_to_room ( obj, pRoom );
      }
    }

    if ( ch->pcdata->pwd[0] == '\0' )
    {
      write_to_buffer ( d,
        "{Y*** {RYour password is corrupt, assigning new password {Y***\n\r",
        0 );
      char newpass[100];
      char cpass[100];

      sprintf ( newpass, "%s", gen_random_pass (  ) );
      sprintf ( cpass, "%s", crypt ( newpass, ch->name ) );

      free_string ( ch->pcdata->pwd );
      ch->pcdata->pwd = str_dup ( cpass );
      save_char_obj ( ch );

      write_to_buffer ( d, "{Y*** {RYour {YNEW {Rpassword is{Y: {W", 0 );
      write_to_buffer ( d, newpass, 0 );
      write_to_buffer ( d, "\n\rPlease re-enter your new password: \n\r", 0 );
      d->connected = CON_GET_OLD_PASSWORD;
      return;
    }

    write_to_buffer ( d,
      "\n\rWelcome to {YD{yawn {Dof {RA{rcheron{D.  {wWe bite.{x\n\r", 0 );
    ch->next = char_list;
    char_list = ch;
    d->connected = CON_PLAYING;
    reset_char ( ch );
    sprintf ( buf, "{DYou are currently logged in as{R: {W%s{R@{W%s{x\n\r\n\r",
      ch->name, d->host );
    send_to_char ( buf, ch );

    DESCRIPTOR_DATA *wd;

    for ( wd = descriptor_list; wd != NULL; wd = wd->next )
      wd->checked = FALSE;

    for ( wd = descriptor_list; wd != NULL; wd = wd->next )
    {
      if ( wd != d && wd->character )
      {
        if ( d->ipa == wd->ipa && d->ipb == wd->ipb && d->ipc == wd->ipc
          && d->ipd == wd->ipd )
        {
          sprintf ( buf, "%s & %s are on the same internet connection.\n\r",
            d->character->name, wd->character->name );
          wiznet ( buf, NULL, NULL, WIZ_LOGINS, 0, 0 );
        }
        else if ( d->ipa == wd->ipa && d->ipb == wd->ipb && d->ipc == wd->ipc )
        {
          sprintf ( buf, "%s & %s are on the same subnet.\n\r",
            d->character->name, wd->character->name );
          wiznet ( buf, NULL, NULL, WIZ_LOGINS, 0, 0 );
        }
      }
    }

    if ( ch->pcdata->uid <= 0 )
    {
      char buf[MLL];

      uid_top++;
      ch->pcdata->uid = uid_top;

      sprintf ( buf, "%s assigned UID: %ld\n\r", ch->name, ch->pcdata->uid );
      wiznet ( buf, NULL, NULL, WIZ_NEWBIE, 0, 0 );
    }
    update_plist ( ch, FALSE );

    ch->pcdata->bonustime = 0;

    if ( ch->level == 0 )
    {

      ch->perm_stat[class_table[ch->class].attr_prime] += 1;
      ch->perm_stat[class_table[ch->class].attr_second] += 1;

      newbie = TRUE;
      ch->level = 1;
      ch->pcdata->newclan = 1;
      ch->exp = exp_per_level ( ch, ch->pcdata->points );
      ch->hit = ch->max_hit;
      ch->mana = ch->max_mana;
      ch->move = ch->max_move;
      ch->train = 15;
      ch->practice = 35;
      if ( ch->class == 0 )
      {
        set_title ( ch, "is a n00b." );

        if ( !ch->pcdata->colorname )
          ch->pcdata->colorname = str_dup ( ch->name );
      }
      if ( ch->class > 0 )
        do_pack ( ch, "self" );
      do_prompt ( ch, "all" );
      do_config ( ch, "newbie" );
      obj_to_char ( create_object ( get_obj_index ( OBJ_VNUM_MAP ), 0 ), ch );
      char_to_room ( ch, get_room_index ( ROOM_VNUM_SCHOOL ) );
    }
    else if ( ch->in_room != NULL )
    {
      char_to_room ( ch, ch->in_room );
    }
    else if ( IS_IMMORTAL ( ch ) )
    {
      char_to_room ( ch, get_room_index ( ROOM_VNUM_CHAT ) );
    }
    else
    {
      char_to_room ( ch, get_room_index ( ROOM_VNUM_TEMPLE ) );
    }

    if ( IS_IMMORTAL ( ch ) )
    {
      sprintf ( abuf, "{xis now watching over you." );
      send_to_channel ( abuf, CHAN_NO_ANNOUNCE, ch, ch );
    }
    else
    {
      sprintf ( abuf, "{xhas entered {YD{yawn {Dof {RA{rcheron{w." );
      send_to_channel ( abuf, CHAN_NO_ANNOUNCE, ch, ch );
    }
    logins++;
    last_login_time = current_time;

    if ( ch->pet != NULL )
    {
      char_to_room ( ch->pet, ch->in_room );
      act ( "$n appears with its owner.", ch->pet, NULL, NULL, TO_ROOM );
    }
    if ( newbie )
    {
      printf_to_char ( ch,
        "\n\r{wFor a list of commands type COMMANDS.\n\rTo see where you are, type LOOK.\n\r" );
    }
    do_look ( ch, "auto" );
    break;
  }
  return;
}
