/* buildcmds.c */ #include "copyright.h" #include "config.h" #include <stdio.h> #ifdef STRING_H #include <string.h> #else #include <strings.h> #endif /* STRING_H */ #include <ctype.h> #if defined(ALLOCA_H) && !defined(NO_ALLOCA) #include <alloca.h> #endif #include "teeny.h" #include "case.h" #include "strlist.h" /* * Building/Creating commands */ /* Buffer from cmds.c */ extern char cmdwork[]; voidfunc do_create(player, argone) int player; char *argone; { int obj, next, home, here; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (check_quota(player)) { notify_player(player, "Sorry, you're over your limit.\r\n"); return; } if (!argone || !*argone) { notify_player(player, "You need to specify a name.\r\n"); return; } if (!ok_name(argone)) { notify_player(player, "That's a silly name for an object!\r\n"); return; } /* Go to it */ obj = create_obj(TYP_THING); if (set_str_elt(obj, NAME, argone) == -1) goto createbomb; if (set_int_elt(obj, OWNER, player) == -1) goto createbomb; if (set_int_elt(obj, LOC, player) == -1) goto createbomb; if (get_int_elt(player, LOC, &here) == -1) goto createbomb; if (controls(player, here) || isabode(here)) { home = here; } else { if (get_int_elt(player, HOME, &home) == -1) goto createbomb; } if (set_int_elt(obj, HOME, home) == -1) goto createbomb; if (get_int_elt(player, CONTENTS, &next) == -1) goto createbomb; if (set_int_elt(player, CONTENTS, obj) == -1) goto createbomb; if (set_int_elt(obj, NEXT, next) == -1) goto createbomb; stamp(obj); /* Tell the player */ sprintf(cmdwork, "Object %s created with number #%d.\r\n", argone, obj); notify_player(player, cmdwork); return; createbomb: notify_bad(player); return; } voidfunc do_dig(player, arg, argtwo) int player; char *arg; char *argtwo; { int room, parent; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (check_quota(player)) { notify_player(player, "Sorry, you're over your limit.\r\n"); return; } if (!arg || !*arg) { notify_player(player, "You need to specify a name.\r\n"); return; } if (!ok_name(arg)) { notify_player(player, "That's a silly name for a room!\r\n"); return; } if (!argtwo || !*argtwo) { parent = ROOT_PARENT; } else { if (!strcasecmp(argtwo, "root")) parent = ROOT_PARENT; else { if (argtwo[0] != '#' || !argtwo[1] || !isdigit(argtwo[1])) { notify_player(player, "You must specify the parent by number.\r\n"); return; } parent = atoi(argtwo + 1); if (!exists_object(parent)) { notify_player(player, "That parent does not exist.\r\n"); return; } if (!isroom(parent)) { notify_player(player, "Illegal parent.\r\n"); return; } if (!controls(player, parent) && parent != ROOT_PARENT && !isabode(parent)) { notify_player(player, "Permission denied.\r\n"); return; } if (get_int_elt(parent, LOC, &room) == -1) goto digbomb; if (!legal_parent_check(parent, room)) { notify_player(player, "Illegal parent.\r\n"); return; } } } room = create_obj(TYP_ROOM); if (set_int_elt(room, OWNER, player) == -1) goto digbomb; if (set_str_elt(room, NAME, arg) == -1) goto digbomb; if (set_int_elt(room, LOC, parent) == -1) goto digbomb; list_add(room, parent, ROOMS_LIST); stamp(room); /* Tell the player */ sprintf(cmdwork, "Room %s created with number #%d.\r\n", arg, room); notify_player(player, cmdwork); return; digbomb: notify_bad(player); return; } void do_set_string(player, argone, argtwo, code) int player; char *argone; char *argtwo; int code; { int obj, flags; StringList *strs; /* Find the thing to set the string ON */ if (!argone || !*argone) { for (strs = Strings; strs->code && strs->code != code; strs++); if (!strs->code) { /* shouldn't ever happen.. */ notify_player(player, "Set what on what?\r\n"); return; } (void) sprintf(cmdwork, "Set the %c%s string on what?\r\n", DOWNCASE((strs->name)[0]), (strs->name) + 1); notify_player(player, cmdwork); return; } if ((obj = resolve_object(player, argone, 0)) == -1) { if ((obj = resolve_exit(player, argone)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } } if (obj == -2) { notify_player(player, "I don't know which one you mean.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't do that!\r\n"); return; } if (!isplayer(obj)) stamp(obj); /* We *might* be setting a player name. Gotta be careful */ if (code == NAME) { if (argtwo == NULL || *argtwo == 0) { notify_player(player, "You must specify a name.\r\n"); return; } /* Check out the name */ if (get_int_elt(obj, FLAGS, &flags) == -1) { warning("do_set_string", "cannot get flags"); goto namebomb; } if ((flags & TYPE_MASK) == TYP_EXIT) if (!ok_exit_name(argtwo)) { notify_player(player, "Bad exit name.\r\n"); return; } else if (!ok_name(argtwo)) { notify_player(player, "Bad name.\r\n"); return; } if ((flags & TYPE_MASK) == TYP_PLAYER) { char *name, *pword, *givenpwd; /* skip to pwd in given name */ if (parse_name_pwd(argtwo, &name, &givenpwd) == -1) { notify_player(player, "Wrong password.\r\n"); return; } if (!ok_player_name(name)) { notify_player(player, "You can't give a player that name.\r\n"); return; } if (get_str_elt(obj, PASSWORD, &pword) == -1) { goto namebomb; } if (!pword || !*pword) { notify_player(player, "You can't change your name.\r\n"); return; } if (!givenpwd || !*givenpwd) { notify_player(player, "Wrong password.\r\n"); return; } if (strcmp(crypt(givenpwd, CRYPT_KEY), pword) != 0) { notify_player(player, "Wrong password.\r\n"); return; } argtwo = name; } } if (set_str_elt(obj, code, argtwo) == -1) goto namebomb; switch (code) { case NAME: notify_player(player, "Name set.\r\n"); break; case DESC: case IDESC: notify_player(player, "Description set.\r\n"); break; default: notify_player(player, "Message set.\r\n"); } return; namebomb: notify_bad(player); return; } voidfunc do_open(player, argone, argtwo) int player; char *argone; char *argtwo; { int here, exit, list, dest, flags; int source; char *p; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (check_quota(player)) { notify_player(player, "Sorry, you're over your limit.\r\n"); return; } if (!argone || !*argone) { notify_player(player, "You must specify a name.\r\n"); return; } if (!ok_exit_name(argone) && !isgod(player)) { notify_player(player, "That's a silly name for an exit!\r\n"); return; } /* parse for a source object */ for (p = argone; *p && *p != '/'; p++); if (*p == '/') { /* found one */ *p++ = 0; /* terminate argone */ if (*p) { if ((source = resolve_object(player, p, iswiz(player))) == -1) { notify_player(player, "I can't find that source.\r\n"); return; } if (source == -2) { notify_player(player, "I can't tell which source you mean.\r\n"); return; } if (!exists_object(source) || !controls(player, source) || isexit(source)) { notify_player(player, "You can't open an exit on that!\r\n"); return; } } else { notify_player(player, "You need to specify a source.\r\n"); return; } } else { if (get_int_elt(player, LOC, &source) == -1) goto openbomb; #ifndef BUILDING_OK if (!controls(player, source)) { #else if (!controls(player, source) && !isbuildok(source)) { #endif notify_player(player, "You can't open an exit here!\r\n"); return; } } exit = create_obj(TYP_EXIT); if (set_str_elt(exit, NAME, argone) == -1) goto openbomb; if (set_int_elt(exit, OWNER, player) == -1) goto openbomb; if (set_int_elt(exit, LOC, source) == -1) goto openbomb; if (get_int_elt(source, EXITS, &list) == -1) goto openbomb; if (set_int_elt(exit, NEXT, list) == -1) goto openbomb; if (set_int_elt(source, EXITS, exit) == -1) goto openbomb; stamp(exit); /* Tell the player about this exit */ sprintf(cmdwork, "Exit %s opened with number #%d.\r\n", argone, exit); notify_player(player, cmdwork); if (get_int_elt(player, LOC, &here) == -1) goto openbomb; if (argtwo != NULL) { /* Try to link this */ if (strcasecmp(argtwo, "home") == 0) { dest = -3; } else { if ((dest = resolve_object(player, argtwo, iswiz(player))) == -1) { notify_player(player, "I can't find that destination.\r\n"); return; } if (dest == -2) { notify_player(player, "I can't tell which destination you mean.\r\n"); return; } } notify_player(player, "Trying to link...\r\n"); /* Can we link there? */ if (dest != -3 && !exists_object(dest)) { notify_player(player, "Bad destination.\r\n"); return; } if (dest != -3 && get_int_elt(dest, FLAGS, &flags) == -1) { notify_player(player, "Can't find destination.\r\n"); return; } if (dest != -3 && (TYPE_MASK & flags) == TYP_EXIT) { notify_player(player, "You can't link an exit to that!\r\n"); return; } if (!controls(player, dest) && !(flags & LINK_OK)) { notify_player(player, "Can't link to destination.\r\n"); return; } /* OK. We can link there. */ if (set_int_elt(exit, DESTINATION, dest) == -1) goto openbomb; notify_player(player, "Linked.\r\n"); } return; openbomb: notify_bad(player); return; } voidfunc do_link(player, argone, argtwo) int player; char *argone; char *argtwo; { int dest, flags, thing, here; int code, foo, exowner; char *msg; if (!argone || !*argone || !argtwo || !*argtwo) { notify_player(player, "Link what to where?\r\n"); return; } if (get_int_elt(player, LOC, &here) == -1) goto linkbomb; /* Find the destination, thing to link to */ if (!strcasecmp(argtwo, "home")) dest = -3; else { if ((dest = resolve_object(player, argtwo, iswiz(player))) == -1) { notify_player(player, "I can't find that destination.\r\n"); return; } if (dest == -2) { notify_player(player, "I can't tell which destination you mean.\r\n"); return; } } /* Can we link there? */ if (dest != -3 && !exists_object(dest)) { notify_player(player, "Bad destination.\r\n"); return; } if (dest != -3 && get_int_elt(dest, FLAGS, &flags) == -1) { notify_player(player, "Can't find destination.\r\n"); return; } if (dest != -3 && (flags & TYPE_MASK) == TYP_EXIT) { notify_player(player, "You can't link anything to that!\r\n"); return; } /* OK. Try to get the thing to link */ if ((thing = resolve_exit(player, argone)) == -1) { if ((thing = resolve_object(player, argone, 0)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } } if (thing == -2) { notify_player(player, "I can't tell which one you want to link.\r\n"); return; } if (get_int_elt(thing, FLAGS, &flags) == -1) goto linkbomb; switch (flags & TYPE_MASK) { case TYP_PLAYER: case TYP_THING: if (!controls(player, dest) && !isabode(dest)) { notify_player(player, "You can't link that there!\r\n"); return; } break; case TYP_ROOM: case TYP_EXIT: if (!controls(player, dest) && !islinkok(dest)) { notify_player(player, "You can't link that there!\r\n"); return; } } /* What sort of thing is it? */ switch (flags & TYPE_MASK) { case TYP_PLAYER: case TYP_THING: if (dest == -3) { notify_player(player, "Paradox in link of object.\r\n"); return; } msg = "Home set.\r\n"; code = HOME; break; case TYP_ROOM: msg = "Dropto set.\r\n"; code = DROPTO; break; case TYP_EXIT: msg = "Linked.\r\n"; code = DESTINATION; /* Check that the exit is unlinked */ if (get_int_elt(thing, DESTINATION, &foo) == -1) goto linkbomb; if (foo != -1) { notify_player(player, "That exit is linked.\r\n"); return; } else { if (get_int_elt(thing, OWNER, &exowner) == -1) goto linkbomb; if (exowner != player) { #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "Only authorized builders may do that.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (check_quota(player)) { notify_player(player, "Sorry, you're over your limit.\r\n"); return; } } } if (set_int_elt(thing, OWNER, player) == -1) goto linkbomb; notify_player(player, "Trying to link...\r\n"); break; default: notify_player(player, "I don't understand that.\r\n"); warning("do_link", "bad type field detected"); return; } if (!controls(player, thing)) { notify_player(player, "You don't own that!\r\n"); return; } /* Link it up. */ if (set_int_elt(thing, code, dest) == -1) goto linkbomb; notify_player(player, msg); return; linkbomb: notify_bad(player); return; } voidfunc do_unlink(player, arg) int player; char *arg; { int obj, flags, code; char *msg; if (!arg || !*arg) { notify_player(player, "Unlink what?\r\n"); return; } if ((obj = resolve_exit(player, arg)) == -1) { if ((obj = resolve_object(player, arg, 0)) == -1) { notify_player(player, "I can't find that.\r\n"); return; } } if (obj == -2) { notify_player(player, "I can't tell which one you want to unlink.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't unlink that!\r\n"); return; } /* Unlink it. */ if (get_int_elt(obj, FLAGS, &flags) == -1) goto unlinkbomb; switch (flags & TYPE_MASK) { case TYP_PLAYER: case TYP_THING: notify_player(player, "Can't unset an object's home!\r\n"); return; case TYP_EXIT: code = DESTINATION; msg = "Exit unlinked.\r\n"; break; case TYP_ROOM: code = DROPTO; msg = "Dropto unset.\r\n"; break; default: notify_player(player, "I don't understand that.\r\n"); return; } if (set_int_elt(obj, code, -1) == -1) goto unlinkbomb; notify_player(player, msg); return; unlinkbomb: notify_bad(player); return; } /* * the next two routines provide @edit service. yay. the code be based on * code found deep within TinyMUSH, with me own argument parser. */ static int parse_attrib(player, s, thing, atr) int player; char *s; int *thing; int *atr; { char buff[1024]; StringList *strs; strcpy(buff, s); /* get name up to / */ for (s = buff; *s && (*s != '/'); s++); if (!*s) return (0); *s++ = 0; if ((*thing = resolve_anything(player, buff, iswiz(player))) == -1) return (0); if (*thing == -2) return (-2); if (!exists_object(*thing) || !controls(player, *thing)) return (0); /* rest is attrib name */ for (strs = Strings; strs->code; strs++) { if (stringprefix(s, strs->name)) { *atr = strs->code; break; } } if (!strs->code) return (0); if (((*atr == NAME) && isplayer(*thing)) || *atr == SITE || *atr == PASSWORD) return (-1); return (1); } voidfunc do_copy(player, first, second) int player; char *first, *second; { int ret, source, dest, satr, datr; char *p, *buf = NULL, *msg; if (!first || !*first || !second || !*second) { notify_player(player, "Copy what to what?\r\n"); return; } if ((ret = parse_attrib(player, first, &source, &satr)) == 0) { notify_player(player, "No match.\r\n"); return; } if (ret == -2) { notify_player(player, "I can't tell which source object you mean.\r\n"); return; } if (ret != 1) { notify_player(player, "Permission denied.\r\n"); return; } if ((ret = parse_attrib(player, second, &dest, &datr)) == 0) { notify_player(player, "No match.\r\n"); return; } if (ret == -2) { notify_player(player, "I can't tell which destination object you mean.\r\n"); return; } if (ret != 1) { notify_player(player, "Permission denied.\r\n"); return; } if (get_str_elt(source, satr, &p) == -1) { notify_bad(player); return; } if (!p || !*p) { notify_player(player, "Nothing to do.\r\n"); return; } #ifdef NO_ALLOCA buf = (char *) ty_malloc(strlen(p) + 1, "do_copy"); #else buf = (char *) alloca(strlen(p) + 1); #endif (void) strcpy(buf, p); if (set_str_elt(dest, datr, buf) == -1) { notify_bad(player); #ifdef NO_ALLOCA ty_free(buf); #endif return; } #ifdef NO_ALLOCA ty_free(buf); #endif stamp(dest); switch (datr) { case NAME: msg = "Name set.\r\n"; break; case DESC: case IDESC: msg = "Description set.\r\n"; break; default: msg = "Message set.\r\n"; } notify_player(player, msg); } voidfunc do_edit(player, it, args) int player; char *it; char *args; { int thing; int atr, d, len; char *r, *s, *val; char dest[1024], arg1[BUFFSIZ], arg2[BUFFSIZ]; if (!it || !*it) { notify_player(player, "Edit what?\r\n"); return; } d = parse_attrib(player, it, &thing, &atr); if (d == 0) { notify_player(player, "No match.\r\n"); return; } else if (d == -2) { notify_player(player, "I can't tell which one you want to edit.\r\n"); return; } else if (d != 1) { notify_player(player, "Permission denied. You can't change that attribute on that object.\r\n"); return; } /* parse arguments */ if (!args || !*args) { notify_player(player, "Nothing to do.\r\n"); return; } d = 0; /* make arg1 */ /* eat this pointer game, xibo ;-) */ while (d < (BUFFSIZ - 32) && args[0] != 0) { if (args[0] != ',' && args[0] != '\\') { arg1[d] = *args++; d++; } else { if (args[0] == '\\' && args[1] != ',') { arg1[d] = *args++; d++; } else { if (args[0] == '\\' && args[1] == ',') { arg1[d] = args[1]; args += 2; d++; } else { arg1[d] = 0; d++; args++; break; } } } } arg1[d] = 0; /* make arg2 */ d = 0; while (d < (BUFFSIZ - 32) && args[d] != 0) { arg2[d] = args[d]; d++; } arg2[d] = 0; if (arg1[0] == 0) { notify_player(player, "Nothing to do.\r\n"); return; } val = arg1; r = (arg2[0]) ? arg2 : (char *) ""; /* replace all occurances of val with r */ if (get_str_elt(thing, atr, &s) == -1) { warning("do_edit", "bad object ref"); notify_bad(player); return; } if (!s || !*s) { notify_player(player, "Nothing to do.\r\n"); return; } len = strlen(val); for (d = 0; (d < 1000) && *s;) if (strncmp(val, s, len) == 0) { if ((d + strlen(r)) < 1000) { strcpy(dest + d, r); d += strlen(r); s += len; } else dest[d++] = *s++; } else dest[d++] = *s++; dest[d++] = 0; dest[BUFFSIZ - 1] = '\0'; if (set_str_elt(thing, atr, dest) == -1) { warning("do_edit", "failed to store revised string"); notify_bad(player); return; } switch (atr) { case DESC: case IDESC: notify_player(player, "Description set.\r\n"); break; case NAME: notify_player(player, "Name set.\r\n"); break; default: notify_player(player, "Message set.\r\n"); } if (!isplayer(thing)) { stamp(thing); } }