/* wiz.c */ #include "copyright.h" /* Wizard-only commands */ #ifdef WANT_ANSI #ifdef __STDC__ #include <stddef.h> #include <stdlib.h> #endif /* __STDC__ */ #endif /* WANT_ANSI */ #include <ctype.h> #include "mudconf.h" #include "config.h" #include "db.h" #include "interface.h" #include "match.h" #include "externs.h" #include "command.h" #include "htab.h" extern char *crypt(); void do_teleport(dbref player, dbref cause, int key, char *arg1, char *arg2) { dbref victim, destination; char *to; /* get victim */ if (*arg2 == '\0') { victim = player; to = arg1; } else { init_match(player, arg1, NOTYPE); match_neighbor(); match_possession(); match_me(); match_absolute(); match_player(); victim = noisy_match_result(); if (victim == NOTHING) return; to = arg2; } /* Validate type of victim */ switch (Typeof(victim)) { case TYPE_PLAYER: case TYPE_THING: break; default: notify(player, "You can't teleport that."); return; } /* Fail if we don't control the victim or the victim's location */ if (!Controls(player, victim) && !Controls(player, Location(victim))) { notify(player, "Permission denied."); return; } /* Check for teleporting home */ if (!string_compare(to, "home")) { (void)move_via_teleport(victim, HOME, cause, 0); return; } /* Find out where to send the victim */ init_match(player, to, NOTYPE); match_here(); match_absolute(); match_neighbor(); match_me(); match_player(); match_exit(); destination = match_result(); switch (destination) { case NOTHING: notify(player, "No match."); return; case AMBIGUOUS: notify(player, "I don't know which destination you mean!"); return; default: if (victim == destination) { notify(player, "Bad destination."); return; } } switch (Typeof(destination)) { case TYPE_ROOM: case TYPE_PLAYER: case TYPE_THING: /* You must control the destination, or it must be a JUMP_OK * room where you pass its TELEPORT lock. */ if (!Controls(player, destination) && !(IS(destination, TYPE_ROOM, ROOM_JUMP_OK) && could_doit(player, destination, A_LTPORT))) { notify(player, "Permission denied."); return; } if (move_via_teleport(victim, destination, cause, 0)) { if (player != victim) { if (!Quiet(player)) notify(player, "Teleported."); if (!Quiet(victim)) notify(victim, "Teleported."); } } break; case TYPE_EXIT: if (Exits(destination) == Location(victim)) { move_exit(victim, destination, 0, "You can't go that way.", 0); } else { notify(player, "I can't find that exit."); } } } /* --------------------------------------------------------------------------- * do_force_prefixed: Interlude to do_force for the # command */ void do_force_prefixed (dbref player, dbref cause, int extra, char *command, char *args[], int nargs) { char *cp; cp=parse_to(&command, ' ', 0); if (!command) return; while (*command && isspace(*command)) command++; if (*command) do_force(player, cause, extra, cp, command, args, nargs); } /* --------------------------------------------------------------------------- * do_force: Force an object to do something. */ void do_force(dbref player, dbref cause, int extra, char *what, char *command, char *args[], int nargs) { dbref victim; if ((victim = match_controlled(player, what)) == NOTHING) return; /* force victim to do command */ wait_que(victim, player, RU_ARG1_COPY, 0, NOTHING, command, args, nargs); } /* --------------------------------------------------------------------------- * do_toad: Turn a player into an object. */ void do_toad(dbref player, dbref cause, int key, char *toad, char *newowner) { dbref victim, recipient, loc, aowner; char *buf; int count, aflags; init_match(player, toad, TYPE_PLAYER); match_neighbor(); match_absolute(); match_player(); if ((victim = noisy_match_result()) == NOTHING) return; if (Typeof(victim) != TYPE_PLAYER) { notify(player, "Try @destroy instead."); return; } if (Wizard(victim)) { notify(player, "You can't toad a Wizard."); 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_text((char *)" was @toaded by "); log_name(player); ENDLOG /* Clear everything out */ if (key & TOAD_NO_CHOWN) { count = -1; } else { count = chown_all(victim, recipient); s_Owner(victim, recipient); /* you get it */ } s_Flags(victim, TYPE_THING|HALT); 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, 1); sprintf(buf, "You toaded %s! (%d objects @chowned)", Name(victim), count + 1); notify(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); delete_player_name(victim, buf); free_lbuf(buf); count = boot_off(victim, (char *)"You have been turned into a slimy toad!"); notify(player, tprintf("%d connection%s closed.", count, (count==1 ? "" : "s"))); } void do_newpassword(dbref player, dbref cause, int key, char *name, char *password) { dbref victim; char *buf; if ((victim = lookup_player(player, name, 0)) == NOTHING) { notify(player, "No such player."); return; } if (*password != '\0' && !ok_password(password)) { /* Can set null passwords, but not bad passwords */ notify(player, "Bad password"); return; } if (God(victim) && !God(player)) { notify(player, "You cannot change that player's password."); return; } STARTLOG(LOG_WIZARD,"WIZ","PASS") log_name(player); log_text((char *)" changed the password of "); log_name(victim); ENDLOG /* it's ok, do it */ s_Pass(victim, crypt(password, "XX")); buf=alloc_lbuf("do_newpassword"); notify(player, "Password changed."); sprintf(buf, "Your password has been changed by %s.", Name(player)); notify(victim, buf); free_lbuf(buf); } void do_boot(dbref player, dbref cause, int key, char *name) { dbref victim; char *buf, *bp; int count; if (key & BOOT_PORT) { if (is_number(name)) { victim = atoi(name); } else { notify(player, "That's not a number!"); return; } STARTLOG(LOG_WIZARD,"WIZ","BOOT") buf = alloc_sbuf("do_boot.port"); sprintf(buf, "Port %d", victim); log_text(buf); log_text((char *)" was @booted by "); log_name(player); free_sbuf(buf); 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(player, "You cannot boot that player!"); return; } if ((Typeof(victim) != TYPE_PLAYER && !God(player)) || (player == victim)) { notify(player, "You can only boot off other players!"); return; } STARTLOG(LOG_WIZARD,"WIZ","BOOT") log_name_and_loc(victim); log_text((char *)" was @booted by "); log_name(player); ENDLOG notify(player, tprintf("You booted %s off!", Name(victim))); } if (key & BOOT_QUIET) { buf = NULL; } else { bp = buf = alloc_lbuf("do_boot.msg"); safe_str(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(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(dbref player, dbref cause, int key, char *arg1) { dbref a; int amt, curamt; if (!is_number(arg1)) return; amt = atoi(arg1); DO_WHOLE_DB(a) { if (Typeof(a) == TYPE_PLAYER) { 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(dbref player, dbref cause, int key, char *thing) { dbref object; object = match_controlled(player, thing); switch (object) { case NOTHING: notify(player, "No match."); break; case AMBIGUOUS: notify(player, "I don't know which one"); break; default: s_Next(object, NOTHING); notify(player, "Cut."); } } /* --------------------------------------------------------------------------- * count_quota, mung_quota, show_quota, do_quota: Manage quotas. */ static int count_quota (dbref player) { int i, q; player = Owner(player); q = 0 - mudconf.player_quota; DO_WHOLE_DB(i) { if (Owner(i) != player) continue; if ((Flags(i) & GOING) && (Typeof(i) != TYPE_ROOM)) continue; switch (Typeof(i)) { case TYPE_EXIT: q += mudconf.exit_quota; break; case TYPE_ROOM: q += mudconf.room_quota; break; case TYPE_THING: q += mudconf.thing_quota; break; case TYPE_PLAYER: q += mudconf.player_quota; break; } } return q; } static void mung_quotas (dbref player, int key, int value) { dbref aowner; int aq, rq, xq, aflags; char *buff; if (key & QUOTA_FIX) { /* Get value of stuff owned and good value, set other value * from that. */ xq = count_quota(player); if (key & QUOTA_TOT) { buff = atr_get(Owner(player), A_RQUOTA, &aowner, &aflags); aq = atoi(buff) + xq; atr_add_raw(Owner(player), A_QUOTA, tprintf("%d", aq)); free_lbuf(buff); } else { buff = atr_get(Owner(player), A_QUOTA, &aowner, &aflags); rq = atoi(buff) - xq; atr_add_raw(Owner(player), A_RQUOTA, tprintf("%d", rq)); free_lbuf(buff); } } else { /* Obtain (or calculate) current relative and absolute quota */ buff = atr_get(Owner(player), A_QUOTA, &aowner, &aflags); if (!*buff) { free_lbuf(buff); buff = atr_get(Owner(player), A_RQUOTA, &aowner, &aflags); rq = atoi(buff); free_lbuf(buff); aq = rq + count_quota(player); } else { aq = atoi(buff); free_lbuf(buff); buff = atr_get(Owner(player), A_RQUOTA, &aowner, &aflags); rq = atoi(buff); free_lbuf(buff); } /* Adjust values */ if (key & QUOTA_REM) { aq += (value - rq); rq = value; } else { rq += (value - aq); aq = value; } /* Set both abs and relative quota */ atr_add_raw(Owner(player), A_QUOTA, tprintf("%d", aq)); atr_add_raw(Owner(player), A_RQUOTA, tprintf("%d", rq)); } } static void show_quota (dbref player, dbref victim) { dbref aowner; int aq, rq, aflags; char *buff; player = Owner(player); victim = Owner(victim); buff = atr_get(victim, A_QUOTA, &aowner, &aflags); aq = atoi(buff); free_lbuf(buff); buff = atr_get(victim, A_RQUOTA, &aowner, &aflags); rq = aq - atoi(buff); free_lbuf(buff); if (!Wizard(victim)) notify(player, tprintf("%-16s Quota: %9d Used: %9d", Name(victim), aq, rq)); else notify(player, tprintf("%-16s Quota: UNLIMITED Used: %9d", Name(victim), rq)); } void do_quota (dbref player, dbref cause, int key, char *arg1, char *arg2) { dbref who; int set, value, i; if(!(mudconf.quotas | Wizard(player))) { notify(player, "Quotas are not enabled."); return; } if ((key & QUOTA_TOT) && (key & QUOTA_REM)) { notify(player, "Illegal combination of switches."); return; } value = 0; set = 0; if (key & QUOTA_ALL) { if (arg1 && *arg1) { value = atoi(arg1); set = 1; } if (set) { STARTLOG(LOG_WIZARD,"WIZ","QUOTA") log_name(player); log_text((char *)" changed everyone's quota"); ENDLOG } DO_WHOLE_DB(i) { if (Typeof(i) == TYPE_PLAYER) { if (set) mung_quotas(i, key, value); show_quota(player, i); } } return; } if (!arg1 || *arg1 == '\0') who = player; else { init_match(player, arg1, TYPE_PLAYER); match_me(); match_player(); match_neighbor(); match_absolute(); if ((who = noisy_match_result()) == NOTHING) return; } if (!Wizard(player)) { if (arg2 && *arg2) { notify(player, "Permission denied."); return; } if (player != who) { notify(player, "Permission denied."); return; } } if (arg2 && *arg2) { set = 1; value = atoi(arg2); } if (set) { STARTLOG(LOG_WIZARD,"WIZ","QUOTA") log_name(player); log_text((char *)" changed the quota of "); log_name(who); ENDLOG mung_quotas(who, key, value); } show_quota(player, who); } /* -------------------------------------------------------------------------- * do_motd: Wizard-settable message of the day (displayed on connect) */ void do_motd (dbref player, dbref cause, int key, char *message) { switch (key) { case MOTD_ALL: strcpy(mudconf.motd_msg, message); if (!Quiet(player)) notify(player, "Set: MOTD."); break; case MOTD_WIZ: strcpy(mudconf.wizmotd_msg, message); if (!Quiet(player)) notify(player, "Set: Wizard MOTD."); break; case MOTD_DOWN: strcpy(mudconf.downmotd_msg, message); if (!Quiet(player)) notify(player, "Set: Down MOTD."); break; case MOTD_FULL: strcpy(mudconf.fullmotd_msg, message); if (!Quiet(player)) notify(player, "Set: Full MOTD."); break; case MOTD_LIST: if (Wizard(player)) { notify(player, tprintf("MOTD: %s", mudconf.motd_msg)); notify(player, tprintf("Wizard MOTD: %s", mudconf.wizmotd_msg)); notify(player, tprintf("Down MOTD: %s", mudconf.downmotd_msg)); notify(player, tprintf("Full MOTD: %s", mudconf.fullmotd_msg)); } else { if (Guest(player)) fcache_send(player, mudstate.guest_fcache); else fcache_send(player, mudstate.motd_fcache); notify(player, mudconf.motd_msg); } break; default: notify(player, "Illegal combination of switches."); } } /* --------------------------------------------------------------------------- * do_enable: enable or disable global control flags */ 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 *)"idlechecking", 2, CA_PUBLIC, CF_IDLECHECK}, {(char *)"interpret", 2, CA_PUBLIC, CF_INTERP}, {(char *)"local_rwho", 3, CA_PUBLIC, CF_ALLOW_RWHO}, {(char *)"logins", 3, CA_PUBLIC, CF_LOGIN}, {(char *)"transmit_rwho", 1, CA_PUBLIC, CF_RWHO_XMIT}, { NULL, 0, 0, 0}}; void do_global (dbref player, dbref cause, int key, char *flag) { int flagvalue; /* Set or clear the indicated flag */ flagvalue = search_nametab(player, enable_names, flag); if (flagvalue == -1) { notify(player, "I don't know about that flag."); } else if (key == GLOB_ENABLE) { mudconf.control_flags |= flagvalue; if (!Quiet(player)) notify(player, "Enabled."); } else if (key == GLOB_DISABLE) { mudconf.control_flags &= ~flagvalue; if (!Quiet(player)) notify(player, "Disabled."); } else { notify(player, "Illegal combination of switches."); } }