Пример #1
0
int event_idle(EVENT_DATA *event)
{
  DESCRIPTOR_DATA *d = event->owner.ch->d;
  if (d->acc->ch->level >= LEVEL_IMMORTAL) /* imms don't idle off, they go afk */
  {
    event->ticks_left = IDLE_OUT;
    if (!IS_SET(d->acc->ch->tflags, CTFLAG_AFK))
      do_afk(d->acc->ch, " ");
    else
    {
      char buf[512];
      time_words_long(event->owner.ch->idle, buf);
      strlpre(buf, "\n#cYou have been idle for ", 512);
      strlcat(buf, ".\n", 512);
      send_to_char(event->owner.ch, buf);
    }
    return 0;
  }

  syslog("DISCONNECT", "%s (on %s@%s) has been booted because of prolonged inactivity.", d->acc->ch->name, d->acc->name, d->ip);
  sckoutput(d->socket, "\n\33[1;31mYou have been idle for too long.\n");
  save_account(d->acc);
  logout_msg(d->acc->ch);

  wipe_character(d->acc->ch);
  wipe_descriptor(d);
  return 1;
}
Пример #2
0
int event_save(EVENT_DATA *event)
{
  save_account(event->owner.ch->acc);

  event->ticks_left = TICKS_PER_SECOND * 120;
  return 0;
}
Пример #3
0
void do_copyover(void) {
  LIST_ITERATOR *sock_i = newListIterator(socket_list);
  SOCKET_DATA     *sock = NULL;
  FILE *fp;
  char buf[100];
  char control_buf[20];
  char port_buf[20];

  if ((fp = fopen(COPYOVER_FILE, "w+")) == NULL)
    return;

  sprintf(buf, "\n\r <*>            The world starts spinning             <*>\n\r");

  // For each playing descriptor, save its character and account
  ITERATE_LIST(sock, sock_i) {
    compressEnd(sock, sock->compressing, FALSE);
    // kick off anyone who hasn't yet logged in a character
    if (!socketGetChar(sock) || !socketGetAccount(sock) || 
	!charGetRoom(socketGetChar(sock))) {
      text_to_socket(sock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n");
      close_socket(sock, FALSE);
    }
    // save account and player info to file
    else {
      fprintf(fp, "%d %s %s %s\n",
	      sock->control, accountGetName(sock->account), 
	      charGetName(sock->player), sock->hostname);
      // save the player
      save_player(sock->player);
      save_account(sock->account);
      text_to_socket(sock, buf);
    }
  } deleteListIterator(sock_i);
Пример #4
0
void finish_creation(DESCRIPTOR_DATA *d, int hardcore)
{
  char buf[MAX_STRING_LENGTH];
  d->state = STATE_ACCT_MENU;
  d->acc->charcount++;
  d->acc->totalchars++;
  d->acc->ch = new_character();
  strlcpy(d->acc->ch->name, d->acc->character[d->acc->charcount-1], 32);
  strlcpy(d->acc->ch->accname, d->acc->name, 32);
  snprintf(buf, MAX_STRING_LENGTH, "Character %s created.\n", d->acc->ch->name);
  send_to_descriptor(d, buf);
  buf[0] = 0;
  if (hardcore)
  {
    SET_BIT(d->acc->ch->cflags, CFLAG_HARDCORE);
    snprintf(buf, MAX_STRING_LENGTH, "hardcore ");
    d->acc->status[d->acc->charcount-1] = CHSTATUS_HARDCORE;
  }
  else
    d->acc->status[d->acc->charcount-1] = CHSTATUS_NORMAL;

  log_time(d->acc->chfirsttime[d->acc->charcount-1]);
  syslog("CREATION", "New %scharacter %s (on %s@%s) has been created.", buf, d->acc->ch->name, d->acc->name, d->ip);
  save_account(d->acc);
  free_character(d->acc->ch);
  d->acc->ch = NULL;
  show_account_menu(d, 1);
  if (d->acc->logins == 1)
    send_to_descriptor(d, "\n#r[#1HINT#r]#3 Press '#R1#3' to log into your new character.\n");
}
Пример #5
0
void Svcmd_GiveAdmin_f ( void )
{
	int client_id = -1; 
    char   arg1[MAX_STRING_CHARS];

	if (trap->Argc() != 2) 
    {
		trap->Print( "Usage: giveadmin <player>\n");
		return;
    }

	trap->Argv( 1,  arg1, sizeof( arg1 ) );

	client_id = ClientNumberFromString( NULL, arg1, qfalse ); 
	if (client_id == -1)
	{
		return;
	}

	if (g_entities[client_id].client->sess.amrpgmode > 0)
	{
		g_entities[client_id].client->pers.bitvalue |= (1 << ADM_GIVEADM);
		save_account(&g_entities[client_id]);
		trap->Print("GiveAdmin saved successfully.\n");
	}
	else
	{
		trap->Print("Player is not logged in.\n");
	}
}
Пример #6
0
int event_linkdeath(EVENT_DATA *event)
{
  DESCRIPTOR_DATA *d = event->owner.ch->d;

  syslog("DISCONNECT", "%s (on %s@%s) has been booted because of prolonged linkdeath.", d->acc->ch->name, d->acc->name, d->ip);
  save_account(d->acc);
  logout_msg(d->acc->ch);

  wipe_character(d->acc->ch);
  wipe_descriptor(d);
  return 1;
}
Пример #7
0
int event_loginidle(EVENT_DATA *event)
{
  DESCRIPTOR_DATA *d = event->owner.d;

  syslog("DISCONNECT", "%s has been booted because of prolonged inactivity while not logged in.", d->ip);
  sckoutput(d->socket, "\n\33[1;31mYou have been idle for too long.\n");
  close(d->socket);

  if (d->acc->logins > 0) /* aka is this account fully created */
    save_account(d->acc);

  wipe_descriptor(d);
  return 1;
}
Пример #8
0
int save_player(Character *ch)
{

    if (ch->pc == 0)
    {
        log_error("character not a player");
        return 0;
    }
    db_begin_transaction();

    if (!save_account(ch->pc->account))
    {
        return 0;
    }
    int res = save_character(ch, plr_flags);
    const size_t maxCond = MAX_COND;
    field_map pc_values[] =
    {
        {"playerId", &ch->id, SQL_INT},
        {"accountId", &ch->pc->account->id, SQL_INT},
        {"title", &ch->pc->title, SQL_TEXT},
        {"roomId", (ch->inRoom ? &ch->inRoom->id : 0), SQL_INT},
        {"prompt", &ch->pc->prompt, SQL_TEXT},
        {"battlePrompt", &ch->pc->battlePrompt, SQL_TEXT},
        {"explored", &ch->pc->explored, SQL_CUSTOM, NULL, NULL, 0, save_explored},
        {"channels", &ch->pc->channels, SQL_FLAG, channel_flags},
        {"condition", &ch->pc->condition, SQL_CUSTOM, NULL, &maxCond, 0, db_save_int_array},
        {"experience", &ch->pc->experience, SQL_INT},
        {"permHit", &ch->pc->permHit, SQL_INT},
        {"permMana", &ch->pc->permMana, SQL_INT},
        {"permMove", &ch->pc->permMove, SQL_INT},
        {"created", &ch->pc->created, SQL_INT},
        {0}
    };

    if (res == 1)
    {

        if (sql_insert_query(pc_values, "player") != SQL_OK)
        {
            log_data("could not insert player");
            return 0;
        }
    }

    else if (res == 2)
    {

        if (sql_update_query(pc_values, "player", ch->id) != SQL_OK)
        {
            log_data("could not update character");
            return 0;
        }
    }

    if (!save_char_objs(ch)) {
        res = 0;
    }

    if (!save_char_affects(ch)) {
        res = 0;
    }
    db_end_transaction();
    return UMIN(res, 1);

}
Пример #9
0
void nanny(DESCRIPTOR_DATA *d, char *input)
{
  int i;
  char buf[MAX_STRING_LENGTH];
  DESCRIPTOR_DATA *dt;

  switch(d->state)
  {
    case STATE_GET_NAME:
      if (input[0] == 0)
      {
        sckoutput(d->socket, "Fine, then.\n");
        wipe_descriptor(d);
        return;
      }
      i = check_string(input, 4, 12, 0);
      if (i == 1)
        send_to_descriptor(d, "Your name must have at least 4 letters.\n");
      else if (i == 2)
        send_to_descriptor(d, "Your name can contain at most 12 letters.\n");
      else if (i == 4 || i == 3)
        send_to_descriptor(d, "Your name can contain only letters.\n");
      else
      {
        input[0] = UPPER(input[0]);
        load_account(input, d->acc);
        d->acc->d = d;

        if (d->acc->name[0] == 0)
        {
          check_address(d->ip, d->acc->name);
          if (d->acc->name[0] != 0 && stricmp(input, d->acc->name))
            send_to_descriptor(d, "#RWARNING:#n Your IP is linked to an existing account. It is against the rules to have multiple accounts.\n\n");

          strlcpy(d->acc->name, input, 32);
          snprintf(buf, MAX_STRING_LENGTH, "Are you sure you want the name %s? ", input);
          send_to_descriptor(d, buf);
          d->state = STATE_CONFIRM_NAME;
          return;
        }

        send_to_descriptor(d, "Password? ");
        send_to_descriptor(d, password_on);
        d->state = STATE_GET_PASS;
        return;
      }
      send_to_descriptor(d, "What do you want your account name to be? ");
    break;


    case STATE_GET_PASS:
      send_to_descriptor(d, password_off);

      if (!strcmp(d->acc->password, input))
      {
        /* check to see if someone else is logged in under this account */
        for (dt = dhead; dt; dt = dt->next)
        {
          if (dt == d || dt->acc == NULL)
            continue;

          if (!stricmp(d->acc->name, dt->acc->name))
          {
            /* d = new connection, dt = old */
            if (dt->socket > 0 && dt->state != STATE_LINKDEAD)
            {
              sckoutput(dt->socket, "\n\nYou have been kicked off.\n");
              close(dt->socket);
            }

            dt->socket = d->socket;
            d->socket = -1; /* this is mandatory because wipe_descriptor closes d->socket */
            wipe_descriptor(d);
            d = dt;

            if (d->state != STATE_PLAYING && d->state != STATE_LINKDEAD)
              send_to_descriptor(d, "\nYou have kicked someone off while they were logging in. Sending you to the account menu.\n");
            else
            {
              destroy_all_events(d->acc->ch, EVENT_LINKDEAD);
              setup_char_events(d->acc->ch);
              d->acc->ch->idle = 0;
              syslog("RECONNECT", "%s (on %s@%s) has reconnected.", d->acc->ch->name, d->acc->name, d->ip);
              d->state = STATE_PLAYING;
              send_to_descriptor(d, "\n#RReconnected.#n\n");
              return;
            }
          }
        }

        syslog("LOGIN", "%s@%s has logged in.", d->acc->name, d->ip);
        d->state = STATE_ACCT_MENU;
        d->acc->logins++;
        save_account(d->acc);
        show_account_menu(d, 0);
        snprintf(buf, MAX_STRING_LENGTH, "#1[#2Last connection from #R%s#2 at #R%s#2.#1]\n", d->acc->lasthost, d->acc->lasttime);
        save_address(d);
        send_to_descriptor(d, buf);
        if (d->acc->failed == 1)
          snprintf(buf, MAX_STRING_LENGTH, "#1[#RWARNING:#2 1 failed login attempt since your last connection.#1]\n");
        else if (d->acc->failed > 1)
          snprintf(buf, MAX_STRING_LENGTH, "#1[#RWARNING:#2 %d failed login attempts since your last connection.#1]\n", d->acc->failed);
        if (d->acc->failed > 0)
        {
          send_to_descriptor(d, buf);
          d->acc->failed = 0;
          save_account(d->acc);
        }
        send_to_descriptor(d, "#nWhat is your choice? ");
        return;
      }

      sckoutput(d->socket, "Incorrect password. Logging you off...\n");
      syslog("PASSWORD", "%s@%s -- incorrect password! Logged off.", d->acc->name, d->ip);
      d->acc->failed++;
      save_account(d->acc);
      wipe_descriptor(d);
    break;

    case STATE_CONFIRM_NAME:
      if (input[0] == 'y' || input[0] == 'Y')
      {
        send_to_descriptor(d, "What do you want your password to be? ");
        syslog("NEW", "New account %s is being created.", d->acc->name);
        d->state = STATE_NEW_PASS;
        send_to_descriptor(d, password_on);
        return;
      }

      send_to_descriptor(d, "Okay. What do you want your name to be? ");
      d->state = STATE_GET_NAME;
    break;

    case STATE_NEW_PASS:
      send_to_descriptor(d, password_off);
      if (input[0] == 0)
      {
        send_to_descriptor(d, "\nWhat do you want your password to be? ");
        send_to_descriptor(d, password_on);
        return;
      }
      i = check_string(input, 4, 12, 1);
      if (i == 1)
        send_to_descriptor(d, "\nYour password must have at least 4 characters.\n");
      else if (i == 2)
        send_to_descriptor(d, "\nYour password can contain at most 12 characters.\n");
      else if (i == 4)
        send_to_descriptor(d, "\nYour password can contain only letters and numbers.\n");
      else
      {
        strlcpy(d->acc->password, input, 32);
        send_to_descriptor(d, "\nPlease retype your password for confirmation. ");
        send_to_descriptor(d, password_on);
        d->state = STATE_CONFIRM_PASS;
        return;
      }
      send_to_descriptor(d, "\nWhat do you want your password to be? ");
      send_to_descriptor(d, password_on);
    break;

    case STATE_CONFIRM_PASS:
      send_to_descriptor(d, password_off);
      if (strcmp(d->acc->password, input))
      {
        send_to_descriptor(d, "\nYour passwords must match exactly.\nWhat do you want your password to be? ");
        d->state = STATE_NEW_PASS;
        d->acc->password[0] = 0;
        send_to_descriptor(d, password_on);
        return;
      }

      send_to_descriptor(d, "\nDo you want ANSI color? ");
      d->state = STATE_GET_ANSI;
    break;

    case STATE_GET_ANSI:
      d->acc->aflags = 0;
      if (input[0] == 'y' || input[0] == 'Y')
        SET_BIT(d->acc->aflags, AFLAG_ANSI);
      else if (input[0] == 'n' || input[0] == 'N')
        ;
      else
      {
        send_to_descriptor(d, "Please type yes or no.\nDo you want ANSI color? ");
        return;
      }

      for (dt = dhead; dt; dt = dt->next)
      {
        if (dt == d)
          continue;

        if (!stricmp(d->acc->name, dt->acc->name) && (dt->state > STATE_GET_PASS || dt->state < STATE_CONFIRM_NAME))
        {
          sckoutput(d->socket, "You have been kicked off.\n");
          wipe_descriptor(d);
          return;
        }
      }

      d->acc->logins = 1;
      d->acc->changes = time(NULL);
      strlcpy(d->acc->email, "Unset", 128);
      d->state = STATE_ACCT_MENU;
      log_time(d->acc->firsttime);
      save_address(d);
      show_account_menu(d, 1);
      save_account(d->acc);
    break;

    case STATE_ACCT_MENU:
      switch (input[0])
      {
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          i = atoi(input);
          if (i > d->acc->charcount)
          {
            send_to_descriptor(d, "Unknown option.\nWhat is your choice? ");
            return;
          }
          if (d->acc->status[i - 1] == CHSTATUS_DELETED)
          {
            send_to_descriptor(d, "You are unable to log onto that player.\nWhat is your choice? ");
            return;
          }

          {
            d->acc->ch = load_character(d->acc, d->acc->character[i - 1]);
            d->acc->ch->acc = d->acc;
            d->acc->ch->d = d;
            setup_char_events(d->acc->ch);
            d->state = STATE_PLAYING;
            d->acc->cur_char = i - 1;
            ++d->acc->chlogins[i - 1];
            destroy_d_events(d, EVENT_LOGINIDLE);

            if (d->acc->ch->level >= LEVEL_IMMORTAL)
              d->acc->status[i - 1] = CHSTATUS_IMMORTAL;

            if (!IS_SET(d->acc->ch->cflags, CFLAG_OLDPLAYER))
            {
              syslog("LOGIN", "%s (on %s@%s) is now playing for the first time!", d->acc->ch->name, d->acc->name, d->ip);
              login_msg_new(d->acc->ch);
              SET_BIT(d->acc->ch->cflags, CFLAG_OLDPLAYER);
              if (IS_SET(d->acc->ch->cflags, CFLAG_HARDCORE))
                d->acc->ch->plane = PLANE_HNEWBIE;
              else
                d->acc->ch->plane = PLANE_NEWBIE;
              d->acc->ch->maxhp = 1000;
              d->acc->ch->maxmove = 1000;
              d->acc->ch->maxmana = 1000;
              d->acc->ch->hp = d->acc->ch->maxhp;
              d->acc->ch->move = d->acc->ch->maxmove;
              d->acc->ch->mana = d->acc->ch->maxmana;
              d->acc->ch->level = LEVEL_MORTAL;
              d->acc->ch->sightradius = 5; /* pwipe: increase this to 50 */
              strlcpy(d->acc->ch->prompt, "#1[#2%pP#1] #1[#2%h#1/#2%HH %m#1/#2%MM %v#1/#2%VV#1]#n> ", 256);
              send_to_char(d->acc->ch, "\nWelcome to Undertow. This is a completely custom MUD. We recommend that you read #RHELP NEWBIE#n.\n");
            }
            else
            {
              syslog("LOGIN", "%s (on %s@%s) is now playing.", d->acc->ch->name, d->acc->name, d->ip);
              login_msg(d->acc->ch);
              do_look(d->acc->ch, "");
            }

            save_account(d->acc);
          }
        break;

        case 'r':
        case 'R':
          if (new_changes(d->acc) == 0)
          {
            send_to_descriptor(d, "There are no new changes.\nWhat is your choice? ");
            return;
          }
          show_changes(d->acc, -1);
          send_to_descriptor(d, "\n#nWhat is your choice? ");
        break;

        case 'c':
        case 'C':
          d->state = STATE_CONFIG_MENU;
          show_account_settings(d);
        break;

        case 's':
        case 'S':
          send_who(d);
          send_to_descriptor(d, "#nWhat is your choice? ");
        break;

        case 'n':
        case 'N':
          if (d->acc->charcount >= MAX_CHARS_PER_ACCOUNT)
          {
            send_to_descriptor(d, "You have met your maximum amount of characters for this account.\nWhat is your choice?");
            return;
          }

          d->state = STATE_NEW_CHAR;
          send_to_descriptor(d, "What do you want your name to be? ");
        break;

        case 'd':
        case 'D':
          if (d->acc->charcount == 0)
          {
            send_to_descriptor(d, "You have no characters to delete.\nWhat is your choice? ");
            return;
          }

          show_delete_menu(d);
          d->state = STATE_DELETE_CHAR;
        break;

        case 'q':
        case 'Q':
          save_account(d->acc);
          syslog("QUIT", "%s@%s quit at the login screen.", d->acc->name, d->ip);
          sckoutput(d->socket, "Goodbye.\n");

          wipe_descriptor(d);
        break;

        case '\0':
          show_account_menu(d, 1);
        break;

        default:
          send_to_descriptor(d, "Unknown option.\nWhat is your choice? ");
        break;
      }
    break;

    case STATE_CONFIG_MENU:
      switch (input[0])
      {
        case 'r':
        case 'R':
          d->state = STATE_ACCT_MENU;
          show_account_menu(d, 1);
        break;

        case 'a':
        case 'A':
          TOGGLE_BIT(d->acc->aflags, AFLAG_ANSI);
          if (IS_SET(d->acc->aflags, AFLAG_ANSI))
          {
            if (IS_SET(d->acc->aflags, AFLAG_ANSI_SPARSE))
              send_to_descriptor(d, "Your prompts will now be colored. If you want full color, turn Full ANSI Color on.\nWhat is your choice? ");
            else
              send_to_descriptor(d, "Welcome to the wonderful world of #Rc#Yo#Gl#Co#Mr#n!\nWhat is your choice? ");
          }
          else
            send_to_descriptor(d, "ANSI color turned off.\nWhat is your choice? ");
        break;

        case 'f':
        case 'F':
          TOGGLE_BIT(d->acc->aflags, AFLAG_ANSI_SPARSE);
          if (!IS_SET(d->acc->aflags, AFLAG_ANSI))
            send_to_descriptor(d, "You would probably notice a subsequent color level change if you had color on.\nWhat is your choice? ");
          else if (IS_SET(d->acc->aflags, AFLAG_ANSI_SPARSE))
            send_to_descriptor(d, "You will now only see colored prompts.\nWhat is your choice? ");
          else
            send_to_descriptor(d, "You will now see full color.\nWhat is your choice? ");
        break;

        case 'l':
        case 'L':
          TOGGLE_BIT(d->acc->aflags, AFLAG_REPLYLOCK);
          if (IS_SET(d->acc->aflags, AFLAG_REPLYLOCK))
            send_to_descriptor(d, "You will now reply only to the last person to whom you sent a tell.\nWhat is your choice? ");
          else
            send_to_descriptor(d, "You will now reply to the person who most recently sent you a tell.\nWhat is your choice? ");
        break;

        case 'p':
        case 'P':
          TOGGLE_BIT(d->acc->aflags, AFLAG_PUBLIC_EMAIL);
          if (IS_SET(d->acc->aflags, AFLAG_PUBLIC_EMAIL))
            send_to_descriptor(d, "Your email address is now public.\nWhat is your choice? ");
          else
            send_to_descriptor(d, "Your email address is now private.\nWhat is your choice? ");
        break;

        case 'c':
        case 'C':
          d->state = STATE_CHANGE_PASS1;
          send_to_descriptor(d, "What is your current password? ");
        send_to_descriptor(d, password_on);
        break;

        case 'e':
        case 'E':
          d->state = STATE_SET_EMAIL;
          send_to_descriptor(d, "What is your email address? ");
        break;

        case '\0':
          show_account_settings(d);
        break;

        case 'd':
        case 'D':
          SET_BIT(d->acc->aflags, AFLAG_ANSI);
          REMOVE_BIT(d->acc->aflags, AFLAG_ANSI_SPARSE);
          REMOVE_BIT(d->acc->aflags, AFLAG_PUBLIC_EMAIL);
          strlcpy(d->acc->email, "Unset", 128);
          send_to_descriptor(d, "Reverted to default settings.\nWhat is your choice?");
        break;

        default:
          send_to_descriptor(d, "Unknown option.\nWhat is your choice? ");
        break;
      }
    break;

    case STATE_CHANGE_PASS1:
      send_to_descriptor(d, password_off);
      if (input[0] == 0)
      {
        d->state = STATE_CONFIG_MENU;
        send_to_descriptor(d, "\nWhat is your choice? ");
        return;
      }

      if (strcmp(d->acc->password, input))
      {
        send_to_descriptor(d, "\nIncorrect password.\nWhat is your choice? ");
        d->state = STATE_CONFIG_MENU;
        return;
      }

      d->state = STATE_CHANGE_PASS2;
      d->acc->temp[0] = 0;
      send_to_descriptor(d, "\nWhat do you want your new password to be? ");
      send_to_descriptor(d, password_on);
    break;

    case STATE_CHANGE_PASS2:
      send_to_descriptor(d, password_off);
      if (input[0] == 0)
      {
        d->state = STATE_CONFIG_MENU;
        send_to_descriptor(d, "\nWhat is your choice? ");
        return;
      }

      i = check_string(input, 4, 12, 1);
      if (i == 1)
        send_to_descriptor(d, "\nYour password must have at least 4 characters.\n");
      else if (i == 2)
        send_to_descriptor(d, "\nYour password can contain at most 12 characters.\n");
      else if (i == 4)
        send_to_descriptor(d, "\nYour password can contain only letters and numbers.\n");
      else
      {
        strlcpy(d->acc->temp, input, 128);
        send_to_descriptor(d, "\nPlease retype your password for confirmation. ");
        d->state = STATE_CHANGE_PASS3;
        send_to_descriptor(d, password_on);
        return;
      }
      send_to_descriptor(d, "\nWhat do you want your password to be? ");
      send_to_descriptor(d, password_on);
    break;

    case STATE_CHANGE_PASS3:
      send_to_descriptor(d, password_off);
      if (input[0] == 0)
      {
        d->state = STATE_CONFIG_MENU;
        send_to_descriptor(d, "\nWhat is your choice? ");
        return;
      }

      if (strcmp(d->acc->temp, input))
      {
        send_to_descriptor(d, "\nPasswords must match exactly.\nWhat is your choice? ");
        d->state = STATE_CONFIG_MENU;
        return;
      }

      strlcpy(d->acc->password, input, 32);
      send_to_descriptor(d, "\nYour password is now changed.\nWhat is your choice? ");
      d->state = STATE_CONFIG_MENU;
      save_account(d->acc);
    break;

    case STATE_SET_EMAIL:
      i = check_string(input, -1, 47, 0);
      if (i == 2)
        send_to_descriptor(d, "Your email can contain at most 47 characters.\n");
      else if (strlen(input) == 0)
      {
        strlcpy(d->acc->email, "Unset", 128);
        d->state = STATE_CONFIG_MENU;
        send_to_descriptor(d, "Your email address is now unset.\nWhat is your choice? ");
      }
      else
      {
        replace(input, buf, "%", "", MAX_STRING_LENGTH);
        replace(buf, input, "~", "-", MAX_STRING_LENGTH);
        strlcpy(d->acc->email, input, 128);
        d->state = STATE_CONFIG_MENU;
        snprintf(buf, MAX_STRING_LENGTH, "Your email address is now %s.\nWhat is your choice? ", input);
        send_to_descriptor(d, buf);
        return;
      }
      send_to_descriptor(d, "What is your email address? ");
    break;

    case STATE_DELETE_CHAR:
      if (input[0] == 'r' || input[0] == 'R')
      {
        d->state = STATE_ACCT_MENU;
        show_account_menu(d, 1);
        return;
      }
      if (input[0] == 0)
      {
        show_delete_menu(d);
        return;
      }

      i = atoi(input);
      if (i < 1 || i > d->acc->charcount)
        send_to_descriptor(d, "Out of bounds.\nWhich character do you want to delete? ");
      else
      {
        d->acc->name[15] = --i;
        snprintf(buf, MAX_STRING_LENGTH, "Are you sure you want to delete %s?", d->acc->character[i]);
        send_to_descriptor(d, buf);
        d->state = STATE_CONFIRM_DEL;
      }
    break;

    case STATE_CONFIRM_DEL:
      if (input[0] == 'y' || input[0] == 'Y')
      {
        i = d->acc->name[15];
        d->acc->name[15] = 0;
        snprintf(buf, MAX_STRING_LENGTH, "%s has been deleted.\nWhat is your choice? ", d->acc->character[i]);
        send_to_descriptor(d, buf);
        syslog("DELETION", "%s (on %s@%s) has selfdeleted.", d->acc->character[i], d->acc->name, d->ip);
        d->state = STATE_ACCT_MENU;
        d->acc->chtime[i] = 0;
        snprintf(buf, MAX_STRING_LENGTH, "rm -f account/%s.chr", d->acc->character[i]);
        to_lower(buf);
        system(buf);

        d->acc->charcount--;
        while (i < d->acc->charcount)
        {
          strlcpy(d->acc->character[i], d->acc->character[i + 1], 32);
          i++;
        }
        save_account(d->acc);
        return;
      }
      d->state = STATE_ACCT_MENU;
      show_account_menu(d, 1);
    break;

    case STATE_NEW_CHAR:
      i = 0;
      if (input[0] == 0)
      {
        d->state = STATE_ACCT_MENU;
        show_account_menu(d, 1);
        return;
      }

      i = check_string(input, 4, 12, 0);
      if (i == 1)
        send_to_descriptor(d, "Your name must have atleast 4 letters.\n");
      else if (i == 2)
        send_to_descriptor(d, "Your name can contain at most 12 letters.\n");
      else if (i == 4 || i == 3)
        send_to_descriptor(d, "Your name can contain only letters.\n");
      else
      {
        input[0] = UPPER(input[0]);
        for (dt = dhead; dt; dt = dt->next)
          if ((d != dt) && !stricmp(input, dt->acc->character[dt->acc->charcount]))
            i = 1;
        if (i == 0 && char_exists(input))
          i = 1;
        if (i)
        {
          snprintf(buf, MAX_STRING_LENGTH, "The name %s is already taken.\nWhat do you want your name to be? ", input);
          send_to_descriptor(d, buf);
          return;
        }
        strlcpy(d->acc->character[d->acc->charcount], input, 32);
        snprintf(buf, MAX_STRING_LENGTH, "Are you sure you want the name %s? ", input);
        send_to_descriptor(d, buf);
        d->state = STATE_CONFIRM_CHAR;
        return;
      }
      send_to_descriptor(d, "What do you want your name to be? ");
    break;

    case STATE_CONFIRM_CHAR:
      if (input[0] == 'y' || input[0] == 'Y')
      {
        if (d->acc->logins == 1)
        {
          d->state = STATE_ACCT_MENU;
          finish_creation(d, 0);
          return;
        }
        d->state = STATE_GET_HARDCORE;
        send_to_descriptor(d, "Do you want this character to be hardcore (death = deletion)? ");
      }
      else
      {
        d->state = STATE_ACCT_MENU;
        show_account_menu(d, 1);
      }
    break;

    case STATE_GET_HARDCORE:
      finish_creation(d, input[0] == 'y' || input[0] == 'Y');
    break;
  }
}