/* override.c * code for overriding commands and functions */ #include "copyright.h" #include "autoconf.h" #include "externs.h" #include "command.h" #include "functions.h" static int FDECL(contains, (char *, char *)); static void FDECL(ovr_list, (dbref, dbref, int)); /* split_token: Get next token from string as null-term string. String is * destructively modified. */ static char * split_token(sp, sep) char **sp, sep; { char *str, *save; save = str = *sp; if (!str) { *sp = NULL; return NULL; } while (*str && (*str != sep)) str++; if (*str) { *str++ = '\0'; if (sep == ' ') { while (*str == sep) str++; } } else { str = NULL; } *sp = str; return save; } /* do_override: override a command or function * Alloy [2-25-96] */ void do_override(player, cause, key, arg1, arg2) dbref player, cause; int key; char *arg1, *arg2; { CMDENT *cmd; FUN *func; char *what, *name, *atr, *buff, *t, *newbuff, *nbp, *sav; dbref object; int attr, abort = 0, clear = 0; /* can't have local user functions yet */ if (key & OVR_FUNCTION) key |= OVR_GLOBAL; /* set what and object correctly for the override type */ if (key & OVR_GLOBAL) { if (!Good_obj(mudconf.master_room)) { notify_quiet(player, "You must enable the master room to use @override/global."); return; } what = arg1; object = mudconf.master_room; } else { if (!arg1 || !*arg1) { notify_quiet(player, "Override where?"); return; } what = arg2; init_match(player, arg1, TYPE_ZONE); match_everything(0); object = noisy_match_result(); if (!Good_obj(object)) { return; } else if (!isZone(object)) { notify_quiet(player, "You must specify a zone in which to override."); return; } } /* maybe they want to list */ if (!what || !*what) { if (key & OVR_GLOBAL) notify(player, "Overridden globally:"); else notify(player, tprintf("Overridden in %s:", unparse_object(player, object, 0))); ovr_list(player, object, 0); ovr_list(player, object, 1); return; } /* no, so match the command or function */ if (*what == NOT_TOKEN) { clear = 1; what++; } for (t = what; *t; t++) *t = ToLower(*t); key &= ~OVR_GLOBAL; if (key == OVR_CMD) { attr = A_OVR_CMD; cmd = (CMDENT *) hashfind(what, &mudstate.command_htab); if (!cmd) { notify_quiet(player, "No such command."); return; } name = cmd->cmdname; /* make sure they don't override @override! */ if (!string_compare(cmd->cmdname, "@override")) { notify_quiet(player, "You can't override the @override command!"); return; } } else { attr = A_OVR_FUNC; func = (FUN *) hashfind(what, &mudstate.func_htab); if (!func) { notify_quiet(player, "No such function."); return; } name = (char *) func->name; } /* now stick it in the attribute */ atr = atr_get_raw(object, attr); sav = nbp = buff = alloc_lbuf("do_override.buff"); safe_str(atr, buff, &nbp); nbp = newbuff = alloc_lbuf("do_override.newbuff"); if (!clear) { while (t = split_token(&buff, ' ')) { if (!string_compare(t, name)) abort = 1; if (nbp != newbuff) safe_chr(' ', newbuff, &nbp); safe_str(t, newbuff, &nbp); } if (nbp != newbuff) safe_chr(' ', newbuff, &nbp); safe_str(name, newbuff, &nbp); } else { abort = 1; while (t = split_token(&buff, ' ')) { if (!string_compare(t, name)) { abort = 0; } else { if (nbp != newbuff) safe_chr(' ', newbuff, &nbp); safe_str(t, newbuff, &nbp); } } } free_lbuf(sav); if (abort) { notify_quiet(player, tprintf("That has %s been overridden.", clear ? "not" : "already")); return; } atr_add_raw(object, attr, newbuff); free_lbuf(newbuff); notify(player, clear ? "Overridden." : "Enabled."); } /* is_overridden: should this builtin command/function be ignored? */ int is_overridden(player, cmd, type) dbref player; char *cmd; int type; { char *atr, c[SBUF_SIZE], *p; dbref loc; strcpy(c, cmd); for (p = c; *p; p++) *p = ToLower(*p); loc = Location(player); if (Good_obj(loc) && Good_obj(Zone(loc))) { atr = atr_get_raw(Zone(loc), type); if (atr && *atr && contains(atr, c)) return 1; } loc = mudconf.master_room; if (!Good_obj(loc)) return 0; atr = atr_get_raw(loc, type); if (!atr || !*atr) return 0; return contains(atr, c); } /* contains: does str contain item? */ static int contains(str, item) char *str, *item; { char *buff, *t, *sav; int count = 0; if (!str || !*str) return 0; t = sav = buff = alloc_lbuf("contains"); safe_str(str, buff, &t); do { t = split_token(&buff, ' '); if (!string_compare(t, item)) count++; } while (buff); free_lbuf(sav); return count; } /* ovr_list: list functions/commands that are overridden */ static void ovr_list(player, loc, func) dbref player, loc; int func; { char *atr, *out, *p, *t; p = out = alloc_lbuf("ovr_list.out"); safe_str(func ? " Functions: " : " Commands: ", out, &p); atr = atr_get_raw(loc, func ? A_OVR_FUNC : A_OVR_CMD); if (!atr || !*atr) safe_str((char *) "(none)", out, &p); else safe_str(atr, out, &p); notify(player, out); free_lbuf(out); }