/* mguests.c - multiguest code originally ported from DarkZone */ /* $Id: mguests.c,v 1.18 2002/09/28 10:58:09 rmg Exp $ */ #include "autoconf.h" #include "copyright.h" #include "config.h" #include "alloc.h" /* required by mudconf */ #include "flags.h" /* required by mudconf */ #include "htab.h" /* required by mudconf */ #include "mudconf.h" /* required by code */ #include "db.h" /* required by externs */ #include "externs.h" /* required by interface */ #include "interface.h" /* required by code */ #include "attrs.h" /* required by code */ #include "powers.h" /* required by code */ extern void FDECL(do_lock, (dbref, dbref, int, char *, char *)); typedef int object_flag_type; dbref create_guest(num) int num; { dbref player, aowner; int found, same_str, aflags; char name[LBUF_SIZE * 2]; char base[PLAYER_NAME_LIMIT * 2]; char prefixes[LBUF_SIZE], suffixes[LBUF_SIZE], *pp, *sp, *tokp, *toks; if (!Wizard(mudconf.guest_nuker) || !Good_obj(mudconf.guest_nuker)) mudconf.guest_nuker = GOD; /* If basename only is provided, guests are named <basename><number>. * if guest_prefixes and/or guest_suffixes is provided, names will * be generated using a sequential combination of the two lists, * and the guests created will get an alias of <basename><number>. * If we run out of possible name combinations before we run into * the max number of guests, we start calling guests <basename><number>. * If we generate a name longer than the limit, we also fall back on * the basename scheme. */ found = 0; if (*mudconf.guest_prefixes && *mudconf.guest_suffixes) { strcpy(prefixes, mudconf.guest_prefixes); for (pp = strtok_r(prefixes, " \t", &tokp); pp && !found; pp = strtok_r(NULL, " \t", &tokp)) { strcpy(suffixes, mudconf.guest_suffixes); for (sp = strtok_r(suffixes, " \t", &toks); sp && !found; sp = strtok_r(NULL, " \t", &toks)) { sprintf(name, "%s%s", pp, sp); if (lookup_player(GOD, name, 0) == NOTHING) found = 1; } } } else if (*mudconf.guest_prefixes || *mudconf.guest_suffixes) { strcpy(prefixes, (*mudconf.guest_prefixes ? mudconf.guest_prefixes : mudconf.guest_suffixes)); for (pp = strtok_r(prefixes, " \t", &tokp); pp && !found; pp = strtok_r(NULL, " \t", &tokp)) { if (lookup_player(GOD, pp, 0) == NOTHING) { strcpy(name, pp); found = 1; } } } sprintf(base, "%s%d", mudconf.guest_basename, num + 1); same_str = 1; if (!found || (strlen(name) >= PLAYER_NAME_LIMIT)) { strcpy(name, base); } else if (strcasecmp(name, base)) { if (!badname_check(base) || !ok_player_name(base) || (lookup_player(GOD, base, 0) != NOTHING)) { STARTLOG(LOG_SECURITY | LOG_PCREATES, "CON", "BAD") log_printf("Guest connect failed in alias check: %s", base); ENDLOG return NOTHING; } same_str = 0; } /* Make the player. */ player = create_player(name, mudconf.guest_password, mudconf.guest_nuker, 0, 1); if (player == NOTHING) { STARTLOG(LOG_SECURITY | LOG_PCREATES, "CON", "BAD") log_printf("Guest connect failed in create_player: %s", name); ENDLOG return NOTHING; } /* Add an alias for the basename. */ if (!same_str) { atr_pget_info(player, A_ALIAS, &aowner, &aflags); atr_add(player, A_ALIAS, base, player, aflags); add_player_name(player, base); } /* Turn the player into a guest. */ s_Guest(player); move_object(player, (Good_loc(mudconf.guest_start_room) ? mudconf.guest_start_room : (Good_loc(mudconf.start_room) ? mudconf.start_room : 0))); s_Flags(player, (Flags(mudconf.guest_char) & ~TYPE_MASK & ~mudconf.stripped_flags.word1) | TYPE_PLAYER); s_Flags2(player, Flags2(mudconf.guest_char) & ~mudconf.stripped_flags.word2); s_Flags3(player, Flags3(mudconf.guest_char) & ~mudconf.stripped_flags.word3); s_Pennies(player, Pennies(mudconf.guest_char)); s_Zone(player, Zone(mudconf.guest_char)); s_Parent(player, Parent(mudconf.guest_char)); /* Make sure the guest is locked. */ do_lock(player, player, A_LOCK, tprintf("#%d", player), "me"); do_lock(player, player, A_LENTER, tprintf("#%d", player), "me"); do_lock(player, player, A_LUSE, tprintf("#%d", player), "me"); /* Copy all attributes. */ atr_cpy(GOD, player, mudconf.guest_char); return player; } void destroy_guest(guest) dbref guest; { if (!Wizard(mudconf.guest_nuker) || !Good_obj(mudconf.guest_nuker)) mudconf.guest_nuker = GOD; if (!Guest(guest)) return; atr_add_raw(guest, A_DESTROYER, tprintf("%d", mudconf.guest_nuker)); destroy_player(guest); destroy_obj(mudconf.guest_nuker, guest); } char *make_guest(d) DESC *d; { int i; dbref guest; char name[SBUF_SIZE]; /* Nuke extra guests. */ for (i = 0; i < mudconf.number_guests; i++) { sprintf(name, "%s%d", mudconf.guest_basename, i + 1); guest = lookup_player(GOD, name, 0); if ((guest != NOTHING) && !Connected(guest)) destroy_guest(guest); } /* Find the first free guest ID. */ for (i = 0; i < mudconf.number_guests; i++) { sprintf(name, "%s%d", mudconf.guest_basename, i + 1); if (lookup_player(GOD, name, 0) == NOTHING) break; } if (i == mudconf.number_guests) { queue_string(d, "GAME: All guests are currently in use. Please try again later.\n"); return NULL; } if ((guest = create_guest(i)) == NOTHING) { queue_string(d, "GAME: Error creating guest ID, please try again later.\n"); STARTLOG(LOG_SECURITY | LOG_PCREATES, "CON", "BAD") log_printf("Error creating guest ID. '%s' already exists.\n", name); ENDLOG return NULL; } return Name(guest); }