/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMud ROM Derivative (c) 2001-2004 by Markanth * * http://www.firstmud.com/ <markanth@firstmud.com> * * By using this code you have agreed to follow the term of * * the 1stMud license in ../doc/1stMud/LICENSE * ***************************************************************************/ #include "merc.h" #include "interp.h" #include "data_table.h" #include "recycle.h" #include "tables.h" Proto (bool check_social, (CharData *, char *, const char *)); Proto (bool check_disabled, (CharData *, CmdData *)); Do_Fun (do_null) { chprintln (ch, "This command is nullified, please notify the immortals."); return; } bool cmd_level_ok (CharData * ch, CmdData * cmd) { return (get_trust (ch) >= cmd->level); } void interpret (CharData * ch, const char *argument) { char command[MAX_INPUT_LENGTH]; char logline[MAX_INPUT_LENGTH]; CmdData *cmd; while (isspace (*argument)) argument++; if (NullStr (argument)) return; RemBit (ch->affected_by, AFF_HIDE); if (!IsNPC (ch) && IsSet (ch->act, PLR_FREEZE)) { chprintln (ch, "You're totally frozen!"); return; } crash_info.status = CRASH_PRE_PROCESSING; strcpy (logline, argument); crash_info.desc = ch->desc; strcpy (crash_info.shrt_cmd, logline); sprintf (crash_info.long_cmd, "[%5ld] %s in [%5ld] %s: %s", IsNPC (ch) ? ch->pIndexData->vnum : 0, IsNPC (ch) ? ch->short_descr : ch->name, ch->in_room ? ch->in_room->vnum : 0, ch->in_room ? ch->in_room->name : "(not in a room)", logline); if (!isalpha (argument[0]) && !isdigit (argument[0])) { command[0] = argument[0]; command[1] = '\0'; argument++; while (isspace (*argument)) argument++; } else { argument = one_argument (argument, command); } for (cmd = command_hash[tolower (command[0]) % MAX_CMD_HASH]; cmd; cmd = cmd->next_hash) { if (IsSet (cmd->flags, CMD_NOPREFIX) ? !str_cmp (command, cmd->name) : !str_prefix (command, cmd->name) && cmd_level_ok (ch, cmd)) break; } if (cmd) { if (ch->master && IsSet (cmd->flags, CMD_NO_ORDER)) { act ("You can't order $N to do that!", ch->master, NULL, ch, TO_CHAR); return; } if (cmd->log == LOG_NEVER) strcpy (logline, ""); if ((!IsNPC (ch) && IsSet (ch->act, PLR_LOG)) || IsSet (mud_info.mud_flags, MUD_LOGALL) || cmd->log == LOG_ALWAYS) { new_wiznet (ch, logline, WIZ_SECURE, true, get_trust (ch), "Log $N: $t"); } } if (ch->desc != NULL && ch->desc->snoop_by != NULL) { d_printlnf (ch->desc->snoop_by, "> %s", ch->name, logline); } if (!cmd) { if (!check_social (ch, command, argument) #ifndef DISABLE_I3 && !I3_command_hook (ch, command, argument) #endif ) { char *const huh_message[] = { "Huh?", "Pardon?", "What is command '%s'?", "Input error.", "Try again.", "I do not understand.", "Type commands for a list of commands." }; chprintlnf (ch, huh_message[number_range (0, (sizeof (huh_message) / sizeof (huh_message[0]) - 1))], command); } return; } else if (check_disabled (ch, cmd)) { chprintlnf (ch, "%s has been temporarily disabled.", Upper (cmd->name)); return; } if (ch->position < cmd->position) { switch (ch->position) { case POS_DEAD: chprintln (ch, "Lie still; you are DEAD."); break; case POS_MORTAL: case POS_INCAP: chprintln (ch, "You are hurt far too bad for that."); break; case POS_STUNNED: chprintln (ch, "You are too stunned to do that."); break; case POS_SLEEPING: chprintln (ch, "In your dreams, or what?"); break; case POS_RESTING: chprintln (ch, "Nah... You feel too relaxed..."); break; case POS_SITTING: chprintln (ch, "Better stand up first."); break; case POS_FIGHTING: chprintln (ch, "No way! You are still fighting!"); break; default: break; } return; } crash_info.status = CRASH_LIKELY; (*cmd->do_fun) (cmd->name, ch, argument); crash_info.status = CRASH_POST_PROCESSING; strcat (crash_info.shrt_cmd, " (Finished)"); strcat (crash_info.long_cmd, " (Finished)"); crash_info.status = CRASH_UNLIKELY; tail_chain (); return; } void do_function (CharData * ch, Do_F * do_fun, const char *argument) { const char *command_string; command_string = str_dup (argument); (*do_fun) (cmd_name (do_fun), ch, command_string); free_string (command_string); } SocialData * find_social (const char *command) { SocialData *social; int hash; if (tolower (command[0]) < 'a' || tolower (command[0]) > 'z') hash = 0; else hash = (tolower (command[0]) - 'a') + 1; for (social = social_hash[hash]; social; social = social->next_hash) { if (!str_prefix (command, social->name)) return social; } return NULL; } bool check_social (CharData * ch, char *command, const char *argument) { char arg[MAX_INPUT_LENGTH]; CharData *victim; SocialData *cmd; if ((cmd = find_social (command)) == NULL) return false; if (!IsNPC (ch) && IsSet (ch->comm, COMM_NOEMOTE)) { chprintln (ch, "You are anti-social!"); return true; } switch (ch->position) { case POS_DEAD: chprintln (ch, "Lie still; you are DEAD."); return true; case POS_INCAP: case POS_MORTAL: chprintln (ch, "You are hurt far too bad for that."); return true; case POS_STUNNED: chprintln (ch, "You are too stunned to do that."); return true; case POS_SLEEPING: if (!str_cmp (cmd->name, "snore")) break; chprintln (ch, "In your dreams, or what?"); return true; default: break; } one_argument (argument, arg); victim = NULL; if (NullStr (arg)) { act (cmd->others_no_arg, ch, NULL, victim, TO_ROOM); act (cmd->char_no_arg, ch, NULL, victim, TO_CHAR); } else if ((victim = get_char_room (ch, NULL, arg)) == NULL) { chprintln (ch, "They aren't here."); } else if (victim == ch) { act (cmd->others_auto, ch, NULL, victim, TO_ROOM); act (cmd->char_auto, ch, NULL, victim, TO_CHAR); } else { if (is_ignoring (victim, ch->name, IGNORE_SOCIALS)) { act ("$N is ignoring socials from you.", ch, NULL, victim, TO_CHAR); return true; } act (cmd->others_found, ch, NULL, victim, TO_NOTVICT); act (cmd->char_found, ch, NULL, victim, TO_CHAR); act (cmd->vict_found, ch, NULL, victim, TO_VICT); if (!IsNPC (ch) && IsNPC (victim) && !IsAffected (victim, AFF_CHARM) && IsAwake (victim) && victim->desc == NULL) { switch (number_bits (4)) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: act (cmd->others_found, victim, NULL, ch, TO_NOTVICT); act (cmd->char_found, victim, NULL, ch, TO_CHAR); act (cmd->vict_found, victim, NULL, ch, TO_VICT); break; case 9: case 10: case 11: case 12: act ("$n slaps $N.", victim, NULL, ch, TO_NOTVICT); act ("You slap $N.", victim, NULL, ch, TO_CHAR); act ("$n slaps you.", victim, NULL, ch, TO_VICT); break; } } } return true; } bool is_number (const char *arg) { if (*arg == '\0') return false; if (*arg == '+' || *arg == '-') arg++; for (; *arg != '\0'; arg++) { if (!isdigit (*arg)) return false; } return true; } static unsigned int x_argument (const char *argument, char arg[MAX_INPUT_LENGTH], char c) { char *p; char *q; int number; p = strchr (argument, c); if (p == NULL) { strcpy (arg, argument); return 1; } number = strtoul (argument, &q, 0); if (q != p) number = 0; strncpy (arg, p + 1, MAX_INPUT_LENGTH); return number; } unsigned int number_argument (const char *argument, char *arg) { return x_argument (argument, arg, '.'); } unsigned int mult_argument (const char *argument, char *arg) { return x_argument (argument, arg, '*'); } const char * one_argument (const char *argument, char *arg_first) { char cEnd; while (isspace (*argument)) argument++; cEnd = ' '; if (*argument == '\'' || *argument == '"') cEnd = *argument++; while (*argument != '\0') { if (*argument == cEnd) { argument++; break; } *arg_first = tolower (*argument); arg_first++; argument++; } *arg_first = '\0'; while (isspace (*argument)) argument++; return argument; } Do_Fun (do_commands) { CmdData *cmd; int i = 0; Buffer *b; Column Cd; int cat = NO_FLAG; if (!NullStr (argument) && (cat = (int) flag_value (cmd_categories, argument)) == NO_FLAG) { cmd_syntax (ch, NULL, n_fun, "<flag>", NULL); chprintln (ch, "Valid flags are:"); show_flags (ch, cmd_categories); return; } b = new_buf (); set_cols (&Cd, ch, 6, COLS_BUF, b); for (cmd = cmd_first_sorted; cmd; cmd = cmd->next_sort) { if (cmd->level <= LEVEL_HERO && cmd_level_ok (ch, cmd) && cmd->category != CMDCAT_NOSHOW && (cat == NO_FLAG || cmd->category == (cmd_cat) cat)) { i++; print_cols (&Cd, "%3d. %s", i, cmd->name); } } cols_nl (&Cd); if (i == 0) { if (cat != NO_FLAG) bprintlnf (b, "No commands found in the '%s' category.", flag_string (cmd_categories, cat)); else bprintln (b, "No commands found."); } sendpage (ch, buf_string (b)); free_buf (b); return; } Do_Fun (do_wizhelp) { CmdData *cmd; int i = 0; Column Cd; Buffer *b; b = new_buf (); set_cols (&Cd, ch, 6, COLS_BUF, b); for (cmd = cmd_first_sorted; cmd; cmd = cmd->next_sort) { if (cmd->level >= LEVEL_HERO && cmd_level_ok (ch, cmd) && cmd->category != CMDCAT_NOSHOW) { i++; print_cols (&Cd, "%3d. %s", i, cmd->name); } } cols_nl (&Cd); sendpage (ch, buf_string (b)); free_buf (b); return; } Do_Fun (do_disable) { CmdData *i; DisabledData *p; char arg[MIL]; if (IsNPC (ch)) { chprintln (ch, "RETURN first."); return; } argument = one_argument (argument, arg); if (NullStr (arg)) { if (!disabled_first) { chprintln (ch, "There are no commands disabled."); return; } chprintln (ch, "Disabled commands:" NEWLINE "Command Level Disabled by Disabled for"); for (p = disabled_first; p; p = p->next) { chprintlnf (ch, "%-12s %5d %-12s %s", p->command->name, p->level, p->disabled_by, p->disabled_for); } return; } for (p = disabled_first; p; p = p->next) if (!str_cmp (arg, p->command->name)) break; if (p) { if (get_trust (ch) < p->level) { chprintln (ch, "This command was disabled by a higher power."); return; } UnLink (p, disabled, next, prev); free_disabled (p); rw_disabled_data (act_write); chprintln (ch, "Command enabled."); } else { for (i = command_hash[tolower (arg[0]) % MAX_CMD_HASH]; i; i = i->next_hash) if (!str_cmp (i->name, arg)) break; if (!i) { chprintln (ch, "No such command."); return; } if (i->do_fun == do_disable) { chprintln (ch, "You cannot disable the disable command."); return; } if (i->level > get_trust (ch)) { chprintln (ch, "You don't have access to that command; you cannot disable it."); return; } p = new_disabled (); p->command = i; p->disabled_by = str_dup (ch->name); p->disabled_for = str_dup (argument); p->level = get_trust (ch); Link (p, disabled, next, prev); chprintln (ch, "Command disabled."); rw_disabled_data (act_write); } } bool check_disabled (CharData * ch, CmdData * command) { DisabledData *p; for (p = disabled_first; p; p = p->next) if (p->command->do_fun == command->do_fun) break; if (!p) return false; if (!ch || NullStr (p->disabled_for)) return true; return is_exact_name (ch->name, p->disabled_for); } void cmd_syntax (CharData * ch, const char *title, const char *n_fun, ...) { va_list args; char *str; size_t i; if (NullStr (n_fun) || !ch || !ch->desc) return; va_start (args, n_fun); str = va_arg (args, char *); if (str == NULL) return; if (NullStr (title)) { if (ch->desc->editor != ED_NONE) title = olc_ed_name (ch->desc); else { switch (number_range (1, 3)) { default: case 1: title = "Syntax"; break; case 2: title = "Usage"; break; case 3: title = "Type"; break; } } } i = strlen (title) + 1; chprintlnf (ch, "{W%s: {w%s %s{x", Upper (title), n_fun, str); while ((str = va_arg (args, char *)) != NULL) chprintlnf (ch, "{W%*c {w%s %s{x", i, ':', n_fun, str); va_end (args); } const char * cmd_name (Do_F * dofun) { CmdData *c; for (c = cmd_first; c; c = c->next) if (c->do_fun == dofun) return c->name; return "unknown"; }