/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.h" #include "mud.h" #include "cmd.h" #include "vars.h" /* standard commands */ extern int cmd_build (); extern int cmd_do (); extern int cmd_drop (); extern int cmd_go (); extern int cmd_help (); /* in cmd.c (this file) */ extern int cmd__if (); extern int cmd_inv (); extern int cmd_look (); extern int cmd_NEWS (); extern int cmd_QUIT (); extern int cmd_WHO (); /* in tcpio.c (net-specific) */ extern int cmd_page (); extern int cmd_password (); extern int cmd__password (); /* wiz-only */ extern int cmd__rand (); extern int cmd_read (); extern int cmd_say (); extern int cmd_set (); /* in vars.c */ extern int cmd_unset (); /* in vars.c */ extern int cmd_take (); extern int cmd_telep (); extern int cmd_use (); extern int cmd_unwear (); extern int cmd_wear (); extern int cmd__wall (); extern int cmd_which (); extern int cmd_whisper (); extern int cmd_destroy (); extern int cmd_examine (); /* wiz internal debug functions */ extern int cmd__dump (); extern int cmd__echo (); extern int cmd__force (); extern int cmd__cacheconfig (); /* in cache.c */ extern int cmd__wizard (); extern int cmd__mark (); extern int cmd__cronconfig (); /* in cron.c */ extern int cmd__mudconfig (); /* in mud.c */ extern int cmd__netconfig (); /* in tcpio.c or whatever net module */ #ifdef COMBAT extern int cmd__combat (); /* in combat.c */ extern int cmd__attack (); /* in combat.c */ extern int cmd_wield (); /* in combat.c */ /* usermode cron stuff */ extern int cmd__cron (); /* in cron.c */ extern int cmd__cronlist (); /* in cron.c */ extern int cmd__crondel (); /* in cron.c */ #endif /* MASTER command table. THIS IS SEARCHED LINEARLY, WHICH IS WHY YOU SHOULD MAKE SURE THAT MOST FREQENTLY USED COMMANDS ARE NEAREST TO THE TOP OF THE TABLE. (linear search is faster in the case of a MUD than a binary search, since we can predict that 90% of ops will fall between emote/say) */ static Cmd ctab[] = { { /* blather something in a TinyMUD-like manner */ "say", 1, CM_EXACT | CM_NOPLY, cmd_say, "say \"string\""}, { /* emote command - TinyMUD-like emote (do and emote are aliases) */ "do", 1, CM_EXACT | CM_NOPLY, cmd_do, "do \"string\""}, { /* look around */ "look", 1, CM_NOFLG, cmd_look, "look [thing1] ..."}, { /* go */ "go", 2, CM_FIXARG | CM_EXACT | CM_NOPLY, cmd_go, "go place"}, { /* whisper */ "whisper", 3, CM_FIXARG | CM_NOPLY, cmd_whisper, "whisper player message"}, { /* page */ "page", 2, CM_NOFLG | CM_NOPLY, cmd_page, "page player [message]"}, { /* echo back to user */ "_echo", 2, CM_NOFLG, cmd__echo, "_echo text"}, { /* inventory */ "inventory", 1, CM_NOFLG, cmd_inv, "inventory [thing] ..."}, { /* take */ "take", 2, CM_NOFLG, cmd_take, "take thing [thing2] ..."}, { /* read text off of something */ "read", 2, CM_FIXARG, cmd_read, "read [thing] ..."}, { /* get - an alias for take */ "get", 2, CM_EXACT, cmd_take, "get thing [thing2] ..."}, { /* drop */ "drop", 2, CM_NOFLG, cmd_drop, "drop thing [thing2] ..."}, { /* examine object(s) */ "examine", 1, CM_NOFLG, cmd_examine, "examine [thing1] ..."}, { "set", 2, CM_EXACT, cmd_set, "set thing [type] attribute value (or \"set help\" for help)"}, { "unset", 3, CM_FIXARG, cmd_unset, "unset thing attribute"}, { /* hold */ "hold", 1, CM_EXACT, cmd_use, "hold thing (or nothing to stop holding current object)"}, { /* use */ "use", 1, CM_EXACT, cmd_use, "use thing (or nothing to stop using current object)"}, { /* wear */ "wear", 2, CM_EXACT | CM_FIXARG, cmd_wear, "wear thing"}, { /* unwear */ "unwear", 2, CM_EXACT | CM_FIXARG, cmd_unwear, "unwear thing"}, #ifdef COMBAT { /* combat various supporting functions */ "_combat", 1, CM_NOPLY, cmd__combat, "_combat [options]"}, { "_attack", 5, CM_NOPLY, cmd__attack, "_attack target attribute value risk [success-string] [failure-string]"}, { /* wield */ "wield", 1, CM_EXACT, cmd_wield, "wield thing (or nothing to stop using current weapon)"}, { /* _cron */ "_cron", 3, CM_EXACT, cmd__cron, "_cron second-count command [repeats] [object-actor]", }, { /* _Ucron */ "_Ucron", 3, CM_EXACT, cmd__cron, "_Ucron second-count command [repeats] [object-actor]", }, { /* _cronlist */ "_cronlist", 1, CM_EXACT | CM_FIXARG, cmd__cronlist, "_cronlist", }, { /* _crondel */ "_crondel", 2, CM_EXACT | CM_FIXARG, cmd__crondel, "_crondel event", }, #endif { /* create a new ?? */ #ifdef BUILD_WIZ_ONLY "build", 2, CM_PRIV, cmd_build, #else "build", 2, CM_NOFLG, cmd_build, #endif "build object-type [object-specific options] (or \"build help\")"}, { /* which */ "which", 2, CM_NOFLG, cmd_which, "which [object-type] thing-to-match"}, { /* randomly pick a command */ "_rand", 2, CM_NOFLG, cmd__rand, "_rand [cmd1] [cmd2] [...cmdN]"}, { /* conditional (of sorts) */ "_if", 2, CM_NOFLG, cmd__if, "_if boolean-expression cmd [\"else\" cmd]"}, { /* teleport */ "teleport", 3, CM_FIXARG, cmd_telep, "teleport [thing] [destination]"}, { /* destroy an object ; command name must match exactly */ #ifdef BUILD_WIZ_ONLY "destroy", 2, CM_EXACT | CM_PRIV, cmd_destroy, #else "destroy", 2, CM_EXACT, cmd_destroy, #endif "destroy object-type object (or \"destroy help\")"}, { /* NEWS */ "NEWS", 1, CM_NOFLG | CM_NOPLY, cmd_NEWS, "NEWS [action] [article] (or \"NEWS help\")"}, { /* QUIT command */ "QUIT", 1, CM_EXACT | CM_NOWHERE, cmd_QUIT, "QUIT"}, { /* WHO command */ "WHO", 1, CM_NOWHERE, cmd_WHO, "WHO [who] ..."}, { /* dump command list/summary */ "help", 1, CM_NOWHERE, cmd_help, "help [cmd] ..."}, { /* dump object to controlling terminal in OIF format */ "_dump", 2, CM_NOFLG, cmd__dump, "_dump objid"}, { /* submit a command as someone else */ "_force", 3, CM_PRIV, cmd__force, "_force who command"}, { /* shout */ "_wall", 1, CM_PRIV, cmd__wall, "_wall message"}, { /* set a thing's password */ "password", 3, CM_FIXARG, cmd_password, "password oldpassword newpassword"}, { /* wiz set a thing's password */ "_password", 3, CM_FIXARG | CM_PRIV, cmd__password, "_password thing password"}, { /* cache-specific commands [implementation dependent] */ "_cacheconfig", 2, CM_PRIV, cmd__cacheconfig, "_cacheconfig [options] (or \"_cacheconfig help\")"}, { /* permanent database specific commands [implementation dependent] */ "_dbconfig", 2, CM_PRIV, CMD__DBCONFIG, "_dbconfig [options] (or \"_dbconfig help\")"}, { /* output a text mark for 'bots. echo back first arg with an '@' */ "_mark", 1, CM_NOFLG, cmd__mark, "_mark \"string\""}, { /* mud server specific commands [somewhat implementation dependent] */ "_mudconfig", 2, CM_PRIV | CM_NOWHERE, cmd__mudconfig, "_mudconfig [options] (or \"_mudconfig help\")"}, { /* cron execution specific commands [somewhat implementation dependent] */ "_cronconfig", 2, CM_PRIV | CM_NOWHERE, cmd__cronconfig, "_cronconfig [options] (or \"_cronconfig help\")"}, { /* network layer specific commands [somewhat implementation dependent] */ "_netconfig", 2, CM_PRIV, cmd__netconfig, "_netconfig [options] (or \"_netconfig help\")"}, { /* wizard management */ "_wizard", 2, CM_NOFLG, cmd__wizard, "_wizard [options] (or \"_wizard help\")"}, /* list terminator */ {NULL, 0, 0, NULL, NULL} }; Cmd *cmdlookup (char *s) { Cmd *p = ctab; size_t x; x = strlen (s); while (p->name != (char *) 0) { if ((p->flgs & CM_EXACT) && *s == *p->name && !strcmp (s, p->name)) return (p); if (!(p->flgs & CM_EXACT) && *s == *p->name && !strncmp (s, p->name, x)) return (p); p++; } return (0); } Cmd *u_cmdlookup (char *s) { Cmd *ret; for (ret = ctab; ret->name != (char *) 0; ret++) if (!strcmp (s, ret->name)) return (ret); return ((Cmd *) 0); } /* ARGSUSED */ int cmd_help (int argc, char *argv[], char *who, char *aswho) { Cmd *p = ctab; int x; int wiz; wiz = ut_flagged (who, var_wiz); if (argc <= 1) { while (p->name != (char *) 0) { if (wiz || !(p->flgs & CM_PRIV)) say (who, p->usage, "\n", (char *) 0); p++; } return (0); } for (x = 1; x < argc; x++) { char fnuf[MAXPATHLEN]; char *jnk; jnk = argv[x]; while ((jnk = strchr (jnk, '.')) != (char *) 0) { if (*(jnk + 1) == '.') { say (who, "nice try: \"", argv[x], "\"\n", (char *) 0); return (1); } jnk++; } if (strlen (argv[x]) >= MAXPATHLEN) { say (who, "impossible command: \"", argv[x], "\"\n", (char *) 0); continue; } snprintf (fnuf, sizeof (fnuf), "HELP/%s", argv[x]); if ((p = cmdlookup (argv[x])) != (Cmd *) 0) { if (wiz || !(p->flgs & CM_PRIV)) { say (who, "usage: ", p->usage, "\n", (char *) 0); } if (say_file (who, fnuf)) say (who, "no help file available.\n", (char *) 0); } else { if (say_file (who, fnuf)) say (who, "unknown command: \"", argv[x], "\"\n", (char *) 0); } } return (0); }