/* * MusicMUD - Admin module (part 2) * Copyright (C) 1998-2003 Abigail Brady * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <string.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <ctype.h> #ifdef CONFIG_PTHREAD #include <pthread.h> #endif #include "musicmud.h" #include "verbs.h" #include "State.h" #include "zoneload.h" #include "magic.h" #include "msi.h" #include "misc.h" #include "Socket.h" #include "config.h" #include "startup.h" #include "trap.h" #include "flags.h" #include "Writer.h" #include "pflags.h" #include "util.h" #include "levels.h" #include "flagnames.h" #ifdef CONFIG_PIPE_IDENT #include "pipe-ident.h" #endif #include "Library.h" #define MODULE "admin2" #define is_room(r) (r->get_flag(FL_ROOM)) static int object_depth(MudObject *who) { int level = 0; while (who) { who = who->owner; level++; } return level; } static bool verb_mudcrash(MudObject *who, int, const char **) { *(int *)0=0; return true; } static bool verb_magic(MudObject *, int, const char **) { signals_start(); return true; } static void do_save(FILE *f, const char *zonename) { MudObject *o; int i; foreach(zones->get(zonename)->children, o, i) { if (!is_player(o)) { o->save(f); } } } static bool verb_shutdown(MudObject *luser, int , const char *argv[]) { ident::done(); if (!streq(argv[1], "quick")) { log(PFL_SEEINFO, 0, "admin", "emergency zone saving started"); struct timeval start_time; gettimeofday(&start_time, 0); FILE *meta=xopen(DATA_WORLD_EMERG, "index", "w"); if (!meta) return true; int size = zones->getsize(); for (int i=0;i<size;i++) { const char *id = zones->get(i)->id; luser->printf("Saving zone %s\n", id); FILE *f = xopen(DATA_WORLD_EMERG, id, "w"); do_save(f, id); luser->send_data(); fprintf(meta, "%s\n", id); xclose(f); } xclose(meta); struct timeval end_time; gettimeofday(&end_time, 0); log(PFL_SEEINFO, 0, "admin", "emergency zone saving finished"); } save_var_data(); Player *p; int i; foreach(players, p, i) { p->interpret("saveplayer"); p->printf("%#s has been shut down. Goodbye.\n", THE_MUDNAME); p->send_data(); } log(PFL_SEEINFO, 0, "admin", "shutdown"); exit(1); return true; } static bool verb_savezones(MudObject *o, int , const char *[]) { struct timeval start_time; gettimeofday(&start_time, 0); FILE *meta=xopen_tmp(DATA_WORLD, "index", "w"); int size = zones->getsize(); log(PFL_SEEINFO, 0, "zone", "about to save zones"); o->printf("Saving zones "); for (int eep=0;eep<size;eep++) { const char *id = zones->get(eep)->id; if (id[0] == '@') continue; o->printf("%s ", id); FILE *f = xopen_tmp(DATA_WORLD, id, "w"); if (!f) { o->printf("\nBad news : the zonefiles couldn't be saved properly. Contact an administrator.\n"); return true; } do_save(f, id); o->send_data(); fprintf(meta, "%s\n", id); xclose_confirm(f, DATA_WORLD, id); } o->printf("\n"); xclose_confirm(meta, DATA_WORLD, "index"); struct timeval end_time; gettimeofday(&end_time, 0); #if 0 int64_t difference = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); #endif save_var_data(); log(PFL_SEEINFO, 0, "zone", "all zones saved"); return true; } static bool verb_savevar(MudObject *o, int argc, const char **argv) { save_var_data(); o->printf("Saved vardata and data/mudconf.\n"); return true; } static bool verb_savethiszone(MudObject *o, int argc, const char **argv) { if (!o->owner) { o->printf("You are nowhere.\n"); return true; } const char *zone = o->owner->get("zone"); if (argc>1 && zones->get(argv[1])) { zone = argv[1]; } if (!zone) { o->printf("What zone?\n"); return true; } FILE *f = xopen_tmp(DATA_WORLD, zone, "w"); if (!f) { o->printf("Bad news : the zonefile couldn't be saved properly\n" "If Daz is on tell him. If not, email him at\n" "dab198@zepler.org\n"); return true; } do_save(f, zone); o->printf("zone %s saved.\n", zone); xclose_confirm(f, DATA_WORLD, zone); log(PFL_SEEINFO, 0, "zone", "%s saved", zone); return true; } static bool verb_rtz(MudObject *o, int argc, const char *argv[]) { if (!o->owner) { o->printf("You are nowhere.\n"); return true; } const char *zone = o->owner->get("zone"); if (!zone) { o->printf("What zone?\n"); return true; } broadcast(!getflag(FL_NORESET) && minlev(LEV_COMMANDER), "^Y[^RRESET^g: ^G%s^g by %s^Y]\n", capitalise(zone).c_str(), name(o)); doreset(zone, true); return true; } static bool verb_reset(MudObject *who, int argc, const char *argv[]) { if (argc < 2) { who->printf("reset <zonename>\n"); return true; } if (!zones->get(argv[1]) && !streq(argv[1], "all")) { who->printf("You can only reset zones or 'all'\n"); return true; } if (streq(argv[1], "all")) broadcast(!getflag(FL_NORESET) && minlev(LEV_COMMANDER), "^Y[^RRESET^g: ^GEverything^g by %s^Y]\n", name(who)); else broadcast(!getflag(FL_NORESET) && minlev(LEV_COMMANDER), "^Y[^RRESET^g: ^G%s^g by %s^Y]\n", capitalise(argv[1]).c_str(), name(who)); doreset(argv[1], true); return true; } static bool verb_snoop(MudObject *player, int argc, const char **argv) { if (argc < 2) { if (player->snooping.getsize()) { player->printf("You are snooping %W.\n", &player->snooping); } else { player->printf("You aren't snooping anyone.\n"); } return true; } MudObject *target = planet->get(argv[1]); if (!target) { player->printf("Can't find %s\n", argv[1]); return true; } if (player == target) { player->printf("Don't you know what you're doing already?!\n"); return true; } if (privs_of(target) > privs_of(player)) { player->printf("You can't snoop %s.\n", him_or_her(target)); return true; } if (player->snooping.get(target->id)) { player->desnoop(target); player->printf("No longer snooping %M.\n", target); log(PFL_SNOOP, 0, "admin", "no longer snooping %s", target->id); } else { player->snoop(target); player->printf("Now snooping %M.\n", target); log(PFL_SNOOP, 0, "admin", "snooping %s", target->id); } return true; } static bool verb_desnoop(MudObject *player, int, const char **) { MudObject *o; int i; if (!player->snooping) { player->printf("You aren't snooping anyone.\n"); return true; } player->printf("No longer snooping %W.\n", &player->snooping); foreach((&player->snooping), o, i) { player->desnoop(o); i--; } return true; } static bool verb_force(MudObject *player, int argc, const char *argv[]) { if (!player->get_priv(PFL_FORCE) && !player->get_flag(FL_TIMER)) { player->printf("You cannot do that.\n"); return true; } if (argc<3) { player->printf("force <who> <what>\n"); return true; } MudObject *target = find_object(player, argv[1]); if (!target) { player->printf("Can't find %s\n", argv[1]); return true; } if (target==player) { player->printf("Forcing yourself to do stuff is not a good idea.\n"); return true; } if (privs_of(target)>=privs_of(player) && !player->ilc) { player->printf("You can only force people of lower levels..\n"); return true; } string cmd = the_rest(argc, argv, 2); int desnoop = 0; if (!player->ilc) { desnoop = player->snoop(target); } if (player->ilc) { target->ilc++; } else { log(PFL_SEEINFO, 0, "admin", "%s forces %s to %s", player->id, target->id, cmd.c_str()); } target->interpret(cmd.c_str()); if (player->ilc) { target->ilc--; } if (desnoop) { player->desnoop(target); } return true; } static bool verb_loadflags(MudObject *, int, const char **) { load_flags(); load_pflags(); return true; } static bool verb_modulelist(MudObject *player, int, const char **){ Object *o; int i; Divert d(player, "modulelist"); foreach(libs, o, i) { time_t t = o->get_int("timestamp"); player->printf("%-40s %s", o->id, ctime(&t)); } return true; } #include "aberchat.h" static bool verb_reboot(MudObject *who, int, const char **) { #ifdef CONFIG_PIPE_IDENT ident::done(); #endif #ifdef CONFIG_THREAD pthread_kill_other_threads_np(); if (fork()!=0) exit(0); #endif char buffer[256]; char wallace[4096]; sprintf(buffer, VARDATA "/reboot-misc.%i", getpid()); FILE *f = xopen(".", buffer, "w"); if (f) { fprintf(f, "%i\n", (int)mud_start); xclose(f); } sprintf(buffer, VARDATA "/reboot-parties.%i", getpid()); f = xopen(".", buffer, "w"); if (f) { MudObject *p; int i; foreach(players, p, i) { if (!p->followers.getsize()) { continue; } fprintf(f, "%s ", p->id); MudObject *o; int j; foreach((&p->followers), o, j) if (o->id[0]!='@' && !o->get_flag(FL_OBSERVED)) { o->set_flag(FL_OBSERVED, 1); fprintf(f, "%s ", o->id); } fprintf(f, "\n"); } xclose(f); } sprintf(buffer, VARDATA "/reboot.%i", getpid()); f = xopen(".", buffer, "w"); if (aberchat_auth && aberchat_socket) { int fd = aberchat_socket->getfd(); fcntl(fd, F_SETFD, false); while ((read(fd, wallace, 4096)) > 0) ; sprintf(buffer, VARDATA "/aberfd.%i", getpid()); FILE *f2 = xopen(".", buffer, "w"); fprintf(f2, "%i\n", fd); xclose(f2); } Player *p; int i; foreach(players, p, i){ Socket *s = p->p?p->p->socket:0; if (s) { int fd = s->getfd(); fcntl(fd, F_SETFD, false); read(fd, wallace, 4096); if (p->get_flag(FL_LOGGEDIN)) { fprintf(f, "%s %i %s %i %s\n", p->id, fd, p->owner->id, (int)p->get_idle(), p->p->serialise().c_str()); } else { PersonState *ps = p->get_person_state(); string sps = serialise_personstate(ps); fprintf(f, "%s %i %s %i %s\n%s\n", p->id, fd, p->owner->id, (int)p->get_idle(), p->p->serialise().c_str(), sps.c_str()); } } #ifndef NOCOMPRESS if (p->p) { p->p->compress_off(); } #endif } xclose(f); log(PFL_NONE, 0, "global", "reboot begun"); foreach(players, p, i) { p->interpret("save"); p->send_data(); } save_var_data(); int port = MUD_DEFPORT; extern Socket *primary; if (primary) port = primary->port; msi::done(); extern FILE *logfile; xclose(logfile); logfile = 0; Library *l; foreach(libs, l, i) { l->cleanup(); } char pstr[16]; sprintf(pstr, "%i", port); if (port == 6665) execl("./testmud", "./testmud", "-p", pstr, "-r", 0); else execl("./musicmud", "./musicmud", "-p", pstr, "-r", 0); who->printf("failed.\n"); return true; } static bool verb_bans(MudObject *who, int, const char **) { FILE *f=xopen(VARDATA, "banned", "r"); if (!f) { who->printf("Can't open %s/banned.\n", VARDATA); return true; } char buffer[256]; int i=0; while (1) { fgets(buffer, 256, f); if (feof(f)) break; *strchr(buffer, '\n')=0; i++; who->printf("%s\n", buffer); } xclose(f); if (!i) { who->printf("No bans.\n"); } return true; } static bool verb_addban(MudObject *who, int argc, const char **argv) { if (argc == 1) { who->printf("Ban which IP address?\n"); return true; } FILE *f=xopen(VARDATA, "banned", "a"); if (!f) { who->printf("Can't open %s/banned.\n", VARDATA); return true; } fprintf(f, "%s\n", argv[1]); xclose(f); who->printf("OK.\n"); return true; } static bool verb_remban(MudObject *who, int argc, const char **argv) { if (argc == 1) { who->printf("Remove ban on who?\n"); return true; } bool ok = false; FILE *i = xopen(VARDATA, "banned", "r"); if (!i) { who->printf("Can't open %s/banned.\n", VARDATA); return true; } FILE *o = xopen(VARDATA, "banned.tmp", "w"); if (!o) { who->printf("Can't open temporary file.\n"); return true; } while (1) { char buffer[256]; fgets(buffer, sizeof buffer, i); if (feof(i)) break; *strchr(buffer, '\n')=0; if (streq(argv[1], buffer)) { ok = true; } else { fprintf(o, "%s\n", buffer); } } if (ok) { unlink(VARDATA "/banned"); rename(VARDATA "/banned.tmp", VARDATA "/banned"); who->printf("OK.\n"); } else { unlink(VARDATA "/banned.tmp"); who->printf("That IP address is not banned.\n"); } xclose(o); xclose(i); return true; } static bool verb_fds(MudObject *who, int, const char **) { who->printf("%5s %-20s %-20s %5s\n", "fd", "filename", "sourcefile", "line"); for (int l=0;l<1024;l++) { if (fds[l]) { who->printf("%5i %-20s %-20s %5i\n", l, fds[l]->get("filename"), fds[l]->get("sourcefile"), fds[l]->get_int("lineno")); } } return true; } static bool verb_zap(MudObject *who, int argc, const char **argv) { if (argc < 2) { who->printf("zap <who>\n", argv[1]); return true; } MudObject *what = find_object(who, argv[1]); if (!what) { who->printf("Zap who?\n"); return true; } if (!is_player(what)) { who->printf("You can only zap players.\n"); return true; } if (what->get_int("privs")>=who->get_int("privs")) { who->printf("I don't think so.\n"); return true; } NewWorld tozap; add_storeable_eq(what, tozap); MudObject *o; int i; foreach((&tozap), o, i) { vanish(o); } dumpstuff(what, what->owner); what->quit = time(NULL)+2; what->printf("You've been destroyed by %M.\n", who); what->send_data(); log(PFL_SEEINFO, 0, "admin", "%s zaps %s", who->id, what->id); foreach(players, o, i) if (o->get_flag(FL_LOGGEDIN) && o != what) o->printf("You hear a warning siren in the distance.\n"); char name[1024]; sprintf(name, DATA_USERS "/%s", what->id); unlink(name); MudObject *scalp=clone_object(MUD_SCALP, who, NULL); if (scalp) { scalp->setf("desc", "This scalp has a small label sewn to it bearing the name '%M'.", what); what->oprintf(avoid(who), "%#M %[combusts/combust] leaving only %M in %P's possession.\n", what, scalp, who); who->printf("%#M %[combusts/combust] leaving only %M in your possession.\n", what, scalp); } else { what->oprintf(avoid(who), "%#M %[combusts/combust] leaving nothing.\n", what); who->printf("%#M %[combusts/combust].\n", what); } return true; } extern void sigsegv(int); static void do_torture(MudObject *what) { MudObject *o; int i; signal(SIGSEGV, &sigsegv); foreach(what->children, o, i) { do_torture(o); } } static bool verb_torture(MudObject *, int, const char **) { do_torture(mud); return true; } struct Domain { const char *domain; const char *dir; PFlag create, erase; const char *suffix; } domains[] = { { "info", DATA_INFO, PFL_MAKEINFO, PFL_ERASEINFO, ".i" }, { "help", DATA_HELP, PFL_MAKEHELP, PFL_ERASEHELP, "" }, { "policy", DATA_POLICY, PFL_MAKEPOLICY, PFL_ERASEPOLICY, "" }, { "files", DATA_FILES, PFL_MAKEFILE, PFL_ERASEFILE, "" }, { "ac", DATA_ACTIONS, PFL_MAKEINFO, PFL_ERASEINFO, "" }, { "verb", DATA_VERBS, PFL_CODER, PFL_CODER, "" }, { 0 }, }; typedef struct Domain domain_t; static domain_t *get_domain(const char *what) { domain_t *d = domains; while (d->domain) { if (streq(d->domain, what)) return d; d++; } return NULL; } static bool verb_makefile(MudObject *who, int argc, const char **argv) { if (argc < 3) { who->printf("makefile <domain> <filename>\n"); return true; } domain_t *d = get_domain(argv[1]); if (!d) { who->printf("Can't find that domain.\n"); return true; } if (!who->get_priv(d->create) || !is_player(who)) { who->printf("You can't do that now.\n"); return true; } if (strchr(argv[2], '.') || strchr(argv[2], '/')) { who->printf("No.\n"); return true; } string f = d->dir; f+= "/"; f+= argv[2]; f+= d->suffix; struct stat b; if (stat(f.c_str(), &b)==0) { who->printf("'%s' already exists. Use \"erasefile\" to erase it first.\n", f.c_str()); return true; } FILE *fl = xopen(".", f.c_str(), "w"); if (!fl) { who->printf("Can't open '%s'\n", f.c_str()); return true; } Player *p = (Player *)who; p->push_state(new WriterState(fl)); p->printf("Use \"**\" to finish.\n"); return true; } static bool verb_erasefile(MudObject *who, int argc, const char **argv) { if (argc < 3) { who->printf("erasefile <domain> <filename>\n"); return true; } domain_t *d = get_domain(argv[1]); if (!d) { who->printf("Can't find that domain.\n"); return true; } if (!who->get_priv(d->erase) || !is_player(who)) { who->printf("You can't do that now.\n"); return true; } if (strchr(argv[2], '.') || strchr(argv[2], '/')) { who->printf("No.\n"); return true; } string f = d->dir; f+= "/"; f+= argv[2]; f+= d->suffix; unlink(f.c_str()); who->printf("Ok.\n"); return true; } static bool verb_trace(MudObject *who, int argc, const char **argv) { MudObject *victim = 0; if (argc!=2) { who->printf("Syntax : trace <who>.\n"); return true; } if (!is_player(who)) { who->printf("You are not a player.\n"); return true; } victim = planet->get(argv[1]); if (!victim) { who->printf("No such player as %s.\n", argv[1]); return true; } if (!who->tracing.get(victim->id)) { who->trace(victim); who->printf("Now tracing %M.\n", victim); } else { who->detrace(victim); who->printf("No longer tracing %M.\n", victim); } return true; } static bool verb_mudcheck(MudObject *player, int argc, const char **argv) { Player *p=dynamic_cast<Player*>(player); if (!p) { return true; } string fn = "mc2."; fn += player->id; fn += "-0"; FILE *badcols = xopen("tmp", fn.c_str(), "w+"); fn = "mc2."; fn += player->id; FILE *f = xopen("tmp", fn.c_str(), "w+"); p->file_divert(f); // fn += "a"; // FILE *pis = xopen("tmp", fn.c_str(), "w+"); // fn += "2"; //FILE *bc2 = xopen("tmp", fn.c_str(), "w+"); MudObject *o; int i; foreach_alpha(planet, o, i) if (!is_player(o) && !o->get_object("cloneof") && o->id[0]!='@') { if (!o->get("zone")) { continue; } #if 0 if (o->get_int("value")!=-1 && o->get_int("cost")!=-1) { player->printf("%s: value %i, cost %i.\n", o->id, o->get_int("value"), o->get_int("cost")); // o->set("cost", (o->get_int("value")*10)/9); o->unset("value"); } continue; #endif #if 0 if (o->get_int("mass")!=-1) { player->printf("%s:%i\n", o->id, o->get_int("mass")); } else if (o->get_int("size")!=-1) { // player->printf("%s : has size not mass.\n", o->id); player->printf("%s:%i\n", o->id, o->get_int("size")*100); continue; #endif #if 0 if (!o->get_flag(FL_ROOM) && !o->get_flag(FL_QUEST) && !o->get_flag(FL_SHIP) && object_depth(o)>2 && !is_mobile(o) && !o->get_flag(FL_FIXED) && !o->get_flag(FL_EXIT)) { if (o->get_flag(FL_CONTAINER) || o->get_flag(FL_WATERTIGHT)) { fprintf(badcols, "stat:%s:%i:%i:%i:%i:%s:%s\n", o->id, o->get_int("mass", o->get_int("size")==-1?-1:o->get_int("size")*100), o->get_int("ovolume"), o->get_int("maxload", o->get_int("capacity")==-1?-1:o->get_int("capacity")*100), o->get_int("volume"), o->get("short"), name(o)); } else { fprintf(badcols, "stat:%s:%i:%i:::%s:%s\n", o->id, o->get_int("mass", o->get_int("size")==-1?-1:o->get_int("size")*100), o->get_int("ovolume"), o->get("short"), name(o)); } } #endif if (int v=o->array_size("virt")) { for (int j=0;j<v;j++) { player->printf("%s - virt.%i (%s) exists.\n", o->id, j, o->array_get("virt", j, "short")); } } if (o->get_object("quarters")) { o->unset("quarters"); } if (const char *n=name(o)) { if (const char *p=strstr(n, ".")) { if (!p[1]) { player->printf("%s - fullstop in name : '%s'\n", o->id, escape_colour(n).c_str()); } } if (strncmp(n, "a pair of", 9)==0 && !o->get_flag(FL_PLURAL)) { player->printf("%s - isn't plural.\n", o->id); } if (strncmp(n, "some ", 4)==0) { player->printf("%s - some.\n", o->id); } } if (!o->get_flag(FL_ROOM) && !o->get_flag(FL_QUEST) && !o->get_flag(FL_SHIP) && object_depth(o)>2) { const char *w = "^o"; if (is_mobile(o)) w = "^P"; if (const char *n=name(o)) { if (!strstr(n, w)) { player->printf("%s - badcol no %s in name : %s.\n", o->id, w, escape_colour(n).c_str()); } } if (const char *n=o->get("short_desc")) { if (!strstr(n, w)) { player->printf("%s - badcol no %s in short_desc : %s.\n", o->id, w, escape_colour(n).c_str()); } } } if (!o->get_flag(FL_MOBILE) && !o->get_flag(FL_FIXED) && !o->get_flag(FL_ROOM) && !o->get_flag(FL_EXIT)) { // o->get_int(" if (o->get_flag(FL_CONTAINER)) { if (o->get_int("maxload")==-1 && o->get_int("capacity")==-1) { player->printf("%s : has neither maxload nor capacity set.\n", o->id); } } if (o->get_int("mass")==-1 && o->get_int("size")==-1) { player->printf("%s : has neither mass nor size set.\n", o->id); #if 0 } else { if (streq(o->get("zone"), "bingo")|| streq(o->get("zone"), "gaz")|| streq(o->get("zone"), "orion")|| streq(o->get("zone"), "holo")|| streq(o->get("zone"), "orange")|| streq(o->get("zone"), "plett")|| streq(o->get("zone"), "secret")) { continue; } set_owner(player, o); p->file_undivert(); xclose(f); return true; #endif } } /* WEAPONS */ if (o->get_int("damage")>0 && o->get_int("wtype")==-1 && !o->get_flag(FL_MOBILE)) { player->printf("%s : is weapon but has no wtype.\n", o->id); } /* EXITS */ if (o->id[0]!='@') { if (o->get_object("link") && !o->get_flag(FL_EXIT) && !o->get_flag(FL_PARTEXIT)) { player->printf("%s : link but not exit.\n", o->id); } if (o->get("link") && !o->get_object("link")) { player->printf("%s : exit dangling, link is %s.\n", o->id, o->get("link")); } } /* MOBILES */ if (is_mobile(o)) { /* NOT HAVING VARIOUS PLAYER-SPECIFIC THINGS */ if (const char *t=o->get("title")) { player->printf("%s : has title %s.\n", o->id, t); } if (o->get_int("level")!=-1) { int l = o->get_int("level"); player->printf("%s : has level %i.\n", o->id, l); } /* GENDER */ const char *g = o->get("gender"); if (g && !strchr("mfanpMFANP", g[0])) { player->printf("%s : has unsupported gender %s.\n", o->id, g); } else if (!g || !*g) { player->printf("%s : has no gender.\n", o->id); } /* DESCRIPTION */ if (!o->get("desc") || streq(o->get("desc"), "A typical mobile...")) { player->printf("%s : missing desc\n", o->id); } /* TELLS */ if (!player->get_flag(FL_NOTELLSPAM)) { if (is_mobile(o) && o->get_int("aggr", 0)==0 && !o->get_flag(FL_CANTTALK) && !o->get_flag(FL_POLICE)) { if (!o->get("tell.name")) { player->printf("%s : no tell.name\n", o->id); } if (!o->get("tell.job")) { player->printf("%s : no tell.job\n", o->id); } if (!o->get("tell.mission")) { player->printf("%s : no tell.mission\n", o->id); } if (!o->get("tell.follow")) { player->printf("%s : no tell.follow\n", o->id); } if (!o->get("tell.help")) { player->printf("%s : no tell.help\n", o->id); } } } } /* QUEST */ if (o->get_flag(FL_QUEST) && !o->get("mname")) { player->printf("%s : no mname\n", o->id); } /* SHOPS */ if (o->get_flag(FL_STORE)) { int max = o->array_size("shop"); for (int i=0;i<max;i++) { MudObject *m = o->array_get_object("shop", i); if (!m) { player->printf("%s : shop.%i - %s left dangling\n", o->id, i, o->array_get("shop", i)); } } if (!o->get_object("shopmob")) { player->printf("%s : shopmob %s bad.\n", o->id, o->get("shopmob")); } if (!o->array_size("tele")) { o->array_set("tele", 0, "template_list_1"); player->printf("%s : shop doesn't have a list as a tele-object.\n", o->id); } } /* BANKS */ if (o->get_flag(FL_BANK)) { MudObject *bankmob=o->get_object("bankmob"); if (!bankmob) { player->printf("%s : bankmob %s bad.\n", o->id, o->get("bankmob")); } else { if (bankmob->get_object("start")!=o) { player->printf("%s : bankmob %s doesn't start at right place.\n", o->id, bankmob->id); } } } /* TELEOBJECTS */ int max = o->array_size("tele"); for (int i=0;i<max;i++) { MudObject *t = o->array_get_object("tele", i); if (t && !t->get_flag(FL_FIXED)) { player->printf("%s : tele.%i is non-Fixed %s.\n", o->id, i, t->id); } if (t && t->get_flag(FL_CONTAINER)) { player->printf("%s : tele.%i is a Container %s.\n", o->id, i, t->id); } } /* AUTOOBJECTS */ max = o->array_size("auto"); for (int i=0;i<max;i++) { MudObject *t = o->array_get_object("auto", i); if (t && t->get_flag(FL_FIXED) && !t->get_flag(FL_CONTAINER) && !t->get_flag(FL_CANSITON) && !t->get_flag(FL_CANOPEN) && t->get_flag(FL_INVISIBLE)) { player->printf("%s : auto.%i is Fixed, non-Container, non-CanSiton, non-CanOpen, Invisible %s.\n", o->id, i, t->id); } } /* ROOMS */ if (is_room(o) && !is_mobile(o) && !is_player(o)) { if (!o->get("desc")) { player->printf("%s : missing desc\n", o->id); } if (const char *d=o->get("desc")) { if (strstr(d, "standing")) fprintf(badcols, "%s : %s\n", o->id, d); } } /* OBJECTS */ if (!is_room(o) && !is_mobile(o) && !o->get_flag(FL_ROOM)) { if (o->get("wornon") && o->get_int("wornlevel")==-1) { player->printf("%s : doesn't have wornlevel set.\n", o->id); } if (const char *sd=o->get("short_desc")) { if (strchr(sd, '.')) { player->printf("%s : has . in short_desc %s\n", o->id, escape_colour(sd).c_str()); } const char *n = name(o); if (n && sd && strcasecmp(n, sd)==0) { player->printf("%s : short_desc and name are the same! ('%s' and '%s')\n", o->id, sd, n); o->unset("short_desc"); } } if (const char *n=name(o)) { if (isupper(n[0])) { player->printf("%s : capital letter starts name %s\n", o->id, n); } } /* DRINK! */ if (o->get_flag(FL_DRINK)) { if (!o->get_object("empty")) { player->printf("%s : doesn't have an empty set.\n", o->id); } if (!o->get_object("substance")) { player->printf("%s : doesn't have a substance set.\n", o->id); } } /* WATERTIGHT CONTAINERS */ #if 0 if (o->get_flag(FL_WATERTIGHT)) { if (o->get_int("volume")==-1) { player->printf("%s : doesn't have volume set.\n", o->id); } } #endif } } p->file_undivert(); xclose(f); xclose(badcols); // xclose(pis); // xclose(bc2); p->spewfile("tmp", fn.c_str(), 1, argc<2?"":argv[1]); return true; } /* * levellock is * * -1 : unlocked * 1 : new characters aren't allowed, level1 are * 2 : level1 chars aren't allowed, level2 are */ static bool verb_levellock(MudObject *who, int argc, const char **argv) { if (argc < 2) { who->printf("Levellock to which level?\n"); return true; } int current = mud->get_int("levellock"); int to = atoi(argv[1]); if (!strcasecmp(argv[1], "off") || to == 0) to = -1; if (current == to) { if (current != -1) who->printf("The mud is already locked at that level.\n"); else who->printf("The mud is already unlocked.\n"); return true; } if (to > privs_of(who)) { who->printf("You can't lock the mud as high as that.\n"); return true; } MudObject *smith = MUD_ANNOUNCER; if (to == -1) { log(PFL_SEEINFO, LEV_INTERNAL, "admin", "mud is declared open"); if (smith) { smith->interpretf("%s The mud is now fully open!", MUD_ANNCH); } } else if (to == 1) { log(PFL_SEEINFO, LEV_INTERNAL, "admin", "new players are locked out"); if (smith) { smith->interpretf("%s New players have been locked out.", MUD_ANNCH); } } else { log(PFL_SEEINFO, LEV_INTERNAL, "admin", "players lower than level %i are locked out", to); if (smith) { smith->interpretf("%s Players ranking %s and lower have been locked out.", MUD_ANNCH, long_rank(to-1)); } } mud->set("levellock", to); return true; } #include "verbmodule.h" void startup() { AUTO_VERB(makefile, 5, 0, PFL_NONE); AUTO_VERB(erasefile, 6, 0, PFL_NONE); AUTO_VERB(torture, 4, 0, PFL_GOD); AUTO_VERB(bans, 4, 0, PFL_BAN); AUTO_VERB(addban, 4, 0, PFL_BAN); AUTO_VERB(remban, 4, 0, PFL_BAN); AUTO_VERB(fds, 3, 0, PFL_HOSTS); AUTO_VERB(modulelist, 4, 0, PFL_NONE); AUTO_VERB(reboot, 6, 0, PFL_CODER, VFL_OKNOOWNER); AUTO_VERB(savezones, 5, 0, PFL_MAKE, VFL_OKNOOWNER); AUTO_VERB(savevar, 5, 0, PFL_MAKE, VFL_OKNOOWNER); AUTO_VERB(reset, 5, 0, PFL_RESET, VFL_OKNOOWNER); AUTO_VERB(rtz, 3, 0, PFL_RESET); AUTO_VERB(shutdown, 5, 0, PFL_SHUTDOWN, VFL_OKNOOWNER); AUTO_VERB(force, 4, 0, PFL_NONE, VFL_OKNOOWNER); AUTO_VERB(mudcheck, 5, 0, PFL_MAKE); ADD_VERB("mudfix", 3, verb_mudcheck, 0, PFL_MAKE); AUTO_VERB(mudcrash, 8, 0, PFL_GOD); AUTO_VERB(magic, 5, 0, PFL_CODER); AUTO_VERB(snoop, 5, 0, PFL_SNOOP); AUTO_VERB(desnoop, 5, 0, PFL_SNOOP); AUTO_VERB(loadflags, 5, 0, PFL_CODER); AUTO_VERB(zap, 3, 0, PFL_ZAP); AUTO_VERB(savethiszone, 5, 0, PFL_MAKE); AUTO_VERB(trace, 5, 0, PFL_TRACE); ADD_ALIAS(stz, 3, savethiszone); AUTO_VERB(levellock, 6, 0, PFL_CODER); }