/************************************************************************** * 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; } strcpy(logline, argument); 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?{x", "{?Pardon?{x", "{?What is command '%s'?{x", "{?Input error.{x", "{?Try again.{x", "{?I do not understand.{x", "{?Type commands for a list of commands.{x" }; 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; } (*cmd->do_fun) (cmd->name, ch, argument); 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 | TO_SOCIALS); act(cmd->char_no_arg, ch, NULL, victim, TO_CHAR | TO_SOCIALS); } 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 | TO_SOCIALS); act(cmd->char_auto, ch, NULL, victim, TO_CHAR | TO_SOCIALS); } else { if (is_ignoring(victim, ch->name, IGNORE_SOCIALS)) { act("$N is ignoring socials from you.", ch, NULL, victim, TO_CHAR | TO_SOCIALS); return true; } act(cmd->others_found, ch, NULL, victim, TO_NOTVICT | TO_SOCIALS); act(cmd->char_found, ch, NULL, victim, TO_CHAR | TO_SOCIALS); act(cmd->vict_found, ch, NULL, victim, TO_VICT | TO_SOCIALS); 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 | TO_SOCIALS); act(cmd->char_found, victim, NULL, ch, TO_CHAR | TO_SOCIALS); act(cmd->vict_found, victim, NULL, ch, TO_VICT | TO_SOCIALS); break; case 9: case 10: case 11: case 12: act("$n slaps $N.", victim, NULL, ch, TO_NOTVICT | TO_SOCIALS); act("You slap $N.", victim, NULL, ch, TO_CHAR | TO_SOCIALS); act("$n slaps you.", victim, NULL, ch, TO_VICT | TO_SOCIALS); 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"; }