/* 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 }
};