/* The Other Realm Account Code */ #include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include "include.h" #include "channel.h" extern const struct acnt_cmdfun_type acnt_cmdfun_table[]; extern std::list<Channel *> chanList; void account_gen(DESCRIPTOR_DATA *d, char *arg ) { ACCOUNT *pAcnt; char buf[MSL]; while(isspace(*arg)) arg++; if(d->account) pAcnt = d->account; switch(d->connected) { case CON_GET_ACCOUNT_NAME: if(!check_parse_name(arg) ) { write_to_buffer(d, "Illegal name. Try another.\n\r", 0 ); return; } if( ( pAcnt = load_account(d, arg ) ) == NULL ) { sprintf(buf, "{DWelcome to The Other Realm. The account by the name {r'{W%s{r'{D\r\n" "was not found. Would you like to create a new one?{r[{WY{D/{WN{r]{x\n\r", capitalize(arg) ); write_to_buffer(d, buf, 0 ); pAcnt = account_new(); pAcnt->name = str_dup(capitalize(arg) ); d->account = pAcnt; pAcnt->desc = d; d->connected = CON_CONFIRM_ACCOUNT_NAME; return; } write_to_buffer(d, "{DPlease enter your password\n\r{W-->", 0 ); d->connected = CON_CHECK_ACCOUNT_PASSWORD; return; case CON_CONFIRM_ACCOUNT_NAME: switch(UPPER(arg[0] ) ) { case 'Y': sprintf(buf, "{W%s{D it is! Welcome. Now, we require a password for your account\n\r{W-->{x", pAcnt->name ); write_to_buffer(d, buf, 0); d->connected = CON_GET_ACCOUNT_PASSWORD; break; case 'N': write_to_buffer(d, "{DOk then. What shall your name be?{x\n\r", 0); free_account(pAcnt); d->connected = CON_GET_ACCOUNT_NAME; break; default: write_to_buffer(d, "{DPlease choose either {WY{Des, or {WN{Do{x.\n\r",0); break; } break; case CON_GET_ACCOUNT_PASSWORD: if(arg[0] == '\0' ) { write_to_buffer(d, "{DWhat type of password is that!? Please choose another\n\r{W-->",0); return; } pAcnt->password = str_dup(arg); write_to_buffer(d, "{DPlease retype so that we can confirm your password.\n\r{W-->", 0 ); d->connected = CON_CONFIRM_ACCOUNT_PASSWORD; return; case CON_CONFIRM_ACCOUNT_PASSWORD: if(!strcmp(pAcnt->password, arg ) ) { write_to_buffer(d, "{DPassword confirmed.\n\r", 0); write_to_buffer(d, "From which MUD do you hail? (We just want the name of the mud, no url/ports please!)\n\r", 0); d->connected = CON_GET_MUD; return; } free_string(pAcnt->password); write_to_buffer(d, "{DPasswords did not match. What would you like your password to be?\n\r{W-->", 0 ); d->connected = CON_GET_ACCOUNT_PASSWORD; return; case CON_CHECK_ACCOUNT_PASSWORD: if(!strcmp(arg, pAcnt->password ) ) { if(check_reconnect(pAcnt) ) return; if(pAcnt->initLogin == 0) { write_to_buffer(d, "Welcome to MUD-Con V!\n\r",0); pAcnt->sendChanHelp(); } else { sprintf(buf, "{DWelcome back to MUD-Con V, {W%s{D.\n\r", pAcnt->name); write_to_buffer(d, buf, 0); } d->connected = CON_OOC_CHAT; infoChan("%s has entered the MUD-Con.", pAcnt->name); return; } write_to_buffer(d, "{DSorry, that password was incorrect.\n\r",0 ); close_socket(d); free_account(pAcnt); return; case CON_ACCOUNT_MENU: if(arg[0] == '\0' ) { send_accnt_menu(pAcnt); return; } switch (arg[0]) { case '1': write_to_buffer(d, "{DWelcome to The Other Realm Chat Room, for OOC chatter.\n\r",0); d->connected = CON_OOC_CHAT; infoChan("%s has entered the MUD-Con.", pAcnt->name); break; case '2': write_to_buffer(d, "The Forums havn't been written!\n\r", 0 ); return; default: send_accnt_menu(pAcnt); break; } break; case CON_ASK_RECONNECT: switch(UPPER(arg[0]) ) { case 'Y': reconnect_account(pAcnt); d->connected = CON_OOC_CHAT; infoChan("%s has re-entered the MUD-Con.", pAcnt->name); break; case 'N': free_account(pAcnt); d->account = NULL; d->connected = CON_GET_ACCOUNT_NAME; write_to_buffer(d, "Ok then! What name shall you use?\n\r",0); break; default: ptc(pAcnt, "Yes, or no?\n\r"); break; } break; case CON_GET_MUD: if(arg[0] == '\0' ) { write_to_buffer(d, "What kind of mud name is that!?\n\r",0); break; } free_string(pAcnt->mud); pAcnt->mud = str_dup(arg); write_to_buffer(d, "What is the URL for this MUD? (You can include a port)\n\r",0); d->connected = CON_GET_URL; break; case CON_GET_URL: if(arg[0] == '\0' ) { write_to_buffer(d, "What kind of URL is that?\n\r",0); break; } free_string(pAcnt->url); pAcnt->url = str_dup(arg); write_to_buffer(d, "All your information are belong to us. Thanks for coming by MudCon! Please converse... NOW!\n\r",0); addAttendant(pAcnt); d->connected = CON_OOC_CHAT; infoChan("%s has entered the MUD-Con.", pAcnt->name); pAcnt->sendChanHelp(); break; default: write_to_buffer(d, "You suck\n\r",0); break; } return; } void send_accnt_menu(ACCOUNT *pAcnt ) { write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* * * * * * * * * * * * * * * * * * * * * * * * * * *\n\r",0 ); write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* *{W Other Realm Account Menu {D* *\n\r",0 ); write_to_buffer(pAcnt->desc, "{D*{r*{D*{W Please choose one of the Following Options {D*{r*{D*\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* ************************************************* *\n\r",0 ); write_to_buffer(pAcnt->desc, "{D*{r*{D* * * * * * * * * * * * * * * * * * * * * * * * *{r*{D*\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* ************************************************* *\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* {r({D1{r){w Log into Chat {r({D2{r){w Check MUD-Forum {D*\n\r",0 ); write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); write_to_buffer(pAcnt->desc, "{D* * * * * * * * * * * * * * * * * * * * * * * * * * *\n\r",0 ); write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); write_to_buffer(pAcnt->desc, "{D\n\rPlease choose an option\n\r{W-->", 0 ); return; } void interp_acnt_cmd(ACCOUNT *pAcnt, char *argument ) { ACNT_CMD *pCmd; char cmd[MSL]; char *orig; Channel *chan; orig = str_dup(argument); while(isspace(*argument)) argument++; if(argument[0] == '\0' ) return; argument = one_argument(argument,cmd); if( (chan = Channel::find(cmd) ) ) { chan->interpret(pAcnt, argument); return; } for(pCmd = acnt_cmd_list ; pCmd ; pCmd = pCmd->next ) { if (LOWER(cmd[0]) == LOWER(pCmd->name[0]) && !str_prefix( cmd,pCmd->name)) { if(pCmd->level > pAcnt->level ) break; ( *pCmd->do_fun ) (pAcnt, argument ); return; } } logfp(LOG_CMD, "%s:%s", pAcnt->name, orig); if(pAcnt->lastfun) { (*pAcnt->lastfun) (pAcnt, orig); free_string(orig); return; } free_string(orig); write_to_buffer(pAcnt->desc, "That isn't a valid command.\n\r",0 ); return; } void load_accnt_cmds() { FILE *fp; ACNT_CMD *pCmd; char *word; char buf[MSL]; sprintf(buf, "%s%s%s", DATA_DIR, CMD_DIR, ACNT_CMD_FILE ); if( ( fp = fopen(buf, "r") ) == NULL ) { perror(buf); return; } for(word = fread_word(fp); strcasecmp(word, END_CHAR); word = fread_word(fp) ) { if(!strcasecmp(word, "name" ) ) { pCmd = acnt_cmd_new(); if(!acnt_cmd_list) acnt_cmd_list = pCmd; if(acnt_cmd_last) acnt_cmd_last->next = pCmd; acnt_cmd_last = pCmd; SREAD(pCmd->name); continue; } if(!strcasecmp(word, "dofun" ) ) { if( (pCmd->do_fun = acntdofun_lookup(fread_string(fp)) ) == NULL ) //When I get a logging function. Gotta be added here. { logfp(LOG_BUG, "CmdFun not found: %s", word); break; } continue; } IREAD("Lvl", pCmd->level ); //Another logging function here to state that something wasn't valid. } fclose(fp); return; } AC_CMD * acntdofun_lookup( const char *name ) { int cmd; for( cmd = 0; acnt_cmdfun_table[cmd].name != NULL; cmd++ ) { if(LOWER(name[0]) == LOWER(acnt_cmdfun_table[cmd].name[0]) && !str_prefix(name, acnt_cmdfun_table[cmd].name ) ) return acnt_cmdfun_table[cmd].do_fun; } return NULL; } void save_account(ACCOUNT *pAcnt ) { FILE *fp; char buf[MSL]; sprintf(buf, "%s%s", ACCOUNT_DIR, pAcnt->name ); if( ( fp = fopen(buf, "w" ) ) == NULL ) { logfp(LOG_BUG, "SAVE_ACCOUNT: Failed on Fopen, %s\n", pAcnt->name ); return; } fprintf(fp, "Name %s~\n", pAcnt->name ); fprintf(fp, "Pswd %s~\n", pAcnt->password ); fprintf(fp, "Lvl %d\n", pAcnt->level ); fprintf(fp, "CmnF " ); save_flags(common_table, fp, COMMON_MAX, pAcnt->common_flags ); fprintf(fp, "ChnF " ); save_flags(channel_table, fp, CHANNEL_MAX, pAcnt->channel ); if(IS_SET(pAcnt->common_flags, COMMON_AFK ) ) fprintf(fp, "AfkS %s~\n", pAcnt->afk_string ); fprintf(fp, "Read %s~\n", pAcnt->read ); fprintf(fp, "Mud %s~\n", pAcnt->mud ); fprintf(fp, "Url %s~\n", pAcnt->url ); fprintf(fp, "CPst %s~\n", pAcnt->custPost); fprintf(fp, "CTpc %s~\n", pAcnt->custTopic); fprintf(fp, "CRpl %s~\n", pAcnt->custReply); fprintf(fp, "MMade 1\n"); std::list<Topic *>::iterator i; std::list<Channel *>::iterator ch; for(ch = chanList.begin(); ch != chanList.end() ; ++ch) { if( pAcnt->ignore[(*ch)->bit].size() <= 0) continue; for( i = pAcnt->ignore[(*ch)->bit].begin() ; i != pAcnt->ignore[(*ch)->bit].end() ;++i) fprintf(fp, "Ign %d %s\n\r", (*i)->id, (*ch)->name); } fprintf(fp, "%s\n", END_CHAR ); fclose(fp); return; } ACCOUNT *load_account(DESCRIPTOR_DATA *d, char *name) { FILE *fp; char buf[MSL]; char *word; ACCOUNT *pAcnt; sprintf(buf, "%s%s", ACCOUNT_DIR, capitalize(name) ); if( ( fp = fopen(buf, "r" ) ) == NULL ) return NULL; pAcnt = account_new(); for(word = fread_word(fp); strcmp(word, END_CHAR); word = fread_word(fp) ) { if(!strcasecmp(word, "Name" ) ) { SREAD(pAcnt->name); continue; } if(!strcasecmp(word, "Pswd" ) ) { SREAD(pAcnt->password); continue; } if(!strcasecmp(word, "Read") ) { SREAD(pAcnt->read); continue; } if(!strcasecmp(word, "CmnF" ) ) { load_flags(common_table, fp, COMMON_MAX, pAcnt->common_flags ); continue; } if(!strcasecmp(word, "ChnF" ) ) { load_flags(channel_table, fp, CHANNEL_MAX, pAcnt->channel ); continue; } if(!strcasecmp(word, "CPst" ) ) { SREAD(pAcnt->custPost); continue; } if(!strcasecmp(word, "CTpc" ) ) { SREAD(pAcnt->custTopic); continue; } if(!strcasecmp(word, "CRpl" ) ) { SREAD(pAcnt->custReply); continue; } if(!strcasecmp(word, "AfkS" ) ) { SREAD(pAcnt->afk_string ); continue; } if(!strcasecmp(word, "Url" ) ) { SREAD(pAcnt->url); continue; } if(!strcasecmp(word, "Mud" ) ) { SREAD(pAcnt->mud); continue; } if(!strcasecmp(word, "Ign") ) { int tid = fread_number(fp); char *chan = fread_word(fp); Channel *channel; Topic *topic; if( !(channel = Channel::find(chan) ) ) { logfp(LOG_BUG, "Shits gone wrong! No Channel in Account::Load(%s)",chan); continue; } if( !( topic = channel->getTopic(tid) ) ) { logfp(LOG_BUG, "No topic %d", tid); continue; } pAcnt->addIgnore(topic, channel->bit); continue; } IREAD("MMade", pAcnt->initLogin); IREAD("lvl", pAcnt->level ); logfp(LOG_BUG, "Unexpected reference in Account file %s: %s\n",name, word ); continue; } d->account = pAcnt; pAcnt->desc = d; return pAcnt; } ACCOUNT * get_account( const char *name ) { ACCOUNT *pAcnt; for(pAcnt = account_list; pAcnt ; pAcnt = pAcnt->next ) { if(LOWER(pAcnt->name[0]) == LOWER(name[0]) && !str_prefix(name, pAcnt->name ) ) return pAcnt; } return NULL; } bool check_reconnect(ACCOUNT *pAcnt ) { ACCOUNT *acnt; for(acnt = account_list ; acnt ; acnt = acnt->next ) { if(acnt == pAcnt) continue; if(LOWER(acnt->name[0]) == LOWER(pAcnt->name[0]) && !strcasecmp(acnt->name, pAcnt->name ) ) { pAcnt->desc->connected = CON_ASK_RECONNECT; ptc(pAcnt, "You are already logged in. Would you like to reconnect?[y/n]\n\r" ); return true; } } return false; } void reconnect_account(ACCOUNT *pAcnt ) { ACCOUNT *acnt; bool found = false; for(acnt = account_list ; acnt ; acnt = acnt->next ) { if(acnt == pAcnt) continue; if(LOWER(acnt->name[0]) == LOWER(pAcnt->name[0]) && !strcasecmp(acnt->name, pAcnt->name ) ) { found = true; break; } } if(found) { ptc(acnt, "You have reconnected somewhere else... Bye!\n\r"); close_socket(acnt->desc); free_account(acnt); } pAcnt->desc->connected = CON_OOC_CHAT; ptc(pAcnt, "You have reconnected. Welcome back!\n\r"); return; } const struct acnt_cmdfun_type acnt_cmdfun_table[] = { { "acnt_who", acnt_who }, { "acnt_chat", acnt_chat }, { "acnt_save", acnt_save }, { "acnt_quit", acnt_quit }, { "acnt_typo", acnt_typo }, { "acnt_copyover", acnt_copyover }, { "acnt_command", acnt_command }, { "acnt_afk", acnt_afk }, { "acnt_advance", acnt_advance }, { "acnt_socket", acnt_socket }, { "acnt_filecount", acnt_filecount}, { "acnt_channels", acnt_channels }, { "acnt_ignore", acnt_ignore }, { "acnt_ban", acnt_ban }, { "acnt_view", acnt_view }, { "acnt_customize", acnt_customize }, { "acnt_help", acnt_help }, { "acnt_credits", acnt_credits }, { "acnt_ignore", acnt_ignore }, { "acnt_reply", acnt_reply }, { "acnt_tell", acnt_tell }, { NULL, NULL } };