/* wiz.c - Wizard-only commands */ /* $Id: wiz.c,v 1.34 2003/07/14 18:55:22 lwl Exp $ */ #include "copyright.h" #include "autoconf.h" #include "config.h" #include "alloc.h" /* required by mudconf */ #include "flags.h" /* required by mudconf */ #include "htab.h" /* required by mudconf */ #include "mudconf.h" /* required by code */ #include "db.h" /* required by externs */ #include "externs.h" /* required by interface */ #include "interface.h" /* required by code */ #include "file_c.h" /* required by code */ #include "match.h" /* required by code */ #include "command.h" /* required by code */ #include "attrs.h" /* required by code */ #include "powers.h" /* required by code */ void do_teleport(player, cause, key, arg1, arg2) dbref player, cause; int key; char *arg1, *arg2; { dbref victim, destination, loc, exitloc; char *to; int hush = 0; if (((Fixed(player)) || (Fixed(Owner(player)))) && !(Tel_Anywhere(player))) { notify(player, mudconf.fixed_tel_msg); return; } /* get victim */ if (*arg2 == '\0') { victim = player; to = arg1; } else { init_match(player, arg1, NOTYPE); match_everything(0); victim = noisy_match_result(); if (victim == NOTHING) return; to = arg2; } /* Validate type of victim */ if (!Has_location(victim) && !isExit(victim)) { notify_quiet(player, "You can't teleport that."); return; } /* If this is an exit, we need to control it, or it must be * unlinked. (Same permissions as @link.) Or, we can control * the room. (Same permissions as get.) * Otherwise, fail if we're not Tel_Anything, and we don't control * the victim or the victim's location. */ if (isExit(victim)) { if ((Location(victim) != NOTHING) && !Controls(player, victim) && !Controls(player, Exits(victim))) { notify_quiet(player, NOPERM_MESSAGE); return; } } else if (!Controls(player, victim) && !Controls(player, Location(victim)) && !Tel_Anything(player)) { notify_quiet(player, NOPERM_MESSAGE); return; } /* * Check for teleporting home. Exits don't have homes. */ if (!string_compare(to, "home")) { if (isExit(victim)) notify_quiet(player, NOPERM_MESSAGE); else move_via_teleport(victim, HOME, cause, 0); return; } /* * Find out where to send the victim */ init_match(player, to, NOTYPE); match_everything(0); destination = match_result(); switch (destination) { case NOTHING: notify_quiet(player, "No match."); return; case AMBIGUOUS: notify_quiet(player, "I don't know which destination you mean!"); return; default: if ((victim == destination) || Going(destination)) { notify_quiet(player, "Bad destination."); return; } } /* * If fascist teleport is on, you must control the victim's ultimate * location (after LEAVEing any objects) or it must be JUMP_OK. */ if (mudconf.fascist_tport) { loc = where_room(victim); if (!Good_obj(loc) || !isRoom(loc) || !(Controls(player, loc) || Jump_ok(loc) || Tel_Anywhere(player))) { notify_quiet(player, NOPERM_MESSAGE); return; } } /* If this is an exit, the same privs involved as @open apply. */ if (isExit(victim)) { if (!Has_exits(destination) || (!Controls(player, destination) && !Open_Anywhere(player))) { notify_quiet(player, NOPERM_MESSAGE); return; } exitloc = Exits(victim); s_Exits(exitloc, remove_first(Exits(exitloc), victim)); s_Exits(destination, insert_first(Exits(destination), victim)); s_Exits(victim, destination); s_Modified(victim); notify_quiet(player, "Teleported."); return; } if (Has_contents(destination)) { /* * You must control the destination, or it must be a JUMP_OK * room where the victim passes its TELEPORT lock, or you * must be Tel_Anywhere. */ if (!(Controls(player, destination) || (Jump_ok(destination) && could_doit(victim, destination, A_LTPORT)) || Tel_Anywhere(player))) { /* * Nope, report failure */ if (player != victim) notify_quiet(player, NOPERM_MESSAGE); did_it(victim, destination, A_TFAIL, "You can't teleport there!", A_OTFAIL, NULL, A_ATFAIL, 0, (char **)NULL, 0, MSG_MOVE); return; } /* * We're OK, do the teleport */ if (key & TELEPORT_QUIET) hush = HUSH_ENTER | HUSH_LEAVE; if (move_via_teleport(victim, destination, cause, hush)) { if (player != victim) { if (!Quiet(player)) notify_quiet(player, "Teleported."); } } } else if (isExit(destination)) { if (Exits(destination) == Location(victim)) { move_exit(victim, destination, 0, "You can't go that way.", 0); } else { notify_quiet(player, "I can't find that exit."); } } } /* * --------------------------------------------------------------------------- * do_force_prefixed: Interlude to do_force for the # command */ void do_force_prefixed(player, cause, key, command, args, nargs) dbref player, cause; int key, nargs; char *command, *args[]; { char *cp; cp = parse_to(&command, ' ', 0); if (!command) return; while (*command && isspace(*command)) command++; if (*command) do_force(player, cause, key, cp, command, args, nargs); } /* * --------------------------------------------------------------------------- * do_force: Force an object to do something. */ void do_force(player, cause, key, what, command, args, nargs) dbref player, cause; int key, nargs; char *what, *command, *args[]; { dbref victim; if ((victim = match_controlled(player, what)) == NOTHING) return; /* * force victim to do command */ if (key & FRC_NOW) process_cmdline(victim, player, command, args, nargs, NULL); else wait_que(victim, player, 0, NOTHING, 0, command, args, nargs, mudstate.rdata); } /* * --------------------------------------------------------------------------- * do_toad: Turn a player into an object. */ void do_toad(player, cause, key, toad, newowner) dbref player, cause; int key; char *toad, *newowner; { dbref victim, recipient, loc, aowner; char *buf; int count, aflags, alen; init_match(player, toad, TYPE_PLAYER); match_neighbor(); match_absolute(); match_player(); if ((victim = noisy_match_result()) == NOTHING) return; if (!isPlayer(victim)) { notify_quiet(player, "Try @destroy instead."); return; } if (No_Destroy(victim)) { notify_quiet(player, "You can't toad that player."); return; } if ((newowner != NULL) && *newowner) { init_match(player, newowner, TYPE_PLAYER); match_neighbor(); match_absolute(); match_player(); if ((recipient = noisy_match_result()) == NOTHING) return; } else { recipient = player; } STARTLOG(LOG_WIZARD, "WIZ", "TOAD") log_name_and_loc(victim); log_printf(" was @toaded by "); log_name(player); ENDLOG /* * Clear everything out */ if (key & TOAD_NO_CHOWN) { count = -1; } else { count = chown_all(victim, recipient, player, 0); s_Owner(victim, recipient); /* * you get it */ } s_Flags(victim, TYPE_THING | HALT); s_Flags2(victim, 0); s_Flags3(victim, 0); s_Pennies(victim, 1); /* * notify people */ loc = Location(victim); buf = alloc_mbuf("do_toad"); sprintf(buf, "%s has been turned into a slimy toad!", Name(victim)); notify_except2(loc, player, victim, player, buf, 0); sprintf(buf, "You toaded %s! (%d objects @chowned)", Name(victim), count + 1); notify_quiet(player, buf); /* * Zap the name from the name hash table */ delete_player_name(victim, Name(victim)); sprintf(buf, "a slimy toad named %s", Name(victim)); s_Name(victim, buf); free_mbuf(buf); /* * Zap the alias too */ buf = atr_pget(victim, A_ALIAS, &aowner, &aflags, &alen); delete_player_name(victim, buf); free_lbuf(buf); count = boot_off(victim, (char *)"You have been turned into a slimy toad!"); notify_quiet(player, tprintf("%d connection%s closed.", count, (count == 1 ? "" : "s"))); } void do_newpassword(player, cause, key, name, password) dbref player, cause; int key; char *name, *password; { dbref victim; char *buf, *bp; if ((victim = lookup_player(player, name, 0)) == NOTHING) { notify_quiet(player, "No such player."); return; } if (*password != '\0' && !ok_password(password, player)) { /* Can set null passwords, but not bad passwords. * Notification of reason done by ok_password(). */ return; } if (God(victim)) { notify_quiet(player, "You cannot change that player's password."); return; } STARTLOG(LOG_WIZARD, "WIZ", "PASS") log_name(player); log_printf(" changed the password of "); log_name(victim); ENDLOG /* * it's ok, do it */ s_Pass(victim, crypt((const char *)password, "XX")); notify_quiet(player, "Password changed."); buf = alloc_lbuf("do_newpassword"); bp = buf; safe_tprintf_str(buf, &bp, "Your password has been changed by %s.", Name(player)); notify_quiet(victim, buf); free_lbuf(buf); } void do_boot(player, cause, key, name) dbref player, cause; int key; char *name; { dbref victim; char *buf, *bp; int count; if (!(Can_Boot(player))) { notify(player, NOPERM_MESSAGE); return; } if (key & BOOT_PORT) { if (is_number(name)) { victim = atoi(name); } else { notify_quiet(player, "That's not a number!"); return; } STARTLOG(LOG_WIZARD, "WIZ", "BOOT") log_printf("Port %d was @booted by ", victim); log_name(player); ENDLOG } else { init_match(player, name, TYPE_PLAYER); match_neighbor(); match_absolute(); match_player(); if ((victim = noisy_match_result()) == NOTHING) return; if (God(victim)) { notify_quiet(player, "You cannot boot that player!"); return; } if ((!isPlayer(victim) && !God(player)) || (player == victim)) { notify_quiet(player, "You can only boot off other players!"); return; } STARTLOG(LOG_WIZARD, "WIZ", "BOOT") log_name_and_loc(victim); log_printf(" was @booted by "); log_name(player); ENDLOG notify_quiet(player, tprintf("You booted %s off!", Name(victim))); } if (key & BOOT_QUIET) { buf = NULL; } else { bp = buf = alloc_lbuf("do_boot.msg"); safe_name(player, buf, &bp); safe_str((char *)" gently shows you the door.", buf, &bp); *bp = '\0'; } if (key & BOOT_PORT) count = boot_by_port(victim, !God(player), buf); else count = boot_off(victim, buf); notify_quiet(player, tprintf("%d connection%s closed.", count, (count == 1 ? "" : "s"))); if (buf) free_lbuf(buf); } /* * --------------------------------------------------------------------------- do_poor: Reduce the wealth of anyone over a specified amount. */ void do_poor(player, cause, key, arg1) dbref player, cause; int key; char *arg1; { dbref a; int amt, curamt; if (!is_number(arg1)) return; amt = atoi(arg1); DO_WHOLE_DB(a) { if (isPlayer(a)) { curamt = Pennies(a); if (amt < curamt) s_Pennies(a, amt); } } } /* * --------------------------------------------------------------------------- * do_cut: Chop off a contents or exits chain after the named item. */ void do_cut(player, cause, key, thing) dbref player, cause; int key; char *thing; { dbref object; object = match_controlled(player, thing); switch (object) { case NOTHING: notify_quiet(player, "No match."); break; case AMBIGUOUS: notify_quiet(player, "I don't know which one"); break; default: s_Next(object, NOTHING); notify_quiet(player, "Cut."); } } /* -------------------------------------------------------------------------- * do_motd: Wizard-settable message of the day (displayed on connect) */ void do_motd(player, cause, key, message) dbref player, cause; int key; char *message; { int is_brief; is_brief = 0; if (key & MOTD_BRIEF) { is_brief = 1; key = key & ~MOTD_BRIEF; if (key == MOTD_ALL) key = MOTD_LIST; else if (key != MOTD_LIST) key |= MOTD_BRIEF; } message[GBUF_SIZE - 1] = '\0'; switch (key) { case MOTD_ALL: if (mudconf.motd_msg) { XFREE(mudconf.motd_msg, "do_motd.motd"); } mudconf.motd_msg = XSTRDUP(message, "do_motd.motd"); if (!Quiet(player)) notify_quiet(player, "Set: MOTD."); break; case MOTD_WIZ: if (mudconf.wizmotd_msg) { XFREE(mudconf.wizmotd_msg, "do_motd.wizmotd"); } mudconf.wizmotd_msg = XSTRDUP(message, "do_motd.wizmotd"); if (!Quiet(player)) notify_quiet(player, "Set: Wizard MOTD."); break; case MOTD_DOWN: if (mudconf.downmotd_msg) { XFREE(mudconf.downmotd_msg, "do_motd.downmotd"); } mudconf.downmotd_msg = XSTRDUP(message, "do_motd.downmotd"); if (!Quiet(player)) notify_quiet(player, "Set: Down MOTD."); break; case MOTD_FULL: if (mudconf.fullmotd_msg) { XFREE(mudconf.fullmotd_msg, "do_motd.fullmotd"); } mudconf.fullmotd_msg = XSTRDUP(message, "do_motd.fullmotd"); if (!Quiet(player)) notify_quiet(player, "Set: Full MOTD."); break; case MOTD_LIST: if (Wizard(player)) { if (!is_brief) { notify_quiet(player, "----- motd file -----"); fcache_send(player, FC_MOTD); notify_quiet(player, "----- wizmotd file -----"); fcache_send(player, FC_WIZMOTD); notify_quiet(player, "----- motd messages -----"); } if (mudconf.motd_msg && *mudconf.motd_msg) { notify_quiet(player, tprintf("MOTD: %s", mudconf.motd_msg)); } else { notify_quiet(player, "No MOTD."); } if (mudconf.wizmotd_msg && *mudconf.wizmotd_msg) { notify_quiet(player, tprintf("Wizard MOTD: %s", mudconf.wizmotd_msg)); } else { notify_quiet(player, "No Wizard MOTD."); } if (mudconf.downmotd_msg && *mudconf.downmotd_msg) { notify_quiet(player, tprintf("Down MOTD: %s", mudconf.downmotd_msg)); } else { notify_quiet(player, "No Down MOTD."); } if (mudconf.fullmotd_msg && *mudconf.fullmotd_msg) { notify_quiet(player, tprintf("Full MOTD: %s", mudconf.fullmotd_msg)); } else { notify_quiet(player, "No Full MOTD."); } } else { if (Guest(player)) fcache_send(player, FC_CONN_GUEST); else fcache_send(player, FC_MOTD); if (mudconf.motd_msg && *mudconf.motd_msg) { notify_quiet(player, mudconf.motd_msg); } else { notify_quiet(player, "No MOTD."); } } break; default: notify_quiet(player, "Illegal combination of switches."); } } /* --------------------------------------------------------------------------- * do_global: enable or disable global control flags */ /* *INDENT-OFF* */ NAMETAB enable_names[] = { {(char *)"building", 1, CA_PUBLIC, CF_BUILD}, {(char *)"checkpointing", 2, CA_PUBLIC, CF_CHECKPOINT}, {(char *)"cleaning", 2, CA_PUBLIC, CF_DBCHECK}, {(char *)"dequeueing", 1, CA_PUBLIC, CF_DEQUEUE}, {(char *)"god_monitoring", 1, CA_PUBLIC, CF_GODMONITOR}, {(char *)"idlechecking", 2, CA_PUBLIC, CF_IDLECHECK}, {(char *)"interpret", 2, CA_PUBLIC, CF_INTERP}, {(char *)"logins", 3, CA_PUBLIC, CF_LOGIN}, {(char *)"eventchecking", 2, CA_PUBLIC, CF_EVENTCHECK}, { NULL, 0, 0, 0}}; /* *INDENT-ON* */ void do_global(player, cause, key, flag) dbref player, cause; int key; char *flag; { int flagvalue; /* * Set or clear the indicated flag */ flagvalue = search_nametab(player, enable_names, flag); if (flagvalue < 0) { notify_quiet(player, "I don't know about that flag."); } else if (key == GLOB_ENABLE) { mudconf.control_flags |= flagvalue; STARTLOG(LOG_CONFIGMODS, "CFG", "GLOBAL") log_name(player); log_printf(" enabled: %s", flag); ENDLOG if (!Quiet(player)) notify_quiet(player, "Enabled."); } else if (key == GLOB_DISABLE) { mudconf.control_flags &= ~flagvalue; STARTLOG(LOG_CONFIGMODS, "CFG", "GLOBAL") log_name(player); log_printf(" disabled: %s", flag); ENDLOG if (!Quiet(player)) notify_quiet(player, "Disabled."); } else { notify_quiet(player, "Illegal combination of switches."); } }