/* Do not remove the headers from this file! see /USAGE for more info. */
#include <config.h>
#include <daemons.h>
#include <security.h>
string query_userid();
void save_me();
void remove();
void initialize_user();
void report_login_failures();
void modal_simple(function input_func, mixed prompt, int secure,int lock);
varargs void modal_push(function input_func,
mixed prompt,
int secure,
function return_to_func);
void modal_pop();
void set_privilege(mixed priv); // from M_ACCESS
mixed unguarded(mixed priv, function fp);
void start_shell();
void run_login_script();
int query_n_gen();
/*
** The file name for the body object
*/
private string body_fname;
private string format;
/*
** The body object once it has been instantiated
*/
nosave private object body;
nomask string query_body_fname()
{
return body_fname;
}
nomask object query_body()
{
return body;
}
//### temp hack for upgrading link files. see restore_me()
protected nomask void set_body_fname(string new_body_fname)
{
body_fname = new_body_fname;
}
private void load_mailer()
{
object mailbox;
int idx;
mailbox = MAILBOX_D->get_mailbox(query_userid());
idx = mailbox->first_unread_message();
if ( idx == -1 )
{
mailbox->set_message_index(mailbox->query_message_count() - 1);
}
else
{
mailbox->set_message_index(idx);
write("\n>>You have new mail<<\n");
}
}
varargs nomask void switch_body(string new_body_fname, int permanent)
{
object where;
object old_body;
if(previous_object() != body && this_body() != body)
error("security violation: bad body switch attempt\n");
where = body ? environment(body) : (mixed)VOID_ROOM;
if(permanent && new_body_fname)
{
body_fname = new_body_fname;
save_me();
}
if(!new_body_fname)
new_body_fname = body_fname;
old_body = body;
body = new(new_body_fname, query_userid());
master()->refresh_parse_info();
if(old_body)
{
old_body->move(VOID_ROOM);
if(old_body)
catch(destruct(old_body));
}
load_mailer();
report_login_failures();
/* NOTE: we are keeping the same shell for now... */
body->su_enter_game(where);
}
/*
** Functions to get the body set up and the user into the game.
*/
private nomask void incarnate(int is_new, string bfn)
{
if(bfn)
body_fname = bfn;
body = new(body_fname, query_userid());
master()->refresh_parse_info();
LAST_LOGIN_D->register_last(query_userid(), query_ip_name(this_object()));
if(query_n_gen() != -1)
body->set_gender(query_n_gen());
save_me();
start_shell();
body->enter_game(is_new);
run_login_script();
if(is_new)
{
#ifdef USE_STATS
this_body()->init_stats();
#endif
body->save_me();
/* This seems to me to be a poor place to put this, but fits with
* the default login/new user creation sequence. -- Tigran */
initialize_user();
}
}
void sw_body_handle_existing_logon(int);
private nomask void rcv_try_to_boot(object who, string answer)
{
answer = lower_case(answer);
if( answer == "yes" || answer == "y" )
{
/* Check this again, in case the user quits after the question is asked
* but before this point. If 'who' exists, give them a message and steal
* the body, otherwise not. */
if(who)
{
who->receive_private_msg("You are taken over by yourself, or something.\n");
body=who->query_body();
who->steal_body();
start_shell();
body->reconnect(this_object());
return;
}
sw_body_handle_existing_logon(0);
return;
}
if(answer == "n" || answer == "no")
{
if(wizardp(query_userid()))
{
sw_body_handle_existing_logon(1);
return;
}
write("Try another time then.\n");
destruct(this_object());
}
write("please type 'y' or 'n' >");
modal_simple((: rcv_try_to_boot, who :),0,0,1);
}
protected nomask void sw_body_handle_existing_logon(int enter_now)
{
remove_call_out(); /* all call outs */
if(!enter_now)
{
/*
** Okay... an existing user is ready for their body. Look for other
** users currently connected with this userid. Those other usersmay
** be interactive or link-dead. Do the right thing...
*/
object array users;
string array ids;
int idx;
object the_user;
/* adjust the privilege of the user ob */
if(adminp(query_userid()))
set_privilege(1);
else
set_privilege(query_userid());
/* check for link-deadedness */
users = children(USER_OB) - ({ this_object() });
ids = users->query_userid();
if((idx = member_array(query_userid(), ids)) != -1)
{
if(!interactive(the_user = users[idx]))
{
if(body = the_user->query_body())
{
master()->refresh_parse_info();
the_user->steal_body();
start_shell();
body->reconnect(this_object());
return;
}
}
else
{
write("\nYou are already logged in!\nThrow yourself off? ");
modal_simple((: rcv_try_to_boot, the_user :),0,0,1);
return;
}
}
}
load_mailer();
write("\n"+read_file(MOTD_FILE));
report_login_failures();
BIRTHDAY_D->report();
incarnate(0, 0);
}
/* when a user reconnects, this is used to steal the body back */
nomask void steal_body()
{
/* only USER_OB can steal the body. */
if(base_name(previous_object()) != USER_OB )
error("illegal attempt to steal a body\n");
body = 0;
remove();
}
#ifdef USE_RACES
void got_entry(function when_done, string line)
{
mapping races = RACE_D->query_race_data();
if(line == "list")
{
write("Please select a race from the following list:\n");
printf(format, implode(keys(races), "\n"));
return;
}
if(races[line])
{
modal_pop();
evaluate(when_done, races[line]);
return;
}
if(sscanf(line, "help %s", line) && races[line])
{
write(races[line]->short_description());
return;
}
write("No such race.\n");
}
#endif /* USE_RACES */
void create_body()
{
#ifndef USE_RACES
incarnate(1, DIR_RACES "/human");
#else
string array races = RACE_D->query_races();
function when_done = (: incarnate, 1 :);
int width = 0;
if(sizeof(races) == 1)
{
string default_race = races[0];
write("You will be a " + default_race + ".\n");
incarnate(1, DIR_RACES + "/" + default_race);
}
else
{
foreach(string name in races)
{
if(strlen(name) > width)
width = strlen(name);
}
format = "%#-75." + (75 / (width + 3)) + "s\n\n";
write("\nPlease select a race from the following list:\n");
printf(format, implode(races, "\n"));
write("Type 'help race' for a brief description. Type 'list' to show the choices again.\n");
modal_push((: got_entry, when_done :), "Race? ");
}
#endif /* USE_RACES */
}
/*
** A new character has been created and all inputs have been entered.
** Do a bit of additional work and go for a body.
*/
protected nomask void sw_body_handle_new_logon()
{
remove_call_out(); /* all call outs */
#ifdef AUTO_WIZ
/* auto-wiz everybody as they are created */
write(">>>>> You've been granted automatic guest wizard status. <<<<<\n");
unguarded(1, (: SECURE_D->create_wizard($(query_userid())) :));
#endif
/* auto-admin the first wizard if there are no admins */
{
string *members = SECURE_D->query_domain_members("admin");
if(!sizeof(members))
{
if(!wizardp(query_userid())) unguarded(1,
(: SECURE_D->create_wizard($(query_userid())) :));
write( ">>>>> You have been made admin. Remember to use admtool. <<<<<\n");
unguarded(1, (: SECURE_D->add_domain_member("admin",
$(query_userid()), 1) :));
}
}
/* adjust the privilege of the user ob */
if(adminp(query_userid()))
set_privilege(1);
else
set_privilege(query_userid());
// pass a lfun pointer so that we don't have to worry about validating
// the call.
create_body();
}