HS_DBREF CHSInterface::LookupPlayer(const HS_INT8 * pcName) { #ifdef PENNMUSH // No change in code between versions return lookup_player(pcName); #endif #if defined(TM3) || defined(MUX) return lookup_player(GOD, (char *) pcName, 0); #endif return HSNOTHING; }
void do_newpassword(dbref player, const char *name, const char *password) { dbref victim; char buf[BUFFER_LEN]; if (!Wizard(player) || Typeof(player) != TYPE_PLAYER) { notify(player, "Only a Wizard player can newpassword someone."); return; } else if ((victim = lookup_player(name)) == NOTHING) { notify(player, "No such player."); } else if (*password != '\0' && !ok_password(password)) { /* Wiz can set null passwords, but not bad passwords */ notify(player, "Bad password"); #ifdef GOD_PRIV } else if (God(victim)) { notify(player, "You can't change God's password!"); return; } else { if (TrueWizard(victim) && !God(player)) { notify(player, "Only God can change a wizard's password."); return; } #else /* GOD_PRIV */ } else {
/* doesn't really belong here, but I couldn't figure out where else */ void do_page(dbref player, const char *arg1, const char *arg2) { char buf[BUFFER_LEN]; dbref target; if (!payfor(player, tp_lookup_cost)) { notify_fmt(player, "You don't have enough %s.", tp_pennies); return; } if ((target = lookup_player(arg1)) == NOTHING) { notify(player, "I don't recognize that name."); return; } if (FLAGS(target) & HAVEN) { notify(player, "That player does not wish to be disturbed."); return; } if (blank(arg2)) snprintf(buf, sizeof(buf), "You sense that %s is looking for you in %s.", NAME(player), NAME(DBFETCH(player)->location)); else snprintf(buf, sizeof(buf), "%s pages from %s: \"%s\"", NAME(player), NAME(DBFETCH(player)->location), arg2); if (notify_from(player, target, buf)) notify(player, "Your message has been sent."); else { snprintf(buf, sizeof(buf), "%s is not connected.", NAME(target)); notify(player, buf); } }
/* doesn't really belong here, but I couldn't figure out where else */ void do_page(dbref player, const char *arg1, const char *arg2) { int ignored; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; dbref target; if (!payfor(player, tp_lookup_cost)) { anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies); return; } if ( strcmp(arg1, "me") ) { if ((target = lookup_player(arg1)) == NOTHING) { anotify(player, CINFO WHO_MESG); return; } } else target = player; if(Guest(player)) { if(!Mage(target)) { anotify(player, CINFO "Guests can only page " NAMEWIZ "s, type 'wizzes'."); return; } } if (FLAGS(target) & HAVEN) { anotify(player, CFAIL "That player is haven."); return; } ignored = ignoring(target, player); if(ignored == 1) { anotify(player, CFAIL "That player is ignoring you."); return; } else if(ignored == 2) { anotify(player, CINFO "That player is ignoring you."); } do_parse_mesg(player, player, arg2, "(page)", buf, MPI_ISPRIVATE); tct(buf,buf2); if (!*buf2) { sprintf(buf, CGREEN "You sense that %s is looking for you in %s.", PNAME(player), NAME(DBFETCH(player)->location)); } else { if(buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, CGREEN "%s pages \"" CYELLOW "%s %.3900s" CGREEN "\"", PNAME(player), PNAME(player), buf2); } else { sprintf(buf, CGREEN "%s pages \"" CYELLOW "%.3900s" CGREEN "\"", PNAME(player), buf2); } } if (anotify_from(player, target, buf)) anotify(player, CSUCC "Your message has been sent."); else { sprintf(buf, CINFO "%s is not connected.", PNAME(target)); anotify(player, buf); } }
/** Is a name a valid player name when applied by player to thing? * Player names must be valid object names, but also not forbidden (unless * the player is a wizard). They are * subject to a different length limit, and subject to more stringent * restrictions on valid characters. Finally, it can't be the same as * an existing player name or alias unless it's one of theirs. * \param name name to check. * \param player player for permission checks. * \param thing player who will get the name. * \retval 1 name is valid for players. * \retval 0 name is not valid for players. */ int ok_player_name(const char *name, dbref player, dbref thing) { const char *scan, *good; dbref lookup; if (!ok_name(name, 0) || strlen(name) > (size_t) PLAYER_NAME_LIMIT) return 0; good = (PLAYER_NAME_SPACES || Wizard(player) ? " `$_-.,'" : "`$_-.,'"); /* Make sure that the name contains legal characters only */ for (scan = name; scan && *scan; scan++) { if (isalnum(*scan)) continue; if (!strchr(good, *scan)) return 0; } lookup = lookup_player(name); /* A player may only change to a forbidden name if they're already using that name. */ if (forbidden_name(name)) { if (!((GoodObject(player) && Wizard(player)) || (GoodObject(thing) && lookup == thing))) { return 0; } } return ((lookup == NOTHING) || (lookup == thing)); }
/** Attempt to create a new player object. * \param d DESC the creation attempt is being made on (if from connect screen) * \param executor dbref of the object attempting to create a player (if * \@pcreate) * \param name name of player to create. * \param password initial password of created player. * \param host host from which creation is attempted. * \param ip ip address from which creation is attempted. * \return dbref of created player, NOTHING if invalid name, AMBIGUOUS if taken * name, or HOME for a bad password * password. */ dbref create_player(DESC *d, dbref executor, const char *name, const char *password, const char *host, const char *ip) { if (!ok_player_name(name, executor, NOTHING)) { do_log(LT_CONN, 0, 0, "Failed creation (bad name) from %s", host); if (d) { queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "create: bad name", name); } return (lookup_player(name) == NOTHING ? NOTHING : AMBIGUOUS); } if (!ok_password(password)) { do_log(LT_CONN, 0, 0, "Failed creation (bad password) from %s", host); if (d) { queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "create: bad password", name); } return HOME; } if (DBTOP_MAX && (db_top >= DBTOP_MAX + 1) && (first_free == NOTHING)) { /* Oops, out of db space! */ do_log(LT_CONN, 0, 0, "Failed creation (no db space) from %s", host); if (d) { queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "create: no db space left to create!", name); } return NOTHING; } /* else he doesn't already exist, create him */ return make_player(name, password, host, ip); }
int ok_player_name(const char *name) { const char *scan; if (!ok_name(name) || strlen(name) > PLAYER_NAME_LIMIT) return 0; for (scan = name; *scan; scan++) { if (!(isprint(*scan) && !isspace(*scan)) && *scan != '(' && *scan != ')' && *scan != '\'' && *scan != ',') { /* was isgraph(*scan) */ return 0; } } /* Check the name isn't reserved */ if (*tp_reserved_player_names && equalstr((char*)tp_reserved_player_names, (char*)name)) return 0; /* lookup name to avoid conflicts */ return (lookup_player(name) == NOTHING); }
void match_player(void) { if (md.confidence >= CON_DBREF) { return; } if (Good_obj(md.absolute_form) && isPlayer(md.absolute_form)) { promote_match(md.absolute_form, CON_DBREF); return; } if (*md.string == LOOKUP_TOKEN) { UTF8 *p; for (p = md.string + 1; mux_isspace(*p); p++) { ; // Nothing. } dbref match = lookup_player(NOTHING, p, true); if (Good_obj(match)) { promote_match(match, CON_TOKEN); } } }
char *make_guest(DESC * d) { int i; dbref player, p2; static char name[50]; /* * Nuke extra guests as new guests connect. */ for(i = 0; i < mudconf.number_guests; i++) { sprintf(name, "%s%d", mudconf.guest_prefix, i + 1); p2 = lookup_player(GOD, name, 0); if(p2 != NOTHING && !Connected(p2)) destroy_guest(p2); } /* * Locate a free guest ID, and eat it. */ for(i = 0; i < mudconf.number_guests; i++) { sprintf(name, "%s%d", mudconf.guest_prefix, i + 1); player = lookup_player(GOD, name, 0); if(player == NOTHING) break; } if(i == mudconf.number_guests) { queue_string(d, "GAME: All guest ID's are busy, please try again later.\n"); return NULL; } sprintf(name, "%s%d", mudconf.guest_prefix, i + 1); player = create_guest(name, mudconf.guest_prefix); if(player == NOTHING) { queue_string(d, "GAME: Error creating guest ID, please try again later.\n"); log_text(tprintf ("GUEST: Error creating guest ID. '%s' already exists.\n", name)); return NULL; } return Name(player); }
/* doesn't really belong here, but I couldn't figure out where else */ void do_page(int descr, dbref player, const char *arg1, const char *arg2) { char buf[BUFFER_LEN], buf2[BUFFER_LEN]; dbref target; if (!payfor(player, tp_lookup_cost)) { anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies); return; } if (strcmp(arg1, "me")) { if ((target = lookup_player(arg1)) == NOTHING) { anotify_nolisten2(player, CINFO "Who?"); return; } } else target = player; if (Guest(player)) { if (!Mage(target)) { anotify_nolisten2(player, CINFO "Guests can only page wizards, type 'wizzes'."); return; } } if (FLAGS(target) & HAVEN) { anotify_nolisten2(player, CFAIL "That player is haven."); return; } if (Meeper(OWNER(player))) { do_parse_mesg(descr, player, player, arg2, "(page)", buf, MPI_ISPRIVATE); tct(buf, buf2); } else { tct(arg2, buf2); } if (!*buf2) { sprintf(buf, CSUCC "You sense that %s is looking for you in %s.", PNAME(player), NAME(DBFETCH(player)->location)); } else { if (buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, SYSGREEN "%s pages \"" SYSYELLOW "%s %s" SYSGREEN "\"", PNAME(player), PNAME(player), buf2); } else { sprintf(buf, SYSGREEN "%s pages \"" SYSYELLOW "%s" SYSGREEN "\"", PNAME(player), buf2); } } if (anotify_from(player, target, buf)) anotify_nolisten2(player, CSUCC "Your message has been sent."); else { sprintf(buf, CSUCC "%s is not connected.", PNAME(target)); anotify_nolisten2(player, buf); } }
const char * mfn_force(MFUNARGS) { char *nxt, *ptr; dbref obj = mesg_dbref_raw(player, what, perms, argv[0]); if (obj == AMBIGUOUS || obj == UNKNOWN || obj == NOTHING || obj == HOME) ABORT_MPI("FORCE","Failed match. (arg1)"); if (obj == PERMDENIED) ABORT_MPI("FORCE","Permission denied. (arg1)"); if (Typeof(obj) != TYPE_THING && Typeof(obj) != TYPE_PLAYER) ABORT_MPI("FORCE","Bad object reference. (arg1)"); if (!*argv[1]) ABORT_MPI("FORCE","Null command string. (arg2)"); if (!tp_zombies && !Wizperms(perms)) ABORT_MPI("FORCE","Permission Denied."); if (!Wizperms(perms)) { const char *ptr = RNAME(obj); char objname[BUFFER_LEN], *ptr2; dbref loc = getloc(obj); if (Typeof(obj) == TYPE_THING) { if (FLAGS(obj) & DARK) ABORT_MPI("FORCE","Cannot force a dark puppet."); if ((FLAGS(OWNER(obj)) & ZOMBIE)) ABORT_MPI("FORCE","Permission denied."); if (loc != NOTHING && (FLAGS(loc) & ZOMBIE) && Typeof(loc) == TYPE_ROOM) ABORT_MPI("FORCE","Cannot force a Puppet in a no-puppets room."); for (ptr2 = objname; *ptr && !isspace(*ptr);) *(ptr2++) = *(ptr++); *ptr2 = '\0'; if (lookup_player(objname) != NOTHING) ABORT_MPI("FORCE","Cannot force a thing named after a player."); } if (!(FLAGS(obj) & XFORCIBLE)) { ABORT_MPI("FORCE","Permission denied: forced object not @set Xforcible."); } if (!test_lock_false_default(perms, obj, "@/flk")) { ABORT_MPI("FORCE","Permission denied: Object not force-locked to trigger."); } } if (God(obj)) ABORT_MPI("FORCE","Permission denied: You can't force God."); if (force_level) ABORT_MPI("FORCE","Permission denied: You can't force recursively."); strcpy(buf, argv[1]); ptr = buf; do { nxt = index(ptr, '\r'); if (nxt) *nxt++ = '\0'; force_level++; if (*ptr) process_command(obj, ptr); force_level--; ptr = nxt; } while (ptr); *buf = '\0'; return ""; }
void add_player(dbref who) { hash_data hd; hd.dbval = who; if (add_hash(NAME(who), hd, player_list, PLAYER_HASH_SIZE) == NULL) panic("Out of memory"); if(who != lookup_player(NAME(who))) { log_status(HASH1_MSG); wall_wizards(MARK HASH1_MSG); refresh_players(); if(who != lookup_player(NAME(who))) { log_status(HASH2_MSG); wall_wizards(MARK HASH2_MSG); } } return; }
dbref connect_player(const char *name, const char *password) { dbref player, i; if (*name == '#' && number(name+1) && atoi(name+1)) { player = (dbref) atoi(name + 1); if ((!OkObj(player)) || (Typeof(player) != TYPE_PLAYER)) player = NOTHING; } else { player = lookup_player(name); } if (player == NOTHING) { /* Check for a player not in the hashtable */ for(i = (db_top - 1); i > NOTHING; i--) { if(Typeof(i) == TYPE_PLAYER) { if(!string_compare(name, NAME(i))) { /* Oooga, found a player that lookup didn't! */ log_status(HASH1_MSG); wall_wizards(MARK HASH1_MSG); refresh_players(); player = lookup_player(name); if(player == NOTHING) { log_status(HASH2_MSG); wall_wizards(MARK HASH2_MSG); } break; } } } if(player == NOTHING) return NOTHING; } if (DBFETCH(player)->sp.player.password && *DBFETCH(player)->sp.player.password && strcmp(DBFETCH(player)->sp.player.password, password)) return NOTHING; return player; }
dbref connect_player(const char *name, const char *password) { dbref player; if (*name == NUMBER_TOKEN && number(name + 1) && atoi(name + 1)) { player = (dbref) atoi(name + 1); if ((player < 0) || (player >= db_top) || (Typeof(player) != TYPE_PLAYER)) player = NOTHING; } else { player = lookup_player(name); } if (player == NOTHING) return NOTHING; if (!check_password(player, password)) return NOTHING; return player; }
void match_player(void) { dbref match; if (md.confidence >= CON_DBREF) { return; } if (Good_obj(md.absolute_form) && isPlayer(md.absolute_form)) { promote_match(md.absolute_form, CON_DBREF); return; } if (*md.string == LOOKUP_TOKEN) { match = lookup_player(NOTHING, md.string, 1); if (Good_obj(match)) { promote_match(match, CON_TOKEN); } } }
void do_boot(dbref player, const char *name) { dbref victim; char buf[BUFFER_LEN]; if (!Wizard(player) || Typeof(player) != TYPE_PLAYER) { notify(player, "Only a Wizard player can boot someone off."); return; } if ((victim = lookup_player(name)) == NOTHING) { notify(player, "That player does not exist."); return; } if (Typeof(victim) != TYPE_PLAYER) { notify(player, "You can only boot players!"); } #ifdef GOD_PRIV else if (God(victim)) { notify(player, "You can't boot God!"); } #endif /* GOD_PRIV */ else { notify(victim, "You have been booted off the game."); if (boot_off(victim)) { log_status("BOOTED: %s(%d) by %s(%d)", NAME(victim), victim, NAME(player), player); if (player != victim) { snprintf(buf, sizeof(buf), "You booted %s off!", NAME(victim)); notify(player, buf); } } else { snprintf(buf, sizeof(buf), "%s is not connected.", NAME(victim)); notify(player, buf); } } }
void do_stats(dbref player, const char *name) { int rooms; int exits; int things; int players; int programs; int garbage = 0; int total; int altered = 0; int oldobjs = 0; #ifdef DISKBASE int loaded = 0; int changed = 0; #endif time_t currtime = time(NULL); dbref i; dbref owner=NOTHING; char buf[BUFFER_LEN]; if (!Wizard(OWNER(player)) && (!name || !*name)) { snprintf(buf, sizeof(buf), "The universe contains %d objects.", db_top); notify(player, buf); } else { total = rooms = exits = things = players = programs = 0; if (name != NULL && *name != '\0') { owner = lookup_player(name); if (owner == NOTHING) { notify(player, "I can't find that player."); return; } if (!Wizard(OWNER(player)) && (OWNER(player) != owner)) { notify(player, "Permission denied. (you must be a wizard to get someone else's stats)"); return; } for (i = 0; i < db_top; i++) { #ifdef DISKBASE if ((OWNER(i) == owner) && DBFETCH(i)->propsmode != PROPS_UNLOADED) loaded++; if ((OWNER(i) == owner) && DBFETCH(i)->propsmode == PROPS_CHANGED) changed++; #endif /* count objects marked as changed. */ if ((OWNER(i) == owner) && (FLAGS(i) & OBJECT_CHANGED)) altered++; /* if unused for 90 days, inc oldobj count */ if ((OWNER(i) == owner) && (currtime - DBFETCH(i)->ts.lastused) > tp_aging_time) oldobjs++; switch (Typeof(i)) { case TYPE_ROOM: if (OWNER(i) == owner) total++, rooms++; break; case TYPE_EXIT: if (OWNER(i) == owner) total++, exits++; break; case TYPE_THING: if (OWNER(i) == owner) total++, things++; break; case TYPE_PLAYER: if (i == owner) total++, players++; break; case TYPE_PROGRAM: if (OWNER(i) == owner) total++, programs++; break; } } } else { for (i = 0; i < db_top; i++) { #ifdef DISKBASE if (DBFETCH(i)->propsmode != PROPS_UNLOADED) loaded++; if (DBFETCH(i)->propsmode == PROPS_CHANGED) changed++; #endif /* count objects marked as changed. */ if (FLAGS(i) & OBJECT_CHANGED) altered++; /* if unused for 90 days, inc oldobj count */ if ((currtime - DBFETCH(i)->ts.lastused) > tp_aging_time) oldobjs++; switch (Typeof(i)) { case TYPE_ROOM: total++; rooms++; break; case TYPE_EXIT: total++; exits++; break; case TYPE_THING: total++; things++; break; case TYPE_PLAYER: total++; players++; break; case TYPE_PROGRAM: total++; programs++; break; case TYPE_GARBAGE: total++; garbage++; break; } } } notify_fmt(player, "%7d room%s %7d exit%s %7d thing%s", rooms, (rooms == 1) ? " " : "s", exits, (exits == 1) ? " " : "s", things, (things == 1) ? " " : "s"); notify_fmt(player, "%7d program%s %7d player%s %7d garbage", programs, (programs == 1) ? " " : "s", players, (players == 1) ? " " : "s", garbage); notify_fmt(player, "%7d total object%s %7d old & unused", total, (total == 1) ? " " : "s", oldobjs); #ifdef DISKBASE if (Wizard(OWNER(player))) { notify_fmt(player, "%7d proploaded object%s %7d propchanged object%s", loaded, (loaded == 1) ? " " : "s", changed, (changed == 1) ? "" : "s"); } #endif #ifdef DELTADUMPS { char buf[BUFFER_LEN]; struct tm *time_tm; time_t lasttime = (time_t) get_property_value(0, "_sys/lastdumptime"); time_tm = MUCKTIME(lasttime); format_time(buf, 40, "%a %b %e %T %Z", time_tm); notify_fmt(player, "%7d unsaved object%s Last dump: %s", altered, (altered == 1) ? "" : "s", buf); } #endif } }
void do_quota ( dbref executor, dbref caller, dbref enactor, int eval, int key, int nargs, UTF8 *arg1, UTF8 *arg2, const UTF8 *cargs[], int ncargs ) { UNUSED_PARAMETER(caller); UNUSED_PARAMETER(enactor); UNUSED_PARAMETER(eval); UNUSED_PARAMETER(nargs); UNUSED_PARAMETER(cargs); UNUSED_PARAMETER(ncargs); if (!(mudconf.quotas || Quota(executor))) { notify_quiet(executor, T("Quotas are not enabled.")); return; } if ((key & QUOTA_TOT) && (key & QUOTA_REM)) { notify_quiet(executor, T("Illegal combination of switches.")); return; } dbref who; int value = 0, i; bool set = false; // Show or set all quotas if requested. // if (key & QUOTA_ALL) { if (arg1 && *arg1) { value = mux_atol(arg1); set = true; } else if (key & (QUOTA_SET | QUOTA_FIX)) { value = 0; set = true; } if (set) { STARTLOG(LOG_WIZARD, "WIZ", "QUOTA"); log_name(executor); log_text(T(" changed everyone\xE2\x80\x99s quota")); ENDLOG; } DO_WHOLE_DB(i) { if (isPlayer(i)) { if (set) { mung_quotas(i, key, value); } show_quota(executor, i); } } return; } // Find out whose quota to show or set. // if (!arg1 || *arg1 == '\0') { who = Owner(executor); } else { who = lookup_player(executor, arg1, true); if (!Good_obj(who)) { notify_quiet(executor, T("Not found.")); return; } } // Make sure we have permission to do it. // if (!Quota(executor)) { if (arg2 && *arg2) { notify_quiet(executor, NOPERM_MESSAGE); return; } if (Owner(executor) != who) { notify_quiet(executor, NOPERM_MESSAGE); return; } } if (arg2 && *arg2) { set = true; value = mux_atol(arg2); } else if (key & QUOTA_FIX) { set = true; value = 0; } if (set) { STARTLOG(LOG_WIZARD, "WIZ", "QUOTA"); log_name(executor); log_text(T(" changed the quota of ")); log_name(who); ENDLOG; mung_quotas(who, key, value); } show_quota(executor, who); }
/* ehp: view players' ehp */ int CmdHandler::ehp(char *out, struct command *c) { int usenick, status; char buf[RSN_BUF]; const char *fil, *type; int opt; static struct l_option long_opts[] = { { "f2p", NO_ARG, 'f' }, { "help", NO_ARG, 'h' }, { "ironman", NO_ARG, 'i' }, { "nick", NO_ARG, 'n' }, { 0, 0, 0 } }; usenick = 0; status = EXIT_SUCCESS; type = fil = ""; opt_init(); while ((opt = l_getopt_long(c->argc, c->argv, "fin", long_opts)) != EOF) { switch (opt) { case 'f': fil = "f2p&filter=f2p"; type = "-F2P"; break; case 'h': HELPMSG(out, CMDNAME, CMDUSAGE, CMDDESCR); return EXIT_SUCCESS; case 'i': fil = "im&filter=ironman"; type = "-IM"; break; case 'n': usenick = 1; break; case '?': snprintf(out, MAX_MSG, "%s", l_opterr()); return EXIT_FAILURE; default: return EXIT_FAILURE; } } if (l_optind == c->argc) { if (usenick) { snprintf(out, MAX_MSG, "%s: no Twitch name given", c->argv[0]); status = EXIT_FAILURE; } else { snprintf(out, MAX_MSG, "%s", EHP_DESC); } return status; } if (l_optind != c->argc - 1) { USAGEMSG(out, CMDNAME, CMDUSAGE); return EXIT_FAILURE; } if (!getrsn(buf, RSN_BUF, c->argv[l_optind], c->nick, usenick)) { snprintf(out, MAX_MSG, "%s: %s", c->argv[0], buf); return EXIT_FAILURE; } return lookup_player(out, buf, fil, type); }
/** Check to see if someone can connect to a player. * \param d DESC the connect attempt is being made for * \param name name of player to connect to. * \param password password of player to connect to. * \param host host from which connection is being attempted. * \param ip ip address from which connection is being attempted. * \param errbuf buffer to return connection errors. * \return dbref of connected player object or NOTHING for failure * (with reason for failure returned in errbuf). */ dbref connect_player(DESC *d, const char *name, const char *password, const char *host, const char *ip, char *errbuf) { dbref player; int count; /* Default error */ strcpy(errbuf, T("Either that player does not exist, or has a different password.")); if (!name || !*name) return NOTHING; /* validate name */ if ((player = lookup_player(name)) == NOTHING) { /* Invalid player names are failures, too. */ count = mark_failed(ip); strcpy(errbuf, T("There is no player with that name.")); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d,%s", d->descriptor, ip, count, "invalid player", -1, name); return NOTHING; } /* See if player is allowed to connect like this */ if (Going(player) || Going_Twice(player)) { do_log(LT_CONN, 0, 0, "Connection to GOING player %s not allowed from %s (%s)", Name(player), host, ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count_failed(ip), "player is going", player); strcpy(errbuf, T("You cannot connect to that player at this time.")); return NOTHING; } /* Check sitelock patterns */ if (Guest(player) && (!Site_Can_Guest(host, player) || !Site_Can_Guest(ip, player))) { if (!Deny_Silent_Site(host, AMBIGUOUS) && !Deny_Silent_Site(ip, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "Connection to %s (GUEST) not allowed from %s (%s)", name, host, ip); strcpy(errbuf, T("Guest connections not allowed.")); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "failed sitelock", player); } return NOTHING; } else if (!Guest(player) && (!Site_Can_Connect(host, player) || !Site_Can_Connect(ip, player))) { if (!Deny_Silent_Site(host, player) && !Deny_Silent_Site(ip, player)) { do_log(LT_CONN, 0, 0, "Connection to %s (Non-GUEST) not allowed from %s (%s)", name, host, ip); strcpy(errbuf, T("Player connections not allowed.")); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "failed sitelock", player); } return NOTHING; } /* validate password */ if (!Guest(player)) if (!password_check(player, password)) { /* Increment count of login failures */ ModTime(player)++; check_lastfailed(player, host); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "invalid password", player); strcpy(errbuf, T("That is not the correct password.")); return NOTHING; } /* If it's a Guest player, and already connected, search the * db for another Guest player to connect them to. */ if (Guest(player)) { /* Enforce guest limit */ player = guest_to_connect(player); if (!GoodObject(player)) { do_log(LT_CONN, 0, 0, "Can't connect to a guest (too many connected)"); strcpy(errbuf, T("Too many guests are connected now.")); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count_failed(ip), "too many guests", player); return NOTHING; } } if (Suspect_Site(host, player) || Suspect_Site(ip, player)) { do_log(LT_CONN, 0, 0, "Connection from Suspect site. Setting %s(#%d) suspect.", Name(player), player); set_flag_internal(player, "SUSPECT"); } return player; }
/** Change an object's owner. * \verbatim * This implements @chown. * \endverbatim * \param player the enactor. * \param name name of object to change owner of. * \param newobj name of new owner for object. * \param preserve if 1, preserve privileges and don't halt the object. * \param pe_info the pe_info for lock checks */ void do_chown(dbref player, const char *name, const char *newobj, int preserve, NEW_PE_INFO *pe_info) { dbref thing; dbref newowner = NOTHING; long match_flags = MAT_POSSESSION | MAT_HERE | MAT_EXIT | MAT_ABSOLUTE; /* check for '@chown <object>/<atr>=<player>' */ if (strchr(name, '/')) { do_atrchown(player, name, newobj); return; } if (Wizard(player)) match_flags |= MAT_PLAYER; if ((thing = noisy_match_result(player, name, TYPE_THING, match_flags)) == NOTHING) return; if (!*newobj || !strcasecmp(newobj, "me")) { newowner = player; } else { if ((newowner = lookup_player(newobj)) == NOTHING) { notify(player, T("I couldn't find that player.")); return; } } if (IsPlayer(thing) && !God(player)) { notify(player, T("Players always own themselves.")); return; } /* Permissions checking */ if (!chown_ok(player, thing, newowner, pe_info)) { notify(player, T("Permission denied.")); return; } if (IsThing(thing) && !Hasprivs(player) && !(GoodObject(Location(thing)) && (Location(thing) == player))) { notify(player, T("You must carry the object to @chown it.")); return; } if (preserve && !Wizard(player)) { notify(player, T("You cannot @CHOWN/PRESERVE. Use normal @CHOWN.")); return; } /* chowns to the zone master don't count towards fees */ if (!ZMaster(newowner)) { /* Debit the owner-to-be */ if (!can_pay_fees(newowner, Pennies(thing))) { /* not enough money or quota */ if (newowner != player) notify(player, T ("That player doesn't have enough money or quota to receive that object.")); return; } /* Credit the current owner */ giveto(Owner(thing), Pennies(thing)); change_quota(Owner(thing), QUOTA_COST); } chown_object(player, thing, newowner, preserve); notify(player, T("Owner changed.")); }
/** Attempt to register a new player at the connect screen. * If registration is allowed, a new player object is created with * a random password which is emailed to the registering player. * \param name name of player to register. * \param email email address to send registration details. * \param host host from which registration is being attempted. * \param ip ip address from which registration is being attempted. * \return dbref of created player or NOTHING if creation failed. */ dbref email_register_player(DESC *d, const char *name, const char *email, const char *host, const char *ip) { char *p; char passwd[20]; static char elems[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; int i, len; bool resend = 0; dbref player = NOTHING; FILE *fp; size_t NELEMS = sizeof(elems) - 1; char sbuff[260]; if (!check_fails(ip)) { return NOTHING; } if (strlen(options.sendmail_prog) == 0) return NOTHING; if (!ok_player_name(name, NOTHING, NOTHING)) { /* Check for re-registration request */ player = lookup_player(name); if (GoodObject(player)) { ATTR *a; a = atr_get(player, "LASTLOGOUT"); if (!a) { a = atr_get(player, "REGISTERED_EMAIL"); if (a && !strcasecmp(atr_value(a), email)) resend = 1; } } if (!resend) { do_log(LT_CONN, 0, 0, "Failed registration (bad name) from %s", host); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "register: bad name", name); return NOTHING; } } if (!resend) { /* Make sure that the email address is kind of valid. A valid * address must contain a @. Let the mailer sort it out beyond * that. Also, to prevent someone from using the MUSH to mailbomb * another site, let's make sure that the site to which the user * wants the email sent is also allowed to use the register * command. If there's an @, we check whatever's after the last @ * (since @foo.bar:user@host is a valid email). */ if ((p = strrchr(email, '@'))) { p++; if (!Site_Can_Register(p)) { if (!Deny_Silent_Site(p, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "Failed registration (bad site in email: %s) from %s", email, host); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "register: bad site in email", name); } return NOTHING; } } else { if (!Deny_Silent_Site(host, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "Failed registration (bad email: %s) from %s", email, host); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, mark_failed(ip), "register: sitelocked host", name); } return NOTHING; } if (DBTOP_MAX && (db_top >= DBTOP_MAX + 1) && (first_free == NOTHING)) { /* Oops, out of db space! */ do_log(LT_CONN, 0, 0, "Failed registration (no db space) from %s", host); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s", d->descriptor, ip, count_failed(ip), "register: no db space left to create!", name); return NOTHING; } } /* Come up with a random password of length 7-12 chars */ len = get_random_u32(7, 12); for (i = 0; i < len; i++) passwd[i] = elems[get_random_u32(0, NELEMS - 1)]; passwd[len] = '\0'; /* If we've made it here, we can send the email and create the * character. Email first, since that's more likely to go bad. * Some security precautions we'll take: * 1) We'll use sendmail -t, so we don't pass user-given values to a shell. * 2) We'll cross our fingers and hope nobody uses this to spam. */ release_fd(); snprintf(sbuff, sizeof sbuff, "%s -t", options.sendmail_prog); if ((fp = popen(sbuff, "w")) == NULL) { do_log(LT_CONN, 0, 0, "Failed registration of %s by %s: unable to open sendmail", name, email); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s,%d", d->descriptor, ip, count_failed(ip), "register: Unable to open sendmail!", name, 1); reserve_fd(); return NOTHING; } fprintf(fp, "Subject: "); fprintf(fp, T("[%s] Registration of %s\n"), MUDNAME, name); fprintf(fp, "To: %s\n", email); fprintf(fp, "Precedence: junk\n"); fprintf(fp, "\n"); fprintf(fp, T("This is an automated message.\n")); fprintf(fp, "\n"); fprintf(fp, T("Your requested player, %s, has been created.\n"), name); fprintf(fp, T("The password is %s\n"), passwd); fprintf(fp, "\n"); fprintf(fp, T("To access this character, connect to %s and type:\n"), MUDNAME); fprintf(fp, "\tconnect \"%s\" %s\n", name, passwd); fprintf(fp, "\n"); i = pclose(fp); reserve_fd(); if (i != 0) { /* Mailer exited with an error code. Log it. */ do_rawlog( LT_CONN, "When attempting to email a password to a newly registered player,\n" "\tthe mailer exited with error code %d.\n" "\t(Check /usr/include/sysexits.h if present for the meaning.)", i); queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s,%d", d->descriptor, ip, count_failed(ip), "register: Unable to send email", name, i); return NOTHING; } else if (resend) { /* Reset the password */ (void) atr_add(player, pword_attr, password_hash(passwd, NULL), GOD, 0); return player; } else { /* Ok, all's well, make a player */ player = make_player(name, passwd, host, ip); queue_event(SYSEVENT, "PLAYER`CREATE", "%s,%s,%s,%d,%s", unparse_objid(player), name, "register", d->descriptor, email); (void) atr_add(player, "REGISTERED_EMAIL", email, GOD, 0); return player; } }
int tune_setparm(const dbref player, const char *parmname, const char *val) { struct tune_str_entry *tstr = tune_str_list; struct tune_time_entry *ttim = tune_time_list; struct tune_val_entry *tval = tune_val_list; struct tune_ref_entry *tref = tune_ref_list; struct tune_bool_entry *tbool = tune_bool_list; char buf[BUFFER_LEN]; char *parmval; strcpy(buf, val); parmval = buf; while (tstr->name) { if (!string_compare(parmname, tstr->name)) { if ((player != NOTHING) && (WLevel(OWNER(player)) < tstr->writemlev)) return TUNESET_NOPERM; if (!tstr->isdefault) free((char *) *tstr->str); if (*parmval == '-') parmval++; *tstr->str = string_dup(parmval); tstr->isdefault = 0; return 0; } tstr++; } while (ttim->name) { if (!string_compare(parmname, ttim->name)) { int days, hrs, mins, secs, result; char *end; if ((player != NOTHING) && (WLevel(OWNER(player)) < ttim->writemlev)) return TUNESET_NOPERM; days = hrs = mins = secs = 0; end = parmval + strlen(parmval) - 1; switch (*end) { case 's': case 'S': *end = '\0'; if (!number(parmval)) return 2; secs = atoi(parmval); break; case 'm': case 'M': *end = '\0'; if (!number(parmval)) return 2; mins = atoi(parmval); break; case 'h': case 'H': *end = '\0'; if (!number(parmval)) return 2; hrs = atoi(parmval); break; case 'd': case 'D': *end = '\0'; if (!number(parmval)) return 2; days = atoi(parmval); break; default: result = sscanf(parmval, "%dd %2d:%2d:%2d", &days, &hrs, &mins, &secs); if (result != 4) return 2; break; } *ttim->tim = (days * 86400) + (3600 * hrs) + (60 * mins) + secs; return 0; } ttim++; } while (tval->name) { if (!string_compare(parmname, tval->name)) { if ((player != NOTHING) && (WLevel(OWNER(player)) < tval->writemlev)) return TUNESET_NOPERM; if (!number(parmval)) return 2; *tval->val = atoi(parmval); return 0; } tval++; } while (tref->name) { if (!string_compare(parmname, tref->name)) { dbref obj; if ((player != NOTHING) && (WLevel(OWNER(player)) < tref->writemlev)) return TUNESET_NOPERM; if (!strcmp(parmval, "me")) obj = player; #ifndef SANITY else if (*parmval == '*') obj = lookup_player(parmval + 1); #endif else { if (*parmval != NUMBER_TOKEN) return 2; if (!number(parmval + 1)) return 2; obj = (dbref) atoi(parmval + 1); } if (obj < -1 || obj >= db_top) return 2; if (obj != -1 && tref->typ != NOTYPE && Typeof(obj) != tref->typ) return 3; *tref->ref = obj; return 0; } tref++; } while (tbool->name) { if (!string_compare(parmname, tbool->name)) { if ((player != NOTHING) && (WLevel(OWNER(player)) < tbool->writemlev)) return TUNESET_NOPERM; if (*parmval == 'y' || *parmval == 'Y') { *tbool->boolv = 1; } else if (*parmval == 'n' || *parmval == 'N') { *tbool->boolv = 0; } else { return 2; } return 0; } tbool++; } return 1; }
void do_force(int descr, dbref player, const char *what, char *command) { dbref victim, loc; struct match_data md; assert(what != NULL); assert(command != NULL); assert(player > 0); if (force_level > (tp_max_force_level - 1)) { notify(player, "Can't force recursively."); return; } if (!tp_zombies && (!Wizard(player) || Typeof(player) != TYPE_PLAYER)) { notify(player, "Zombies are not enabled here."); return; #ifdef DEBUG } else { notify(player, "[debug] Zombies are not enabled for nonwizards -- force succeeded."); #endif } /* get victim */ init_match(descr, player, what, NOTYPE, &md); match_neighbor(&md); match_possession(&md); match_me(&md); match_here(&md); match_absolute(&md); match_registered(&md); match_player(&md); if ((victim = noisy_match_result(&md)) == NOTHING) { #ifdef DEBUG notify(player, "[debug] do_force: unable to find your target!"); #endif /* DEBUG */ return; } if (Typeof(victim) != TYPE_PLAYER && Typeof(victim) != TYPE_THING) { notify(player, "Permission Denied -- Target not a player or thing."); return; } #ifdef GOD_PRIV if (God(victim)) { notify(player, "You cannot force God to do anything."); return; } #endif /* GOD_PRIV */ /* if (!controls(player, victim)) { * notify(player, "Permission denied. (you're not a wizard!)"); * return; * } */ if (!Wizard(player) && !(FLAGS(victim) & XFORCIBLE)) { notify(player, "Permission denied: forced object not @set Xforcible."); return; } if (!Wizard(player) && !test_lock_false_default(descr, player, victim, MESGPROP_FLOCK)) { notify(player, "Permission denied: Object not force-locked to you."); return; } loc = getloc(victim); if (!Wizard(player) && Typeof(victim) == TYPE_THING && loc != NOTHING && (FLAGS(loc) & ZOMBIE) && Typeof(loc) == TYPE_ROOM) { notify(player, "Sorry, but that's in a no-puppet zone."); return; } if (!Wizard(OWNER(player)) && Typeof(victim) == TYPE_THING) { const char *ptr = NAME(victim); char objname[BUFFER_LEN], *ptr2; if ((FLAGS(player) & ZOMBIE)) { notify(player, "Permission denied -- you cannot use zombies."); return; } if (FLAGS(victim) & DARK) { notify(player, "Permission denied -- you cannot force dark zombies."); return; } for (ptr2 = objname; *ptr && !isspace(*ptr);) *(ptr2++) = *(ptr++); *ptr2 = '\0'; if (lookup_player(objname) != NOTHING) { notify(player, "Puppet cannot share the name of a player."); return; } } log_status("FORCED: %s(%d) by %s(%d): %s", NAME(victim), victim, NAME(player), player, command); /* force victim to do command */ force_prog=NOTHING; force_level++; process_command(dbref_first_descr(victim), victim, command); force_level--; force_prog=NOTHING; }
void do_toad(int descr, dbref player, const char *name, const char *recip) { dbref victim; dbref recipient; dbref stuff; char buf[BUFFER_LEN]; if (!Wizard(player) || Typeof(player) != TYPE_PLAYER) { notify(player, "Only a Wizard player can turn a person into a toad."); return; } if ((victim = lookup_player(name)) == NOTHING) { notify(player, "That player does not exist."); return; } #ifdef GOD_PRIV if (God(victim)) { notify(player, "You cannot @toad God."); if(!God(player)) { log_status("TOAD ATTEMPT: %s(#%d) tried to toad God.",NAME(player),player); } return; } #endif if(player == victim) { /* If GOD_PRIV isn't defined, this could happen: we don't want the * last wizard to be toaded, in any case, so only someone else can * do it. */ notify(player, "You cannot toad yourself. Get someone else to do it for you."); return; } if (victim == tp_toad_default_recipient) { notify(player, "That player is part of the @toad process, and cannot be deleted."); return; } if (!*recip) { recipient = tp_toad_default_recipient; } else { if ((recipient = lookup_player(recip)) == NOTHING || recipient == victim) { notify(player, "That recipient does not exist."); return; } } if (Typeof(victim) != TYPE_PLAYER) { notify(player, "You can only turn players into toads!"); #ifdef GOD_PRIV } else if (!(God(player)) && (TrueWizard(victim))) { #else } else if (TrueWizard(victim)) { #endif notify(player, "You can't turn a Wizard into a toad."); } else { /* we're ok */ /* do it */ send_contents(descr, victim, HOME); dequeue_prog(victim, 0); /* Dequeue the programs that the player's running */ for (stuff = 0; stuff < db_top; stuff++) { if (OWNER(stuff) == victim) { switch (Typeof(stuff)) { case TYPE_PROGRAM: dequeue_prog(stuff, 0); /* dequeue player's progs */ if (TrueWizard(recipient)) { FLAGS(stuff) &= ~(ABODE | WIZARD); SetMLevel(stuff, 1); } case TYPE_ROOM: case TYPE_THING: case TYPE_EXIT: OWNER(stuff) = recipient; DBDIRTY(stuff); break; } } if (Typeof(stuff) == TYPE_THING && THING_HOME(stuff) == victim) { THING_SET_HOME(stuff, tp_lost_and_found); } } chown_macros(victim, recipient); if (PLAYER_PASSWORD(victim)) { free((void *) PLAYER_PASSWORD(victim)); PLAYER_SET_PASSWORD(victim, 0); } /* notify people */ notify(victim, "You have been turned into a toad."); snprintf(buf, sizeof(buf), "You turned %s into a toad!", NAME(victim)); notify(player, buf); log_status("TOADED: %s(%d) by %s(%d)", NAME(victim), victim, NAME(player), player); /* reset name */ delete_player(victim); snprintf(buf, sizeof(buf), "A slimy toad named %s", NAME(victim)); free((void *) NAME(victim)); NAME(victim) = alloc_string(buf); DBDIRTY(victim); boot_player_off(victim); /* Disconnect the toad */ if (PLAYER_DESCRS(victim)) { free(PLAYER_DESCRS(victim)); PLAYER_SET_DESCRS(victim, NULL); PLAYER_SET_DESCRCOUNT(victim, 0); } ignore_remove_from_all_players(victim); ignore_flush_cache(victim); FREE_PLAYER_SP(victim); ALLOC_THING_SP(victim); THING_SET_HOME(victim, PLAYER_HOME(player)); FLAGS(victim) = TYPE_THING; OWNER(victim) = player; /* you get it */ SETVALUE(victim, 1); /* don't let him keep his immense wealth */ } }