lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* 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();
}