/* wiz.c */ #include "copyrite.h" #include "config.h" /* Wizard-only commands */ #ifdef I_UNISTD #include <unistd.h> #endif #ifdef I_STRING #include <string.h> #else #include <strings.h> #endif #include <math.h> #ifdef I_SYS_TIME #include <sys/time.h> #else #include <time.h> #endif #ifdef I_STDLIB #include <stdlib.h> #endif #include <ctype.h> #ifdef I_FCNTL #include <fcntl.h> #endif #ifdef WIN32 #include <windows.h> #undef OPAQUE #endif #include "conf.h" #include "mushdb.h" #include "intrface.h" #include "match.h" #include "externs.h" #include "access.h" #include "parse.h" #include "mymalloc.h" #ifdef MEM_CHECK #include "memcheck.h" #endif #include "confmagic.h" extern dbref find_entrance _((dbref door)); extern void delete_player _((dbref player, char *alias)); extern int convert_flags _((dbref player, char *s, object_flag_type *p_mask, object_flag_type *p_toggle, object_flag_type *p_type)); extern int hidden _((dbref player)); extern struct db_stat_info *get_stats _((dbref player, dbref owner)); extern dbref find_player_by_desc _((int port)); extern int paranoid_dump; extern int paranoid_checkpt; extern int invok_counter; /* invocation limit */ #ifndef WIN32 #include <sys/file.h> extern int reserved; #else void Win32stats(dbref player); extern void compress_stats(long *entries, long *mem_used, long *total_uncompressed, long *total_compressed); #endif void do_pcreate _((dbref creator, const char *player_name, const char *player_password)); #ifdef QUOTA void do_quota _((dbref player, const char *arg1, const char *arg2, int set_q)); void do_allquota _((dbref player, const char *arg1, int quiet)); #endif int tport_dest_ok _((dbref player, dbref victim, dbref dest)); int tport_control_ok _((dbref player, dbref victim, dbref loc)); void do_teleport _((dbref player, const char *arg1, const char *arg2)); void do_force _((dbref player, const char *what, char *command)); int force_by_number _((dbref player, char *command)); void do_stats _((dbref player, const char *name)); void do_toad _((dbref player, const char *name)); void do_newpassword _((dbref player, const char *name, const char *password)); void do_boot _((dbref player, const char *name, int flag)); #ifdef CONCENTRATOR int parse_conc_descriptor _((char *str, int cport, int port)); #endif void do_chownall _((dbref player, const char *name, const char *target)); void do_chzoneall _((dbref player, const char *name, const char *target)); void do_enable _((dbref player, const char *param, int state)); void do_kick _((dbref player, const char *num)); void do_fixdb _((dbref player, const char *name, const char *val, int sw_opt)); void do_debug_examine _((dbref player, const char *name)); void do_power _((dbref player, const char *name, const char *power)); void do_search _((dbref player, const char *arg1, char **arg3)); void do_sitelock _((dbref player, const char *site, const char *opts, int type)); void do_reboot _((dbref player, int flag)); static int mem_usage _((dbref thing)); extern char confname[BUFFER_LEN]; extern char errlog[BUFFER_LEN]; void do_pcreate(creator, player_name, player_password) dbref creator; const char *player_name; const char *player_password; { dbref player; if (!Create_Player(creator)) { notify(creator, "You do not have the power over body and mind!"); return; } player = create_player(player_name, player_password, "None"); if (player == NOTHING) { notify(creator, tprintf("failure creating '%s' (bad name)", player_name)); return; } if (player == AMBIGUOUS) { notify(creator, tprintf("failure creating '%s' (bad password)", player_name)); return; } notify(creator, tprintf("New player '%s' created with password '%s'", player_name, player_password)); do_log(LT_WIZ, creator, player, "Player creation"); } #ifdef QUOTA void do_quota(player, arg1, arg2, set_q) dbref player; const char *arg1; const char *arg2; int set_q; /* 0 = @quota, 1 = @squota */ { dbref who, thing; int owned, limit, adjust; /* determine the victim */ if (!arg1 || !*arg1 || !strcmp(arg1, "me")) who = player; else { who = lookup_player(arg1); if (who == NOTHING) { notify(player, "No such player."); return; } } /* check permissions */ if (!Wizard(player) && set_q) { notify(player, "Only wizards may change a quota."); return; } if (!Do_Quotas(player) && !See_All(player) && (player != who)) { notify(player, "You can't look at someone else's quota."); return; } /* count up all owned objects */ owned = -1; /* a player is never included in his own * quota */ for (thing = 0; thing < db_top; thing++) { if (db[thing].owner == who) if (!Destroyed(thing)) ++owned; } /* the quotas of priv'ed players are unlimited and cannot be set. */ if (NoQuota(who)) { notify(player, tprintf("Objects: %d Limit: UNLIMITED", owned)); return; } /* if we're not doing a change, determine the mortal's quota limit. * RQUOTA is the objects _left_, not the quota itself. */ if (!set_q) { limit = get_current_quota(who); notify(player, tprintf("Objects: %d Limit: %d", owned, owned + limit)); return; } /* set a new quota */ if (!arg2 || !*arg2) { notify(player, "What do you want to set the quota to?"); return; } adjust = ((*arg2 == '+') || (*arg2 == '-')); if (adjust) limit = owned + get_current_quota(who) + atoi(arg2); else limit = atoi(arg2); if (limit < owned) /* always have enough quota for your objects */ limit = owned; atr_add(Owner(who), "RQUOTA", tprintf("%d", limit - owned), GOD, NOTHING); notify(player, tprintf("Objects: %d Limit: %d", owned, limit)); } void do_allquota(player, arg1, quiet) dbref player; const char *arg1; int quiet; { int oldlimit, limit, owned; dbref who, thing; if (!God(player)) { notify(player, "Who do you think you are, GOD?"); return; } if (!arg1 || !*arg1) { limit = -1; } else if (!is_integer(arg1)) { notify(player, "You can only set quotas to a number."); return; } else { limit = parse_integer(arg1); if (limit < 0) { notify(player, "You can only set quotas to a positive number."); return; } } for (who = 0; who < db_top; who++) { if (Typeof(who) != TYPE_PLAYER) continue; /* count up all owned objects */ owned = -1; /* a player is never included in his own * quota */ for (thing = 0; thing < db_top; thing++) { if (db[thing].owner == who) if (!Destroyed(thing)) ++owned; } if (NoQuota(who)) { if (!quiet) notify(player, tprintf("%s: Objects: %d Limit: UNLIMITED", Name(who), owned)); continue; } if (!quiet) { oldlimit = get_current_quota(who); notify(player, tprintf("%s: Objects: %d Limit: %d", Name(who), owned, oldlimit)); } if (limit != -1) { if (limit <= owned) atr_add(who, "RQUOTA", "0", GOD, NOTHING); else atr_add(who, "RQUOTA", tprintf("%d", limit - owned), GOD, NOTHING); } } if (limit == -1) notify(player, "Quotas not changed."); else notify(player, tprintf("All quotas changed to %d.", limit)); } #endif /* QUOTA */ int tport_dest_ok(player, victim, dest) dbref player; dbref victim; dbref dest; { /* can player legitimately send something to dest */ if (Tel_Anywhere(player)) return 1; if (controls(player, dest)) return 1; /* beyond this point, if you don't control it and it's not a room, no hope */ if (Typeof(dest) != TYPE_ROOM) return 0; /* Check for a teleport lock. It fails if the player is not wiz or * royalty, and the room is tport-locked against the victim, and the * victim does not control the room. */ if (!eval_lock(victim, dest, Tport_Lock)) return 0; if (Toggles(dest) & ROOM_JUMP_OK) return 1; return 0; } int tport_control_ok(player, victim, loc) dbref player; dbref victim; dbref loc; { /* can player legitimately move victim from loc */ if (God(victim) && !God(player)) return 0; if (Tel_Anything(player)) return 1; if (controls(player, victim)) return 1; /* mortals can't @tel priv'ed players just on basis of location ownership */ if (controls(player, loc) && (!Hasprivs(victim) || Owns(player, victim))) return 1; return 0; } void do_teleport(player, arg1, arg2) dbref player; const char *arg1; const char *arg2; { dbref victim; dbref destination; dbref loc; const char *to; dbref absroom; /* "absolute room", for NO_TEL check */ int rec = 0; /* recursion counter */ /* get victim, destination */ if (*arg2 == '\0') { victim = player; to = arg1; } else { if ((victim = noisy_match_result(player, arg1, NOTYPE, MAT_OBJECTS)) == NOTHING) { return; } to = arg2; } if (Typeof(victim) == TYPE_ROOM) { notify(player, "You can't teleport rooms."); return; } if (Destroyed(victim)) { notify(player, "Garbage belongs in the garbage dump."); return; } /* get destination */ if (!strcasecmp(to, "home")) { /* If the object is @tel'ing itself home, treat it the way we'd * treat a 'home' command */ if (player == victim) { #ifdef FIXED_FLAG if (Fixed(Owner(victim))) notify(player, "You can't do that IC!"); else #endif safe_tel(victim, HOME); return; } else destination = db[victim].exits; } else { destination = match_result(player, to, TYPE_PLAYER, MAT_EVERYTHING); } switch (destination) { case NOTHING: notify(player, "No match."); break; case AMBIGUOUS: notify(player, "I don't know which destination you mean!"); break; case HOME: destination = Home(victim); /* FALL THROUGH */ default: /* check victim, destination types, teleport if ok */ if (!GoodObject(destination)) { notify(player, "Bad destination."); return; } if (recursive_member(destination, victim, 0) || (victim == destination)) { notify(player, "Bad destination."); return; } if (!Tel_Anywhere(player) && (Typeof(victim) == TYPE_PLAYER) && (Typeof(destination) == TYPE_PLAYER)) { notify(player, "Bad destination."); return; } if (Typeof(victim) == TYPE_EXIT) { /* Teleporting an exit means moving its source */ if (Typeof(destination) != TYPE_ROOM) { notify(player, "Exits can only be teleported to other rooms."); return; } if (Going(destination)) { notify(player, "You can't move an exit to someplace that's crumbling."); return; } if (!GoodObject(Home(victim))) loc = find_entrance(victim); else loc = Home(victim); if (!GoodObject(loc)) { notify(player, "I can't find that exit!"); return; } if (!(tport_control_ok(player, victim, loc) && tport_dest_ok(player, victim, destination))) { notify(player, "Permission denied."); return; } /* Remove it from its old room */ db[loc].exits = remove_first(db[loc].exits, victim); /* Put it into its new room */ Home(victim) = destination; PUSH(victim, Exits(destination)); notify(player, "Teleported."); return; } loc = Location(victim); /* if royal or wiz and destination is player, tel to location */ if ((Typeof(destination) == TYPE_PLAYER) && (Tel_Anywhere(player)) && (Typeof(victim) == TYPE_PLAYER)) { if (loc != Location(destination)) did_it(victim, victim, NULL, NULL, "OXTPORT", NULL, NULL, loc); safe_tel(victim, Location(destination)); if (loc != Location(destination)) did_it(victim, victim, "TPORT", NULL, "OTPORT", NULL, "ATPORT", Location(destination)); return; } /* check needed for NOTHING. Especially important for unlinked exits */ if ((absroom = db[victim].location) == NOTHING) { notify(victim, "You're in the Void. This is not a good thing."); if (Home(victim) == absroom) Home(victim) = PLAYER_START; do_move(victim, "home", 0); return; } else { /* valid location, perform other checks */ /* if player is inside himself, send him home */ if (absroom == victim) { notify(player, "What are you doing inside of yourself?"); if (Home(victim) == absroom) Home(victim) = PLAYER_START; do_move(victim, "home", 0); return; } /* find the "absolute" room */ while (GoodObject(absroom) && (Typeof(absroom) != TYPE_ROOM) && (rec <= 15)) { absroom = db[absroom].location; rec++; } if (!GoodObject(absroom)) { notify(victim, "You're in the void - sending you home."); if (Home(victim) == Location(victim)) Home(victim) = PLAYER_START; do_move(victim, "home", 0); return; } /* if there are a lot of containers, send him home */ if (rec > 15) { notify(victim, "You're in too many containers."); if (Home(victim) == Location(victim)) Home(victim) = PLAYER_START; do_move(victim, "home", 0); return; } /* note that we check the NO_TEL status of the victim rather * than the player that issued the command. This prevents someone * in a NO_TEL room from having one of his objects @tel him out. * The control check, however, is detemined by command-giving * player. */ /* now check to see if the absolute room is set NO_TEL */ if (IS(absroom, TYPE_ROOM, ROOM_NO_TEL) && !controls(player, absroom) && !Tel_Anywhere(player)) { notify(player, "Teleports are not allowed in this room."); return; } /* Now check the Z_TEL status of the victim's room. * Just like NO_TEL above, except that if the room (or its * Zone Master Room, if any, is Z_TEL, * the destination must also be a room in the same zone */ if (GoodObject(Zone(absroom)) && (IS(absroom, TYPE_ROOM, ROOM_Z_TEL) || IS(Zone(absroom), TYPE_ROOM, ROOM_Z_TEL)) && !controls(player, absroom) && !Tel_Anywhere(player) && (Zone(absroom) != Zone(destination))) { notify(player, "You may not teleport out of the zone from this room."); return; } } if (Typeof(destination) != TYPE_EXIT) { if (tport_control_ok(player, victim, Location(victim)) && tport_dest_ok(player, victim, destination) #ifdef FIXED_FLAG && (Tel_Anything(player) || (Tel_Anywhere(player) && (player == victim)) || (destination == Owner(victim)) || (!Fixed(Owner(victim)) && !Fixed(Owner(player)))) #endif ) { if (loc != destination) did_it(victim, victim, NULL, NULL, "OXTPORT", NULL, NULL, loc); safe_tel(victim, destination); if (loc != destination) did_it(victim, victim, "TPORT", NULL, "OTPORT", NULL, "ATPORT", destination); if ((victim != player) && !(IS(victim, TYPE_THING, THING_PUPPET) && (Owner(victim) == Owner(player)))) notify(player, "Teleported."); return; } /* we can't do it */ did_it(player, destination, "EFAIL", "Permission denied.", "OEFAIL", NULL, "AEFAIL", Location(player)); return; } else { /* attempted teleport to an exit */ if (controls(player, victim) || controls(player, db[victim].location)) { do_move(victim, to, 0); } else { notify(victim, tprintf("%s tries to impose his will on you and fails.", db[player].name)); } } } } void do_force(player, what, command) dbref player; const char *what; char *command; { dbref victim; int j; if ((victim = match_controlled(player, what)) == NOTHING) { notify(player, "Sorry."); return; } if ((Typeof(victim) == TYPE_ROOM) || (Typeof(victim) == TYPE_EXIT)) { notify(player, "You can only force players and things."); return; } if (options.log_forces) { if (Wizard(player)) { /* Log forces by wizards */ if (db[victim].owner != db[player].owner) do_log(LT_WIZ, player, victim, "** FORCE: %s", command); else do_log(LT_WIZ, player, victim, "FORCE: %s", command); } else if (Wizard(Owner(victim))) { /* Log forces of wizards */ do_log(LT_WIZ, player, victim, "** FORCE WIZ-OWNED: %s", command); } } if (God(victim) && !God(player)) { notify(player, "You can't force God!"); return; } /* force victim to do command */ for (j = 0; j < 10; j++) { wnxt[j] = wenv[j]; rnxt[j] = renv[j]; } parse_que(victim, command, player); } int force_by_number(player, command) dbref player; char *command; { /* the command handler has given us something of the format * <#dbref> <command>. Split it up and pass it to @force handler. * We can hack it up in-place, since we won't need it the input again. */ char *s; for (s = command; *s && !isspace(*s); s++) ; if (!*s) return (0); *s++ = '\0'; do_force(player, command, s); return (1); } extern struct db_stat_info * get_stats(player, owner) dbref player; dbref owner; { dbref i; static struct db_stat_info si; si.total = si.rooms = si.exits = si.things = si.players = si.garbage = 0; for (i = 0; i < db_top; i++) { if (owner == ANY_OWNER || owner == db[i].owner) { si.total++; if (Destroyed(i)) { si.garbage++; } else { switch (Typeof(i)) { case TYPE_ROOM: si.rooms++; break; case TYPE_EXIT: si.exits++; break; case TYPE_THING: si.things++; break; case TYPE_PLAYER: si.players++; break; default: break; } } } } return &si; } void do_stats(player, name) dbref player; const char *name; { struct db_stat_info *si; dbref owner; if (*name == '\0') owner = ANY_OWNER; else if (*name == '#') { owner = atoi(&name[1]); if (!GoodObject(owner)) owner = NOTHING; else if (Typeof(owner) != TYPE_PLAYER) owner = NOTHING; } else if (strcasecmp(name, "me") == 0) owner = player; else owner = lookup_player(name); if (owner == NOTHING) { notify(player, tprintf("%s: No such player.", name)); return; } if (!Search_All(player)) { if (owner != ANY_OWNER && owner != player) { notify(player, "You need a search warrant to do that!"); return; } } si = get_stats(player, owner); if (owner == ANY_OWNER) { notify(player, tprintf("%d objects = %d rooms, %d exits, %d things, %d players, %d garbage.", si->total, si->rooms, si->exits, si->things, si->players, si->garbage)); } else { notify(player, tprintf("%d objects = %d rooms, %d exits, %d things, %d players.", si->total - si->garbage, si->rooms, si->exits, si->things, si->players)); } #ifdef MEM_CHECK if (God(player)) list_mem_check(player); #endif #ifdef USE_SMALLOC #ifdef SLOW_STATISTICS if (God(player)) dump_malloc_data(player); #endif #endif #ifdef WIN32 if (Wizard(player)) Win32stats(player); #endif #if defined(DEBUG) && defined(USE_SMALLOC) if (Hasprivs(player)) notify(player, tprintf("%d bytes memory used.", memused())); if (God(player)) verify_sfltable(player); #endif } void do_toad(player, name) dbref player; const char *name; { dbref victim; char tbuf1[BUFFER_LEN]; ATTR *atemp; char alias[PLAYER_NAME_LIMIT]; DESC *d; if (!Wizard(player)) { notify(player, "Only a Wizard can toad a person."); return; } if ((victim = noisy_match_result(player, name, TYPE_PLAYER, MAT_LIMITED)) == NOTHING) return; if (Typeof(victim) != TYPE_PLAYER) { notify(player, "Try @destroy instead!"); } else if (Wizard(victim)) { notify(player, "You can't toad a Wizard."); } else if (db[victim].contents != NOTHING) { notify(player, "You need to destroy their contents first."); } else { /* we're ok */ /* notify people */ notify(victim, "You have been turned into a slimy toad."); notify(player, tprintf("You toaded %s!", db[victim].name)); do_log(LT_WIZ, player, victim, "*** TOAD ***"); /* do it */ atr_clr(victim, "XYXXY", GOD); db[victim].flags = TYPE_THING; db[victim].owner = player; /* you get it */ s_Pennies(victim, 1); #ifdef USE_MAILER do_mail_clear(victim, NULL); #endif /* reset name */ delete_player(victim, NULL); if ((atemp = atr_get_noparent(victim, "ALIAS")) != NULL) { strcpy(alias, uncompress(atemp->value)); delete_player(victim, alias); } while ((d = player_desc(victim))) boot_desc(d); sprintf(tbuf1, "A wart toad named %s", db[victim].name); SET(db[victim].name, tbuf1); do_chownall(player, name, ""); } } void do_newpassword(player, name, password) dbref player; const char *name; const char *password; { dbref victim; if (!Wizard(player)) { notify(player, "Your delusions of grandeur have been duly noted."); 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."); } else if (God(victim) && !God(player)) { notify(player, "You cannot change that player's password."); } else { /* it's ok, do it */ atr_add(victim, "XYXXY", mush_crypt(password), GOD, NOTHING); notify(player, "Password changed."); notify(victim, tprintf("Your password has been changed by %s.", db[player].name)); do_log(LT_WIZ, player, victim, "*** NEWPASSWORD ***"); } } void do_boot(player, name, flag) dbref player; const char *name; int flag; /* 0, normal boot. 1, descriptor boot */ /* 2, self boot */ { dbref victim; #ifdef CONCENTRATOR int cport, port; #endif DESC *d = NULL; victim = NOTHING; switch (flag) { case 2: /* self boot */ victim = player; break; case 1: /* boot by descriptor */ #ifdef CONCENTRATOR if (!parse_conc_descriptor(name, &cport, &port)) { notify(player, "Invalid descriptor specification (use d,d)."); return; } victim = find_player_by_desc(cport, port); #else victim = find_player_by_desc(atoi(name)); #endif if (victim == NOTHING) { notify(player, "There is no one connected on that descriptor."); return; } break; case 0: /* boot by name */ if ((victim = noisy_match_result(player, name, TYPE_PLAYER, MAT_LIMITED | MAT_ME)) == NOTHING) { notify(player, "No such connected player."); return; } if (victim == player) flag = 2; break; } if ((victim != player) && !Can_Boot(player)) { notify(player, "You can't boot other people!"); return; } if (God(victim) && !God(player)) { notify(player, "You're good. That's spelled with two 'o's."); return; } /* look up descriptor */ switch (flag) { case 0: d = player_desc(victim); break; case 1: #ifdef CONCENTRATOR d = port_desc(cport, port); #else d = port_desc(atoi(name)); #endif break; case 2: d = inactive_desc(victim); break; } /* check for more errors */ if (!d) if (flag == 2) notify(player, "None of your connections has been idle."); else notify(player, "That player isn't connected!"); else if (d == cdesc) notify(player, tprintf("Try %s instead.", QUIT_COMMAND)); else { do_log(LT_WIZ, player, victim, "*** BOOT ***"); if (flag == 2) notify(player, "You boot an idle self."); else { notify(player, tprintf("You booted %s off!", db[victim].name)); notify(victim, "You are politely shown to the door."); } boot_desc(d); } } #ifdef CONCENTRATOR int parse_conc_descriptor(str, cport, port) char *str; int *cport; int *port; { char *p, *q; p = str; q = str; while (p && *p && (*p != ',')) p++; if (!p || !*p) return 0; *p = 0; if (!(p + 1) || !*(p + 1)) return 0; *cport = atoi(q); *port = atoi(p + 1); return 1; } #endif /* CONCENTRATOR */ void do_chownall(player, name, target) dbref player; const char *name; const char *target; { int i; dbref victim; dbref n_target; int count = 0; if (!Wizard(player)) { notify(player, "Try asking them first!"); return; } if ((victim = noisy_match_result(player, name, TYPE_PLAYER, MAT_LIMITED)) == NOTHING) return; if (!target || !*target) { n_target = player; } else { if ((n_target = noisy_match_result(player, target, TYPE_PLAYER, MAT_LIMITED)) == NOTHING) return; } for (i = 0; i <= db_top; i++) { if ((db[i].owner == victim) && (Typeof(i) != TYPE_PLAYER)) { db[i].owner = n_target; count++; } } #ifdef QUOTA /* change quota (this command is wiz only and we can assume that * we intend for the recipient to get all the objects, so we * don't do a quota check earlier. */ change_quota(victim, count); change_quota(n_target, -count); #endif notify(player, tprintf("Ownership changed for %d objects.", count)); } void do_chzoneall(player, name, target) dbref player; const char *name; const char *target; { int i; dbref victim; dbref zone; int count = 0; if (!Wizard(player)) { notify(player, "You do not have the power to change reality."); return; } if ((victim = noisy_match_result(player, name, TYPE_PLAYER, MAT_LIMITED)) == NOTHING) return; if (!target || !*target) { notify(player, "No zone specified."); return; } if (!strcasecmp(target, "none")) zone = NOTHING; else { switch (zone = match_result(player, target, TYPE_THING, MAT_LIMITED)) { case NOTHING: notify(player, "I can't seem to find that."); return; case AMBIGUOUS: notify(player, "I don't know which one you mean!"); return; } if (Typeof(zone) != TYPE_THING) { notify(player, "Invalid zone object type."); return; } } for (i = 0; i <= db_top; i++) { if (db[i].owner == victim) { db[i].zone = zone; count++; } } notify(player, tprintf("Zone changed for %d objects.", count)); } void do_enable(player, param, state) dbref player; const char *param; int state; /* enable is 1, disable is 0 */ { const char *name; if (!Wizard(player)) { notify(player, "Unable to authenticate you, sorry."); return; } if (!strcasecmp(param, "pueblo")) { name = "PUEBLO"; options.support_pueblo = state; } else if (!strcasecmp(param, "logins")) { name = "LOGINS"; options.login_allow = state; } else if (!strcasecmp(param, "daytime")) { name = "DAYTIME"; options.daytime = state; } else if (!strcasecmp(param, "command_log")) { name = "LOG COMMANDS"; options.log_commands = state; } else if (!strcasecmp(param, "huh_log")) { name = "LOG HUHS"; options.log_huhs = state; } else if (!strcasecmp(param, "force_log")) { name = "LOG FORCES"; options.log_forces = state; } else if (!strcasecmp(param, "wall_log")) { name = "LOG WIZWALLS"; options.log_walls = state; } else if (!strcasecmp(param, "guests")) { name = "GUEST LOGINS"; options.guest_allow = state; } else if (!strcasecmp(param, "creation")) { name = "PLAYER CREATION"; options.create_allow = state; } else { notify(player, "Unknown parameter."); return; } if (state == 0) notify(player, "Disabled."); else notify(player, "Enabled."); do_log(LT_WIZ, player, NOTHING, "%s %s", name, (state) ? "ENABLED" : "DISABLED"); } /*----------------------------------------------------------------------- * Nasty management: @kick, examine/debug, and @fixdb */ void do_kick(player, num) dbref player; const char *num; { /* executes <num> commands off the queue immediately */ int n; if (!Wizard(player)) { notify(player, "Permission denied."); return; } if (!num || !*num) { notify(player, "How many commands do you want to execute?"); return; } n = atoi(num); if (n <= 0) { notify(player, "Number out of range."); return; } n = do_top(n); notify(player, tprintf("%d commands executed.", n)); } void do_fixdb(player, name, val, sw_opt) dbref player; const char *name; const char *val; int sw_opt; { dbref thing; dbref new; /* do all the checks */ if (!Wizard(player)) { notify(player, "Reality is not yours to warp."); return; } if (!name || !*name) { notify(player, "You must specify an object."); return; } if (!val || !*val) { notify(player, "You must specify a value."); return; } if (!is_strict_number(val)) { notify(player, "The value must be an integer."); return; } /* find the object */ thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING); if (thing == NOTHING) return; /* change the pointers. Do no error checking. */ new = atoi(val); switch (sw_opt) { case 0: db[thing].location = new; break; case 1: db[thing].contents = new; break; case 2: db[thing].exits = new; break; case 3: db[thing].next = new; break; } notify(player, "Fixed."); } void do_debug_examine(player, name) dbref player; const char *name; { #ifdef USE_MAILER struct mail *mp; #endif dbref thing; if (!Hasprivs(player)) { notify(player, "Permission denied."); return; } /* find it */ thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING); if (!GoodObject(thing)) return; notify(player, object_header(player, thing)); notify(player, tprintf("Flags value: 0x%08x", Flags(thing))); notify(player, tprintf("Toggles value: 0x%08x", Toggles(thing))); notify(player, tprintf("Powers value: 0x%08x", Powers(thing))); notify(player, tprintf("Next: %d", db[thing].next)); notify(player, tprintf("Contents: %d", db[thing].contents)); switch (Typeof(thing)) { case TYPE_PLAYER: #ifdef USE_MAILER mp = desc_mail(thing); notify(player, tprintf("First mail sender: %d", mp ? mp->from : NOTHING)); #endif case TYPE_THING: notify(player, tprintf("Location: %d", db[thing].location)); notify(player, tprintf("Home: %d", db[thing].exits)); break; case TYPE_EXIT: notify(player, tprintf("Destination: %d", db[thing].location)); notify(player, tprintf("Source: %d", db[thing].exits)); break; case TYPE_ROOM: notify(player, tprintf("Drop-to: %d", db[thing].location)); notify(player, tprintf("Exits: %d", db[thing].exits)); break; case TYPE_GARBAGE: break; default: notify(player, "Bad object type."); } } /*------------------------------------------------------------------------- * Powers stuff */ #ifdef WIN32 #pragma warning( disable : 4761) /* Disable bogus conversion warning */ #endif /* ARGSUSED */ FUNCTION(fun_haspower) { dbref it; object_flag_type pwr; it = match_thing(executor, args[0]); if (it == NOTHING) { safe_str("#-1", buff, bp); return; } if (HASPOWER_RESTRICTED) if (!Can_Examine(executor, it)) { notify(executor, "We could let you see that, but then we'd have to kill you."); safe_str("#-1", buff, bp); return; } pwr = find_power(args[1]); if (pwr == -1) safe_str("#-1 NO SUCH POWER", buff, bp); else safe_chr((Powers(it) & pwr) ? '1' : '0', buff, bp); } /* ARGSUSED */ FUNCTION(fun_powers) { dbref it; it = match_thing(executor, args[0]); if (it == NOTHING) { safe_str("#-1", buff, bp); return; } if (HASPOWER_RESTRICTED) if (!Can_Examine(executor, it)) { notify(executor, "We could let you see that, but then we'd have to kill you."); safe_str("#-1", buff, bp); return; } safe_str(power_description(it), buff, bp); } #ifdef WIN32 #pragma warning( default : 4761) /* Re-enable conversion warning */ #endif void do_power(player, name, power) dbref player; const char *name; const char *power; { object_flag_type pwr; char *s; dbref thing; if (!Wizard(player)) { notify(player, "Only wizards may grant powers."); return; } if ((thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING)) == NOTHING) return; #ifdef ONLINE_REG if (IS(thing, TYPE_PLAYER, PLAYER_UNREG)) { notify(player, "You can't grant powers to unregistered players."); return; } #endif /* move past the not token if there is one */ for (s = (char *) power; *s && ((*s == NOT_TOKEN) || isspace(*s)); s++) ; if (*s == '\0') { notify(player, "You must specify a power."); return; } pwr = find_power(s); if (pwr == -1) { notify(player, "That is not a power."); return; } if (*power == NOT_TOKEN) { Powers(thing) &= ~pwr; if (!Quiet(player) && !Quiet(thing)) notify(player, tprintf("%s - power removed.", Name(thing))); do_log(LT_WIZ, player, thing, "Power Removed: %s", power); } else { if (Hasprivs(thing) && (pwr == IS_GUEST)) { notify(player, "You can't make admin into guests."); return; } Powers(thing) |= pwr; if (!Quiet(player) && !Quiet(thing)) notify(player, tprintf("%s - power granted.", Name(thing))); do_log(LT_WIZ, player, thing, "Power Granted: %s", power); } } /*---------------------------------------------------------------------------- * Search functions */ void do_search(player, arg1, arg3) dbref player; const char *arg1; char **arg3; { int flag, is_wizard; char *arg2, *restrict_name, *ebuf1, *bp; char const *ebuf2; dbref thing, from, to; int destitute = 1; int eval_search = 0; dbref restrict_owner = NOTHING; dbref restrict_zone = NOTHING; dbref restrict_parent = NOTHING; object_flag_type flag_mask, toggle_mask, restrict_type, power_mask; char tbuf1[BUFFER_LEN]; int rcount, ecount, pcount, ocount; struct dblist *found = NULL, *ptr = NULL, *rlist = NULL, *elist = NULL, *olist = NULL, *plist = NULL; int bot = 0; int top = db_top; if (options.daytime) { notify(player, "Sorry, that command has been temporarily disabled."); return; } /* make sure player has money to do the search */ if (!payfor(player, FIND_COST)) { notify(player, tprintf("Searches cost %d %s.", FIND_COST, ((FIND_COST == 1) ? MONEY : MONIES))); return; } /* parse first argument into two */ if (!arg1 || *arg1 == '\0') arg1 = "me"; arg2 = (char *) index(arg1, ' '); if (arg2 != NULL) *arg2++ = '\0'; /* arg1, arg2, arg3 */ else { if (!arg3[1] || !*arg3[1]) arg2 = (char *) ""; /* arg1 */ else { arg2 = (char *) arg1; /* arg2, arg3 */ arg1 = (char *) ""; } } is_wizard = Search_All(player) || See_All(player); /* set limits on who we search */ if (*arg1 == '\0') { restrict_owner = is_wizard ? ANY_OWNER : player; } else if (arg1[0] == '#') { restrict_owner = atoi(&arg1[1]); if (!GoodObject(restrict_owner)) restrict_owner = NOTHING; else if (Typeof(restrict_owner) != TYPE_PLAYER) restrict_owner = NOTHING; } else if (strcmp(arg1, "me") == 0) { restrict_owner = player; } else { restrict_owner = lookup_player(arg1); } if (restrict_owner == NOTHING) { notify(player, tprintf("%s: No such player.", arg1)); return; } /* set limits on what we search for */ flag = flag_mask = power_mask = toggle_mask = 0; restrict_name = NULL; restrict_type = NOTYPE; switch (arg2[0]) { case '\0': /* the no class requested class :) */ break; case 'e': case 'E': if (string_prefix("exits", arg2)) { restrict_name = (char *) arg3[1]; restrict_type = TYPE_EXIT; } else if (string_prefix("eval", arg2)) { eval_search = 1; } else { flag = 1; } break; case 'f': case 'F': if (string_prefix("flags", arg2)) { /* * convert_flags ignores previous values of flag_mask and * restrict_type while setting them */ if (arg3[1] && *arg3[1] && !convert_flags(player, arg3[1], &flag_mask, &toggle_mask, &restrict_type)) return; } else flag = 1; break; case 'n': case 'N': if (string_prefix("name", arg2)) restrict_name = (char *) arg3[1]; else flag = 1; break; case 'o': case 'O': if (string_prefix("objects", arg2)) { restrict_name = (char *) arg3[1]; restrict_type = TYPE_THING; } else flag = 1; break; case 'p': case 'P': switch (arg2[1]) { case 'a': case 'A': if (string_prefix("parent", arg2)) { if (arg3[1] && *arg3[1]) { restrict_parent = match_result(player, arg3[1], NOTYPE, MAT_ABSOLUTE); } if (restrict_parent == NOTHING) { notify(player, "Unknown parent."); return; } } else flag = 1; break; case 'l': case 'L': if (string_prefix("players", arg2)) { restrict_name = (char *) arg3[1]; if (!arg1 || !*arg1) restrict_owner = ANY_OWNER; restrict_type = TYPE_PLAYER; } else flag = 1; break; case 'o': case 'O': if (string_prefix("powers", arg2)) { power_mask = find_power(arg3[1]); if (power_mask == -1) { notify(player, "No such power to search for."); return; } } else flag = 1; break; default: flag = 1; } break; case 'r': case 'R': if (string_prefix("rooms", arg2)) { restrict_name = (char *) arg3[1]; restrict_type = TYPE_ROOM; } else flag = 1; break; case 't': case 'T': switch (arg2[1]) { case 'h': case 'H': if (string_prefix("things", arg2)) { restrict_name = (char *) arg3[1]; restrict_type = TYPE_THING; } else flag = 1; break; case 'y': case 'Y': if (string_prefix("type", arg2)) { if (!arg3[1] || !*arg3[1]) break; if (string_prefix("room", arg3[1])) restrict_type = TYPE_ROOM; else if (string_prefix("exit", arg3[1])) restrict_type = TYPE_EXIT; else if (string_prefix("object", arg3[1])) restrict_type = TYPE_THING; else if (string_prefix("thing", arg3[1])) restrict_type = TYPE_THING; else if (string_prefix("player", arg3[1])) { if (!arg1 || !*arg1) restrict_owner = ANY_OWNER; restrict_type = TYPE_PLAYER; } else { notify(player, tprintf("%s: unknown type.", arg3[1])); return; } } else flag = 1; break; default: flag = 1; break; } break; case 'z': case 'Z': if (string_prefix("zone", arg2)) { if (arg3[1] && *arg3[1]) { restrict_zone = match_result(player, arg3[1], TYPE_THING, MAT_ABSOLUTE); } if (restrict_zone == NOTHING) { notify(player, "Unknown zone."); return; } } else flag = 1; break; default: flag = 1; } if (flag) { notify(player, tprintf("%s: unknown class.", arg2)); return; } /* make sure player is authorized to do requested search */ if (!is_wizard && restrict_type != TYPE_PLAYER && (restrict_owner == ANY_OWNER || restrict_owner != player)) { notify(player, "You need a search warrant to do that!"); return; } /* find range */ if (arg3[2] && *arg3[2]) bot = atoi(arg3[2]); if (bot < 0) bot = 0; if (arg3[3] && *arg3[3]) top = atoi(arg3[3]) + 1; if (top > db_top) top = db_top; /* the search loop here */ flag = 1; for (thing = bot; thing < top; thing++) { switch (Typeof(thing)) { case TYPE_PLAYER: found = plist; break; case TYPE_EXIT: found = elist; break; case TYPE_THING: found = olist; break; case TYPE_ROOM: found = rlist; break; default: continue; } if (Destroyed(thing)) continue; if ((restrict_owner != ANY_OWNER) && (restrict_owner != Owner(thing))) continue; if (!eval_search) { if (restrict_type != NOTYPE && restrict_type != Typeof(thing)) continue; if ((Flags(thing) & flag_mask) != flag_mask) continue; if ((Toggles(thing) & toggle_mask) != toggle_mask) continue; if ((Powers(thing) & power_mask) != power_mask) continue; if ((restrict_name != NULL) && !string_match(Name(thing), restrict_name)) continue; if ((restrict_parent != NOTHING) && (restrict_parent != Parent(thing))) continue; if ((restrict_zone != NOTHING) && (restrict_zone != Zone(thing))) continue; } else { ebuf1 = replace_string("##", tprintf("#%d", thing), arg3[1]); ebuf2 = ebuf1; bp = tbuf1; process_expression(tbuf1, &bp, &ebuf2, player, player, player, PE_DEFAULT, PT_DEFAULT, NULL); mush_free((Malloc_t) ebuf1, "replace_string.buff"); *bp = '\0'; if (*tbuf1 != '1' || tbuf1[1]) continue; } if (!found) { flag = 0; destitute = 0; found = listcreate(thing); } else listadd(found, thing); switch (Typeof(thing)) { case TYPE_PLAYER: plist = found; break; case TYPE_EXIT: elist = found; break; case TYPE_THING: olist = found; break; case TYPE_ROOM: rlist = found; break; default: break; } } /* if nothing found matching search criteria */ if (destitute) { notify(player, "Nothing found."); return; } /* Walk down the list and print */ rcount = ecount = pcount = ocount = 0; if (restrict_type == TYPE_ROOM || restrict_type == NOTYPE) { notify(player, "\nROOMS:"); for (ptr = rlist; ptr; ptr = ptr->next) { sprintf(tbuf1, "%s [owner: ", object_header(player, ptr->obj)); strcat(tbuf1, tprintf("%s]", object_header(player, db[ptr->obj].owner))); notify(player, tbuf1); rcount++; } } if (restrict_type == TYPE_EXIT || restrict_type == NOTYPE) { notify(player, "\nEXITS:"); for (ptr = elist; ptr; ptr = ptr->next) { if (db[ptr->obj].exits == NOTHING) from = find_entrance(thing); else from = db[ptr->obj].exits; to = db[ptr->obj].location; sprintf(tbuf1, "%s [from ", object_header(player, ptr->obj)); strcat(tbuf1, tprintf("%s to ", (from == NOTHING) ? "NOWHERE" : object_header(player, from))); strcat(tbuf1, tprintf("%s]", (to == NOTHING) ? "NOWHERE" : object_header(player, to))); notify(player, tbuf1); ecount++; } } if (restrict_type == TYPE_THING || restrict_type == NOTYPE) { notify(player, "\nOBJECTS:"); for (ptr = olist; ptr; ptr = ptr->next) { sprintf(tbuf1, "%s [owner: ", object_header(player, ptr->obj)); strcat(tbuf1, tprintf("%s]", object_header(player, db[ptr->obj].owner))); notify(player, tbuf1); ocount++; } } if ((restrict_type == TYPE_PLAYER) || (restrict_type == NOTYPE)) { notify(player, "\nPLAYERS:"); for (ptr = plist; ptr; ptr = ptr->next) { strcpy(tbuf1, object_header(player, ptr->obj)); if (is_wizard) { strcat(tbuf1, " [location: "); strcat(tbuf1, object_header(player, db[ptr->obj].location)); strcat(tbuf1, "]"); } notify(player, tbuf1); pcount++; } } notify(player, "---------- Search Done ----------"); notify(player, tprintf("Totals: Rooms...%d Exits...%d Objects...%d Players...%d", rcount, ecount, ocount, pcount)); if (plist) listfree(plist); if (rlist) listfree(rlist); if (olist) listfree(olist); if (elist) listfree(elist); } #ifdef WIN32 #pragma warning( disable : 4761) /* Disable bogus conversion warning */ #endif /* ARGSUSED */ FUNCTION(fun_hidden) { dbref it = match_thing(executor, args[0]); if (!See_All(executor)) { notify(executor, "Permission denied."); safe_str("#-1", buff, bp); return; } if ((it == NOTHING) || (Typeof(it) != TYPE_PLAYER)) { notify(executor, "Couldn't find that player."); safe_str("#-1", buff, bp); return; } safe_chr(hidden(it) ? '1' : '0', buff, bp); return; } #ifdef WIN32 #pragma warning( default : 4761) /* Re-enable conversion warning */ #endif /* ARGSUSED */ FUNCTION(fun_lsearch) { /* takes arguments in the form of: player, class, restriction */ int flag, is_wiz; char *who, *class, *res, *restrict_name, *ebuf1, *tp; char const *ebuf2; char tbuf1[BUFFER_LEN]; object_flag_type flag_mask, toggle_mask, restrict_type, power_mask; dbref restrict_owner = NOTHING; dbref restrict_zone = NOTHING; dbref restrict_parent = NOTHING; dbref thing; int destitute = 1; int eval_search = 0; int bot = 0; int top = db_top; int rev = strcmp(called_as, "LSEARCH"); if (options.daytime) { notify(executor, "Function disabled."); strcpy(buff, "#-1"); return; } if (!payfor(executor, FIND_COST)) { notify(executor, "Not enough money to do search."); strcpy(buff, "#-1"); return; } is_wiz = Search_All(executor) || See_All(executor); who = args[0]; class = args[1]; res = args[2]; if (nargs > 3) bot = parse_integer(args[3]); if (nargs > 4) top = parse_integer(args[4]) + 1; if (!GoodObject(bot)) bot = 0; if (!GoodObject(top)) top = db_top; /* set limits on who we search */ if (!strcasecmp(who, "all")) restrict_owner = is_wiz ? ANY_OWNER : executor; else if (!strcasecmp(who, "me")) restrict_owner = executor; else restrict_owner = lookup_player(who); if (restrict_owner == NOTHING) { notify(executor, "No such player."); safe_str("#-1", buff, bp); return; } /* set limits on what we search for */ flag = 0; flag_mask = 0; toggle_mask = 0; power_mask = 0; restrict_name = NULL; restrict_type = NOTYPE; switch (class[0]) { case 'e': case 'E': if (string_prefix("exits", class)) { restrict_name = (char *) res; restrict_type = TYPE_EXIT; } else if (string_prefix("eval", class)) { eval_search = 1; } else flag = 1; break; case 'f': case 'F': if (string_prefix("flags", class)) { if (!convert_flags(executor, res, &flag_mask, &toggle_mask, &restrict_type)) { notify(executor, "Unknown flag."); safe_str("#-1", buff, bp); return; } } else flag = 1; break; case 'n': case 'N': if (string_prefix("name", class)) restrict_name = (char *) res; else if (!string_prefix("none", class)) flag = 1; break; case 'o': case 'O': if (string_prefix("objects", class)) { restrict_name = (char *) res; restrict_type = TYPE_THING; } else flag = 1; break; case 'p': case 'P': switch (class[1]) { case 'a': case 'A': if (string_prefix("parent", class)) { restrict_parent = match_result(executor, res, NOTYPE, MAT_ABSOLUTE); if (restrict_parent == NOTHING) { notify(executor, "Unknown parent."); safe_str("#-1", buff, bp); return; } } else flag = 1; break; case 'l': case 'L': if (string_prefix("players", class)) { restrict_name = (char *) res; restrict_type = TYPE_PLAYER; } else flag = 1; break; case 'o': case 'O': if (string_prefix("powers", class)) { power_mask = find_power(res); if (power_mask == -1) { notify(executor, "Unknown power."); safe_str("#-1", buff, bp); return; } } else flag = 1; break; default: flag = 1; } break; case 'r': case 'R': if (string_prefix("rooms", class)) { restrict_name = (char *) res; restrict_type = TYPE_ROOM; } else flag = 1; break; case 't': case 'T': if (string_prefix("type", class)) { if (!strcasecmp(res, "none")) break; if (string_prefix("room", res)) restrict_type = TYPE_ROOM; else if (string_prefix("exit", res)) restrict_type = TYPE_EXIT; else if (string_prefix("object", res)) restrict_type = TYPE_THING; else if (string_prefix("player", res)) restrict_type = TYPE_PLAYER; else { notify(executor, "Unknown type."); strcpy(buff, "#-1"); return; } } else flag = 1; break; case 'z': case 'Z': if (string_prefix("zone", class)) { restrict_zone = match_result(executor, res, TYPE_THING, MAT_ABSOLUTE); if (restrict_zone == NOTHING) { notify(executor, "Unknown zone."); strcpy(buff, "#-1"); return; } } else flag = 1; break; default: flag = 1; } if (flag) { notify(executor, "Unknown type."); safe_str("#-1", buff, bp); return; } /* check privs */ if (!is_wiz && (restrict_type != TYPE_PLAYER) && ((restrict_owner == ANY_OWNER) || (restrict_owner != executor))) { notify(executor, "Permission denied."); safe_str("#-1", buff, bp); return; } /* search loop */ flag = 1; for (rev ? (thing = top - 1) : (thing = bot); rev ? (thing >= bot) : (thing < top); rev ? (thing--) : (thing++)) { if (Destroyed(thing)) continue; if ((restrict_owner != ANY_OWNER) && (restrict_owner != Owner(thing))) continue; if (!eval_search) { if ((restrict_type != NOTYPE) && (restrict_type != Typeof(thing))) continue; if ((Flags(thing) & flag_mask) != flag_mask) continue; if ((Toggles(thing) & toggle_mask) != toggle_mask) continue; if ((Powers(thing) & power_mask) != power_mask) continue; if ((restrict_name != NULL) && (!string_match(Name(thing), restrict_name))) continue; if ((restrict_parent != NOTHING) && (restrict_parent != Parent(thing))) continue; if ((restrict_zone != NOTHING) && (restrict_zone != Zone(thing))) continue; } else { ebuf1 = replace_string("##", tprintf("#%d", thing), res); ebuf2 = ebuf1; tp = tbuf1; process_expression(tbuf1, &tp, &ebuf2, executor, caller, enactor, PE_DEFAULT, PT_DEFAULT, pe_info); mush_free((Malloc_t) ebuf1, "replace_string.buff"); *tp = '\0'; if (*tbuf1 != '1' || tbuf1[1]) continue; } if (destitute) { safe_str(unparse_dbref(thing), buff, bp); destitute = 0; } else { safe_chr(' ', buff, bp); safe_str(unparse_dbref(thing), buff, bp); } } /* nothing found matching search criteria */ if (destitute) { notify(executor, "Nothing found."); safe_str("#-1", buff, bp); return; } } #ifdef QUOTA /* ARGSUSED */ FUNCTION(fun_quota) { int owned; /* Tell us player's quota */ dbref thing; dbref who = lookup_player(args[0]); if ((who == NOTHING) || (Typeof(who) != TYPE_PLAYER)) { notify(executor, "Couldn't find that player."); safe_str("#-1", buff, bp); return; } if (!(Do_Quotas(executor) || See_All(executor) || (who == executor))) { notify(executor, "You can't see someone else's quota!"); safe_str("#-1", buff, bp); return; } if (NoQuota(who)) { /* Unlimited, but return a big number to be sensible */ safe_str("99999", buff, bp); return; } /* count up all owned objects */ owned = -1; /* a player is never included in his own * quota */ for (thing = 0; thing < db_top; thing++) { if (db[thing].owner == who) if (!Destroyed(thing)) ++owned; } safe_str(unparse_integer(owned + get_current_quota(who)), buff, bp); return; } #endif void do_sitelock(player, site, opts, type) dbref player; const char *site; const char *opts; int type; /* 0 = registration, 1 = siteban, 2 = names */ { FILE *fp; char buffer[80]; char *p; if (!Wizard(player)) { notify(player, "Your delusions of grandeur have been noted."); return; } if (opts && *opts) { int can, cant; /* Options form of the command. */ if (!site || !*site) { notify(player, "What site did you want to lock?"); return; } can = cant = 0; if (!parse_access_options(opts, &can, &cant, player)) { notify(player, "No valid options found."); return; } add_access_sitelock(player, site, can, cant); /* HERE */ write_access_file(); notify(player, tprintf("Site %s access options set to %s", site, opts)); do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s --> %s", site, opts); return; } else { /* Backward-compatible non-options form of the command, * or @sitelock/name */ switch (type) { case 0: case 1: if (!site || !*site) { /* List bad sites */ do_list_access(player); return; } /* Add a site */ if (type == 0) add_access_sitelock(player, site, 0, ACS_CREATE); else add_access_sitelock(player, site, 0, ACS_DEFAULT); write_access_file(); notify(player, tprintf("Site %s locked", site)); do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site); break; case 2: if (!site || !*site) { /* List bad names */ #ifndef WIN32 close(reserved); #endif if ((fp = fopen(NAMES_FILE, "r")) == NULL) { notify(player, "Unable to open names file."); } else { while (!feof(fp)) { fgets(buffer, 79, fp); if ((p = strrchr(buffer, '\n'))) /* extra parens for gcc */ *p = '\0'; notify(player, buffer); } fclose(fp); } #ifndef WIN32 reserved = open("/dev/null", O_RDWR); #endif return; } /* Add a name */ #ifndef WIN32 close(reserved); #endif if ((fp = fopen(NAMES_FILE, "a")) != NULL) { /* Put a newline at the end of the site */ fprintf(fp, "%s\n", site); fclose(fp); notify(player, tprintf("Name %s locked", site)); do_log(LT_WIZ, player, NOTHING, "*** NAMELOCK *** %s", site); } else { notify(player, "Error writing to file."); } #ifndef WIN32 reserved = open("/dev/null", O_RDWR); #endif break; } } } /*----------------------------------------------------------------- * Functions which give memory information on objects or players. * Source code originally by Kalkin, modified by Javelin */ static int mem_usage(thing) dbref thing; { int k; ATTR *m; lock_list *l; k = sizeof(struct object); /* overhead */ k += strlen(db[thing].name) + 1; /* The name */ for (m = db[thing].list; m; m = AL_NEXT(m)) { k += sizeof(ATTR); if (!(AL_FLAGS(m) & AF_STATIC)) k += strlen(AL_NAME(m)) + 1; if (*AL_STR(m)) k += strlen(AL_STR(m)) + 1; /* NOTE! In the above, we're getting the size of the * compressed attrib, not the uncompressed one (as Kalkin did) * because (1) it's more efficient, (2) it's more accurate * since that's how the object is in memory. This relies on * compressed attribs being terminated with \0's, which they * are in compress.c. If that changes, this breaks. */ } for (l = Locks(thing); l; l = l->next) { k += sizeof(lock_list); if (!match_lock(l->type)) k += strlen(l->type) + 1; k += sizeof_boolexp(l->key); } return k; } /* ARGSUSED */ FUNCTION(fun_objmem) { dbref thing; if (!Search_All(executor)) { safe_str("#-1 PERMISSION DENIED", buff, bp); return; } if (!strcasecmp(args[0], "me")) thing = executor; else if (!strcasecmp(args[0], "here")) thing = Location(executor); else { thing = noisy_match_result(executor, args[0], NOTYPE, MAT_OBJECTS); } if (!GoodObject(thing) || !Can_Examine(executor, thing)) { safe_str("#-1 PERMISSION DENIED", buff, bp); return; } safe_str(unparse_integer(mem_usage(thing)), buff, bp); } /* ARGSUSED */ FUNCTION(fun_playermem) { int tot = 0; dbref thing; dbref j; if (options.daytime) { notify(executor, "Function disabled."); safe_str("#-1", buff, bp); return; } if (!Search_All(executor)) { safe_str("#-1 PERMISSION DENIED", buff, bp); return; } if (!strcasecmp(args[0], "me") && (Typeof(executor) == TYPE_PLAYER)) thing = executor; else if (*args[0] && *args[0] == '*') thing = lookup_player(args[0] + 1); else if (*args[0] && *args[0] == '#') thing = atoi(args[0] + 1); else thing = lookup_player(args[0]); if (!GoodObject(thing) || !Can_Examine(executor, thing)) { safe_str("#-1 PERMISSION DENIED", buff, bp); return; } for (j = 0; j < db_top; j++) if (Owner(j) == thing) tot += mem_usage(j); safe_str(unparse_integer(tot), buff, bp); } #ifdef WIN32 void Win32stats(dbref player) { /* written by NJG */ MEMORYSTATUS memstat; double mem; #if (COMPRESSION_TYPE == 3) long items, used, total_comp, total_uncomp; double percent; #endif memstat.dwLength = sizeof(memstat); GlobalMemoryStatus(&memstat); notify(player, "---------- Windows memory usage ------------"); notify(player, tprintf("%10ld %% memory in use", memstat.dwMemoryLoad)); mem = memstat.dwAvailPhys / 1024.0 / 1024.0; notify(player, tprintf("%10.3f Mb free physical memory", mem)); mem = memstat.dwTotalPhys / 1024.0 / 1024.0; notify(player, tprintf("%10.3f Mb total physical memory", mem)); mem = memstat.dwAvailPageFile / 1024.0 / 1024.0; notify(player, tprintf("%10.3f Mb available in the paging file ", mem)); mem = memstat.dwTotalPageFile / 1024.0 / 1024.0; notify(player, tprintf("%10.3f Mb total paging file size", mem)); #if (COMPRESSION_TYPE == 3) compress_stats(&items, &used, &total_uncomp, &total_comp); notify(player, "---------- Internal attribute compression ----------"); notify(player, tprintf("%10ld compression table items used, " "taking %ld bytes.", items, used)); notify(player, tprintf("%10ld bytes in text before compression. ", total_uncomp)); notify(player, tprintf("%10ld bytes in text AFTER compression. ", total_comp)); percent = ((float) (total_comp)) / ((float) total_uncomp) * 100.0; notify(player, tprintf("%10.0f %% text compression ratio (lower is better). ", percent)); percent = ((float) (total_comp + used + (32768L * sizeof(char *)))) / ((float) total_uncomp) * 100.0; notify(player, tprintf("%10.0f %% OVERALL compression ratio (lower is better). ", percent)); notify(player, tprintf(" (Includes table items, and table of words pointers of %ld bytes)", 32768L * sizeof(char *))); if (percent >= 100.0) notify(player, " " "(Compression ratio improves with larger database)"); #endif } /* end of calc_memory_used */ #endif /* * --------------------------------------------------------------------------- * do_reboot: Reboots the game w/o disconnecting players. */ void do_reboot(player, flag) dbref player; int flag; /* 0 = normal, 1 = paranoid */ { #ifdef WIN32 notify(player, "Alas, I can't reboot under Windows. Sorry."); #else if (player == NOTHING) { flag_broadcast(0, 0, "GAME: Reboot w/o disconnect from game account, please wait."); } else { if (!Wizard(player)) { notify(player, "You don't have the authority to do that!"); return; } flag_broadcast(0, 0, "GAME: Reboot w/o disconnect by %s, please wait.", Name(Owner(player))); } if (flag) { paranoid_dump = 1; paranoid_checkpt = db_top / 5; if (paranoid_checkpt < 1) paranoid_checkpt = 1; } fork_and_dump(0); alarm(0); dump_reboot_db(); #ifdef INFO_SLAVE kill_info_slave(); #endif #ifndef SINGLE_LOGFILE /* close up the log files */ end_log(connlog_fp); end_log(checklog_fp); end_log(wizlog_fp); end_log(tracelog_fp); end_log(cmdlog_fp); #endif /* SINGLE_LOGFILE */ execl("netmush", "netmush", confname, errlog, NULL); #endif /* WIN32 */ }