/* * This file handles command interpreting */ #include <sys/types.h> #include <stdio.h> /* include main header file */ #include "mud.h" #include "utils.h" #include "character.h" #include "socket.h" #include "room.h" #include "movement.h" // for try_move_special #include "commands.h" #include "action.h" //***************************************************************************** // mandatory modules //***************************************************************************** #include "scripts/scripts.h" //***************************************************************************** // optional modules //***************************************************************************** #ifdef MODULE_FACULTY #include "faculty/faculty.h" #endif #ifdef MODULE_ALIAS #include "alias/alias.h" #endif //***************************************************************************** // local variables and functions //***************************************************************************** NEAR_MAP *cmd_table = NULL; void init_commands() { cmd_table = newNearMap(); //*************************************************************************** // This is for core functions ONLY! If you have a module that adds new // functions to the MUD, they should be added in the init_xxx() function // associated with your module. //*************************************************************************** add_cmd("north", "n", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("east", "e", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("south", "s", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("west", "w", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("up", "u", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("down", "d", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("northeast", "na", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("southeast", "sa", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("southwest", "sb", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("northwest", "nb", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("ne", "ne", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("se", "se", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("sw", "sw", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("nw", "nw", cmd_move, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); // A add_cmd("approach", NULL, cmd_greet, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("ask", NULL, cmd_ask, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd("at", NULL, cmd_at, POS_UNCONCIOUS, POS_FLYING, "builder", TRUE, FALSE); // B add_cmd("back", NULL, cmd_back, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); // C add_cmd("chat", NULL, cmd_chat, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("clear", NULL, cmd_clear, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("close", NULL, cmd_close, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("commands", NULL, cmd_commands, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("compress", NULL, cmd_compress, POS_UNCONCIOUS, POS_FLYING, "player", FALSE, FALSE); add_cmd("copyover", NULL, cmd_copyover, POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, TRUE); // D add_cmd("delay", NULL, cmd_delay, POS_SLEEPING, POS_FLYING, "player", TRUE, FALSE); add_cmd("drop", NULL, cmd_drop, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); // E add_cmd("emote", NULL, cmd_emote, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd(":", NULL, cmd_emote, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd("equipment", NULL, cmd_equipment,POS_SITTING, POS_FLYING, "player", TRUE, FALSE); // F add_cmd("force", NULL, cmd_force, POS_STANDING, POS_FLYING, "admin", FALSE, FALSE); // G add_cmd("gemote", NULL, cmd_gemote, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("give", NULL, cmd_give, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("gossip", NULL, cmd_chat, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("\"", NULL, cmd_chat, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("greet", NULL, cmd_greet, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("get", NULL, cmd_get, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("goto", NULL, cmd_goto, POS_STANDING, POS_FLYING, "builder", FALSE, TRUE ); add_cmd("groupcmds", NULL, cmd_groupcmds,POS_UNCONCIOUS, POS_FLYING, "player", FALSE, FALSE); // I add_cmd("inventory", NULL, cmd_inventory,POS_SITTING, POS_FLYING, "player", TRUE, FALSE); // L add_cmd("look", "l", cmd_look, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd("lock", NULL, cmd_lock, POS_STANDING, POS_FLYING, "player", TRUE, TRUE); add_cmd("land", NULL, cmd_stand, POS_FLYING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("load", NULL, cmd_load, POS_SITTING, POS_FLYING, "builder", FALSE, FALSE); add_cmd("linkdead", NULL, cmd_linkdead, POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, FALSE); add_cmd("lockdown", NULL, cmd_lockdown, POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, FALSE); // M add_cmd("mlist", NULL, cmd_mlist, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("mdelete", NULL, cmd_mdelete, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("mrename", NULL, cmd_mrename, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("more", NULL, cmd_more, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("motd", NULL, cmd_motd, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); // O add_cmd("olist", NULL, cmd_olist, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("odelete", NULL, cmd_odelete, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("orename", NULL, cmd_orename, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("open", NULL, cmd_open, POS_STANDING, POS_FLYING, "player", TRUE, TRUE ); // P add_cmd("put", "p", cmd_put, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("page", NULL, cmd_page, POS_SITTING, POS_FLYING, "builder", TRUE, FALSE); add_cmd("purge", NULL, cmd_purge, POS_SITTING, POS_FLYING, "builder", FALSE, FALSE); add_cmd("pulserate", NULL, cmd_pulserate,POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, FALSE); // Q add_cmd("quit", NULL, cmd_quit, POS_SLEEPING, POS_FLYING, "player", FALSE, TRUE ); // R add_cmd("rreload", NULL, cmd_rreload, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("remove", NULL, cmd_remove, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("repeat", NULL, cmd_repeat, POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, FALSE); add_cmd("rlist", NULL, cmd_rlist, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("rdelete", NULL, cmd_rdelete, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); add_cmd("rrename", NULL, cmd_rrename, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); // S add_cmd("say", NULL, cmd_say, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd("'", NULL, cmd_say, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); add_cmd("save", NULL, cmd_save, POS_SLEEPING, POS_FLYING, "player", FALSE, FALSE); add_cmd("shutdown", NULL, cmd_shutdown, POS_UNCONCIOUS, POS_FLYING, "admin", FALSE, TRUE ); add_cmd("sit", NULL, cmd_sit, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("sleep", NULL, cmd_sleep, POS_SITTING, POS_STANDING, "player", TRUE, FALSE); add_cmd("stand", NULL, cmd_stand, POS_SITTING, POS_STANDING, "player", TRUE, TRUE ); add_cmd("stop", NULL, cmd_stop, POS_SITTING, POS_FLYING, "player", TRUE, FALSE); // T add_cmd("take", NULL, cmd_get, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("tell", NULL, cmd_tell, POS_SLEEPING, POS_FLYING, "player", TRUE, FALSE); add_cmd("transfer", NULL, cmd_transfer, POS_STANDING, POS_FLYING, "builder", FALSE, TRUE); // U add_cmd("unlock", NULL, cmd_unlock, POS_STANDING, POS_FLYING, "player", TRUE, TRUE); // W add_cmd("wake", NULL, cmd_wake, POS_SLEEPING, POS_SLEEPING, "player", TRUE, TRUE ); add_cmd("wear", NULL, cmd_wear, POS_SITTING, POS_FLYING, "player", TRUE, TRUE ); add_cmd("who", NULL, cmd_who, POS_UNCONCIOUS, POS_FLYING, "player", TRUE, FALSE); add_cmd("worn", NULL, cmd_equipment,POS_SITTING, POS_FLYING, "player", TRUE, FALSE); // Z add_cmd("zlist", NULL, cmd_zlist, POS_SITTING, POS_FLYING, "builder", FALSE, TRUE); add_cmd("zreset", NULL, cmd_zreset, POS_UNCONCIOUS, POS_FLYING, "builder", FALSE, FALSE); } bool cmd_exists(const char *cmd) { return nearMapKeyExists(cmd_table, cmd); } void remove_cmd(const char *cmd) { CMD_DATA *old_cmd = nearMapRemove(cmd_table, cmd); if(old_cmd) deleteCmd(old_cmd); } void add_cmd(const char *cmd, const char *sort_by, COMMAND(func), int min_pos, int max_pos, const char *user_group, bool mob_ok, bool interrupts) { // if we've already got a command named this, remove it remove_cmd(cmd); // add in the new command nearMapPut(cmd_table, cmd, sort_by, newCmd(cmd, func, min_pos, max_pos, user_group, mob_ok, interrupts)); } void add_py_cmd(const char *cmd, const char *sort_by, void *pyfunc, int min_pos, int max_pos, const char *user_group, bool mob_ok, bool interrupts) { // if we've already got a command named this, remove it remove_cmd(cmd); // add in the new command nearMapPut(cmd_table, cmd, sort_by, newPyCmd(cmd, pyfunc, min_pos, max_pos, user_group, mob_ok, interrupts)); } // show the character all of the commands in the specified group(s). void show_commands(CHAR_DATA *ch, const char *user_groups) { BUFFER *buf = newBuffer(MAX_BUFFER); NEAR_ITERATOR *near_i = newNearIterator(cmd_table); const char *abbrev = NULL; CMD_DATA *cmd = NULL; int col = 0; // go over all of our buckets ITERATE_NEARMAP(abbrev, cmd, near_i) { if(is_keyword(user_groups, cmdGetUserGroup(cmd), FALSE)) { bprintf(buf, "%-13.13s", cmdGetName(cmd)); if (!(++col % 6)) bufferCat(buf, "\r\n"); } } deleteNearIterator(near_i); // tag on our last newline if neccessary, and show commands if (col % 6) bprintf(buf, "\r\n"); text_to_char(ch, bufferString(buf)); deleteBuffer(buf); } // tries to pull a usable command from the near-table and use it. Returns // TRUE if a usable command was found (even if it failed) and false otherwise. bool try_use_cmd_table(CHAR_DATA *ch, NEAR_MAP *table, const char *command, char *arg, bool abbrev_ok) { if(abbrev_ok == FALSE) { CMD_DATA *cmd = nearMapGet(table, command, FALSE); if(cmd == NULL || !is_keyword(bitvectorGetBits(charGetUserGroups(ch)), cmdGetUserGroup(cmd), FALSE)) return FALSE; else { charTryCmd(ch, cmd, arg); return TRUE; } } else { // try to look up the possible commands LIST *cmd_list = nearMapGetAllMatches(table, command); bool cmd_found = FALSE; if(cmd_list != NULL) { LIST_ITERATOR *cmd_i = newListIterator(cmd_list); CMD_DATA *cmd = NULL; ITERATE_LIST(cmd, cmd_i) { if(is_keyword(bitvectorGetBits(charGetUserGroups(ch)), cmdGetUserGroup(cmd), FALSE)) { charTryCmd(ch, cmd, arg); cmd_found = TRUE; break; } } deleteListIterator(cmd_i); deleteList(cmd_list); } return cmd_found; } } void handle_cmd_input(SOCKET_DATA *dsock, char *arg) { CHAR_DATA *ch; if ((ch = socketGetChar(dsock)) == NULL) return; do_cmd(ch, arg, TRUE); } void do_cmd(CHAR_DATA *ch, char *arg, bool aliases_ok) { char command[MAX_BUFFER]; // make sure we've got a command to try if(!arg || !*arg) return; // if we are leading with a non-character, we are trying to do a short-form // command (e.g. ' for say, " for gossip). Just take the first character // and use the rest as the arg if(isalpha(*arg) || isdigit(*arg)) arg = one_arg(arg, command); else { *command = *arg; *(command+1) = '\0'; arg++; // and skip all spaces while(isspace(*arg)) arg++; } #ifdef MODULE_ALIAS if(aliases_ok && try_alias(ch, command, arg)) return; #endif // check to see if it's a faculty command #ifdef MODULE_FACULTY if(try_use_faculty(ch, command)) return; #endif // first try room commands then world commands if(!try_use_cmd_table(ch,roomGetCmdTable(charGetRoom(ch)),command,arg,FALSE)) if(!try_use_cmd_table(ch, cmd_table, command, arg, TRUE)) text_to_char(ch, "No such command.\r\n"); }