void do_mcpedit(int descr, dbref player, const char *name) { dbref i; struct match_data md; McpFrame *mfr; if (!(mfr = descr_mcpframe(descr))) { do_edit(descr, player, name); return; } else if (Typeof(player) != TYPE_PLAYER) { anotify_nolisten2(player, CFAIL "Only players can edit programs."); return; } else if (!Mucker(player)) { anotify_nolisten2(player, CFAIL NOMBIT_MESG); return; } else if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } else if (!*name) { anotify_nolisten2(player, CINFO "No program name given."); return; } init_match(descr, player, name, TYPE_PROGRAM, &md); match_possession(&md); match_neighbor(&md); match_registered(&md); match_absolute(&md); if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS) return; mcpedit_program(descr, player, i, name, mfr); }
/* Use this to create a program. First, find a program that matches that name. If there's one, then we put him into edit mode and do it. Otherwise, we create a new object for him, and call it a program. */ void do_prog(int descr, dbref player, const char *name) { dbref i; struct match_data md; if (Typeof(player) != TYPE_PLAYER) { anotify_nolisten2(player, CFAIL "Only players can edit programs."); return; } else if (!Mucker(player)) { anotify_nolisten2(player, CFAIL NOMBIT_MESG); return; } else if (!tp_building || tp_db_readonly) { anotify_nolisten2(player, CFAIL NOBUILD_MESG); return; } else if (!*name) { anotify_nolisten2(player, CINFO "No program name given."); return; } init_match(descr, player, name, TYPE_PROGRAM, &md); match_possession(&md); match_neighbor(&md); match_registered(&md); match_absolute(&md); if ((i = match_result(&md)) == NOTHING) { i = new_program(OWNER(player), name); FLAGS(i) |= INTERNAL; DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CSUCC "Program %s created with number %d.", name, i); anotify_nolisten2(player, CINFO "Entering editor."); } else if (i == AMBIGUOUS) { anotify_nolisten2(player, CINFO "I don't know which one you mean!"); return; } else { if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } else if (FLAGS(i) & INTERNAL) { anotify_nolisten2(player, CFAIL NOEDIT_MESG); return; } DBFETCH(i)->sp.program.first = read_program(i); FLAGS(i) |= INTERNAL; DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CINFO "Entering editor for %s.", unparse_object(player, i)); /* list current line */ do_list(player, i, 0, 0, 0); DBDIRTY(i); } FLAGS(player) |= INTERACTIVE; DBDIRTY(player); }
dbref mesg_dbref_raw(int descr, dbref player, dbref what, dbref perms, const char *buf) { struct match_data md; dbref obj = UNKNOWN; if (buf && *buf) { if (!string_compare(buf, "this")) { obj = what; } else if (!string_compare(buf, "me")) { obj = player; } else if (!string_compare(buf, "here")) { obj = getloc(player); } else if (!string_compare(buf, "home")) { obj = HOME; } else { init_match(descr, player, buf, NOTYPE, &md); match_absolute(&md); match_all_exits(&md); match_neighbor(&md); match_possession(&md); match_registered(&md); obj = match_result(&md); if (obj == NOTHING) { init_match_remote(descr, player, what, buf, NOTYPE, &md); match_player(&md); match_all_exits(&md); match_neighbor(&md); match_possession(&md); match_registered(&md); obj = match_result(&md); } } } if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) obj = UNKNOWN; return obj; }
void do_edit(int descr, dbref player, const char *name) { dbref i; struct match_data md; if (Typeof(player) != TYPE_PLAYER) { anotify_nolisten2(player, CFAIL "Only players can edit programs."); return; } else if (!Mucker(player)) { anotify_nolisten2(player, CFAIL NOMBIT_MESG); return; } else if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } else if (!*name) { anotify_nolisten2(player, CINFO "No program name given."); return; } init_match(descr, player, name, TYPE_PROGRAM, &md); match_possession(&md); match_neighbor(&md); match_registered(&md); match_absolute(&md); if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS) return; if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } else if (FLAGS(i) & INTERNAL) { anotify_nolisten2(player, CFAIL NOEDIT_MESG); return; } FLAGS(i) |= INTERNAL; DBFETCH(i)->sp.program.first = read_program(i); DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CINFO "Entering editor for %s.", unparse_object(player, i)); /* list current line */ do_list(player, i, 0, 0, 0); FLAGS(player) |= INTERACTIVE; DBDIRTY(i); DBDIRTY(player); }
void do_give(dbref player, dbref cause, int key, char *who, char *amnt) { dbref recipient; /* check recipient */ init_match(player, who, TYPE_PLAYER); match_neighbor(); match_possession(); match_me(); if (Privilaged(player) || HasPriv(player,NOTHING,POWER_LONG_FINGERS,POWER3,NOTHING)) { match_player(); match_absolute(); } recipient = match_result(); switch (recipient) { case NOTHING: notify(player, "Give to whom?"); return; case AMBIGUOUS: notify(player, "I don't know who you mean!"); return; } if (DePriv(player,recipient,DP_GIVE,POWER7,POWER_LEVEL_SPC)) { notify(player, "Permission denied."); return; } if (DePriv(recipient,player,DP_RECEIVE,POWER7,POWER_LEVEL_SPC)) { notify(player, "Permission denied."); return; } if (is_number(amnt)) { give_money(player, recipient, key, atoi(amnt)); } else if(Guest(recipient)) { notify(player, "Guest really doesn't need money or anything."); return; } else { if ( Typeof(player) != TYPE_ROOM ) give_thing(player, recipient, key, amnt); else notify(player, "Command incompatible with invoker type."); } }
/* * parse_source() * * This is a utility used by do_action and do_attach. It parses * the source string into a dbref, and checks to see that it * exists. * * The return value is the dbref of the source, or NOTHING if an * error occurs. * */ dbref parse_source(int descr, dbref player, const char *source_name) { dbref source; struct match_data md; init_match(descr, player, source_name, NOTYPE, &md); /* source type can be * any */ match_neighbor(&md); match_me(&md); match_here(&md); match_possession(&md); match_registered(&md); match_absolute(&md); source = noisy_match_result(&md); if (source == NOTHING) return NOTHING; /* You can only attach actions to things you control */ if (!controls(player, source)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return NOTHING; } if (Typeof(source) == TYPE_EXIT) { anotify_nolisten2(player, CFAIL "You can't attach an action to an action."); return NOTHING; } if (Typeof(source) == TYPE_PROGRAM) { anotify_nolisten2(player, CFAIL "You can't attach an action to a program."); return NOTHING; } return source; }
void match_and_list(int descr, dbref player, const char *name, char *linespec) { dbref thing; char *p; char *q; int range[2]; int argc; struct match_data md; struct line *tmpline; init_match(descr, player, name, TYPE_PROGRAM, &md); match_neighbor(&md); match_possession(&md); match_registered(&md); match_absolute(&md); if ((thing = noisy_match_result(&md)) == NOTHING) return; if (Typeof(thing) != TYPE_PROGRAM) { notify(player, "You can't list anything but a program."); return; } /* if (!(controls(player, thing) || Linkable(thing))) { */ if (!(controls(player, thing) || (FLAGS(thing) & VEHICLE))) { notify(player, "Permission denied. (You don't control the program, and it's not set Viewable)"); return; } if (!*linespec) { range[0] = 1; range[1] = -1; argc = 2; } else { q = p = linespec; while (*p) { while (*p && !isspace(*p)) *q++ = *p++; while (*p && isspace(*++p)) ; } *q = '\0'; argc = 1; if (isdigit(*linespec)) { range[0] = atoi(linespec); while (*linespec && isdigit(*linespec)) linespec++; } else { range[0] = 1; } if (*linespec) { argc = 2; while (*linespec && !isdigit(*linespec)) linespec++; if (*linespec) range[1] = atoi(linespec); else range[1] = -1; } } tmpline = PROGRAM_FIRST(thing); PROGRAM_SET_FIRST(thing, read_program(thing)); do_list(player, thing, range, argc); free_prog_text(PROGRAM_FIRST(thing)); PROGRAM_SET_FIRST(thing, tmpline); return; }
static void give_thing (dbref giver, dbref recipient, int key, char *what) { dbref thing, loc; char *str, *sp; init_match(giver, what, TYPE_THING); match_possession(); match_me(); thing = match_result(); switch (thing) { case NOTHING: notify(giver, "You don't have that!"); return; case AMBIGUOUS: notify(giver, "I don't know which you mean!"); return; } if (thing == giver) { notify(giver, "You can't give yourself away!"); return; } if (((Typeof(thing) != TYPE_THING) && (Typeof(thing) != TYPE_PLAYER)) || !(Enter_ok(recipient) || controls(giver, recipient))) { notify(giver, "Permission denied."); return; } if ((Flags3(thing) & NOMOVE) && !Wizard(giver)) { notify(giver, "Permission denied."); return; } if (!could_doit(giver, thing, A_LGIVE,1)) { sp = str = alloc_lbuf("do_give.gfail"); safe_str((char *)"You can't give ", str, &sp); safe_str(Name(thing), str, &sp); safe_str((char *)" away.", str, &sp); *sp = '\0'; did_it(giver, thing, A_GFAIL, str, A_OGFAIL, NULL, A_AGFAIL, (char **)NULL, 0); free_lbuf(str); return; } if (!could_doit(thing, recipient, A_LRECEIVE,1)) { sp = str = alloc_lbuf("do_give.rfail"); safe_str(Name(recipient), str, &sp); safe_str((char *)" doesn't want ", str, &sp); safe_str(Name(thing), str, &sp); safe_chr('.', str, &sp); *sp = '\0'; did_it(giver, recipient, A_RFAIL, str, A_ORFAIL, NULL, A_ARFAIL, (char **)NULL, 0); free_lbuf(str); return; } loc = Location(giver); if ( !Good_obj(loc) || loc == NOTHING || loc == AMBIGUOUS || Recover(loc) || Going(loc) ) loc = giver; if (!could_doit(giver, loc, A_LGIVETO, 1)) { sp = str = alloc_lbuf("do_giveto.rfail"); safe_str((char *)"You can not give ", str, &sp); safe_str(Name(thing), str, &sp); safe_str((char *)" away at this location.", str, &sp); *sp = '\0'; notify(giver, str); free_lbuf(str); return; } move_via_generic(thing, recipient, giver, 0); divest_object(thing); if (!(key & GIVE_QUIET)) { str = alloc_lbuf("do_give.thing.ok"); strcpy(str, Name(giver)); notify_with_cause(recipient, giver, unsafe_tprintf("%s gave you %s.", str, Name(thing))); notify(giver, "Given."); notify_with_cause(thing, giver, unsafe_tprintf("%s gave you to %s.", str, Name(recipient))); free_lbuf(str); } else { notify(giver, "Given. (quiet)"); } did_it(giver, thing, A_DROP, NULL, A_ODROP, NULL, A_ADROP, (char **)NULL, 0); did_it(recipient, thing, A_SUCC, NULL, A_OSUCC, NULL, A_ASUCC, (char **)NULL, 0); }
/* do_link * * Use this to link to a room that you own. It also sets home for * objects and things, and drop-to's for rooms. * It seizes ownership of an unlinked exit, and costs 1 penny * plus a penny transferred to the exit owner if they aren't you * * All destinations must either be owned by you, or be LINK_OK. */ void do_link(int descr, dbref player, const char *thing_name, const char *dest_name) { dbref good_dest[MAX_LINKS]; int ndest, i; struct match_data md; char buf[BUFFER_LEN]; dbref thing, dest; if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } if (Guest(player)) { anotify_fmt(player, CFAIL "%s", tp_noguest_mesg); return; } init_match(descr, player, thing_name, TYPE_EXIT, &md); match_all_exits(&md); match_neighbor(&md); match_possession(&md); match_me(&md); match_here(&md); match_absolute(&md); match_registered(&md); if (Mage(OWNER(player))) match_player(&md); if ((thing = noisy_match_result(&md)) == NOTHING) return; switch (Typeof(thing)) { case TYPE_EXIT: /* we're ok, check the usual stuff */ if (DBFETCH(thing)->sp.exit.ndest != 0) { if (controls(player, thing)) { if ((DBFETCH(thing)->sp.exit.dest)[0] != NIL) { anotify_nolisten2(player, CINFO "That exit is already linked."); return; } } else { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } } /* handle costs */ if (OWNER(thing) == OWNER(player)) { if (!payfor(player, tp_link_cost)) { anotify_fmt(player, CFAIL "It costs %d %s to link this exit.", tp_link_cost, (tp_link_cost == 1) ? tp_penny : tp_pennies); return; } } else { if (!payfor(player, tp_link_cost + tp_exit_cost)) { anotify_fmt(player, CFAIL "It costs %d %s to link this exit.", (tp_link_cost + tp_exit_cost), (tp_link_cost + tp_exit_cost == 1) ? tp_penny : tp_pennies); return; } else if (!Builder(player)) { anotify_nolisten2(player, CFAIL NOBBIT_MESG); return; } else { /* pay the owner for his loss */ dbref owner = OWNER(thing); DBFETCH(owner)->sp.player.pennies += tp_exit_cost; DBDIRTY(owner); } } /* link has been validated and paid for; do it */ OWNER(thing) = OWNER(player); if (! (ndest = link_exit(descr, player, thing, (char *) dest_name, good_dest))) { anotify_nolisten2(player, CFAIL "No destinations linked."); DBFETCH(player)->sp.player.pennies += tp_link_cost; /* Refund! */ DBDIRTY(player); break; } DBFETCH(thing)->sp.exit.ndest = ndest; if (DBFETCH(thing)->sp.exit.dest) free(DBFETCH(thing)->sp.exit.dest); DBFETCH(thing)->sp.exit.dest = (dbref *) malloc(sizeof(dbref) * ndest); for (i = 0; i < ndest; i++) (DBFETCH(thing)->sp.exit.dest)[i] = good_dest[i]; break; case TYPE_THING: case TYPE_PLAYER: init_match(descr, player, dest_name, TYPE_ROOM, &md); match_neighbor(&md); match_absolute(&md); match_registered(&md); match_me(&md); match_here(&md); match_null(&md); if (Typeof(thing) == TYPE_THING) match_possession(&md); if ((dest = noisy_match_result(&md)) == NOTHING) return; if (Typeof(thing) == TYPE_THING && dest == NIL) { anotify_fmt(player, CFAIL "%s", "You cannot HOME a THING to NIL."); return; } if (!controls(player, thing) || !can_link_to(player, Typeof(thing), dest)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } if (parent_loop_check(thing, dest)) { anotify_nolisten2(player, CFAIL "That would cause a parent paradox."); return; } /* do the link */ if (Typeof(thing) == TYPE_THING) { DBFETCH(thing)->sp.thing.home = dest; } else DBFETCH(thing)->sp.player.home = dest; sprintf(buf, CSUCC "%s's home set to %s.", NAME(thing), unparse_object(player, dest)); anotify_nolisten2(player, buf); break; case TYPE_ROOM: /* room dropto's */ init_match(descr, player, dest_name, TYPE_ROOM, &md); match_neighbor(&md); match_possession(&md); match_registered(&md); match_absolute(&md); match_home(&md); match_null(&md); if ((dest = noisy_match_result(&md)) == NOTHING) break; if (!controls(player, thing) || !can_link_to(player, Typeof(thing), dest) || (thing == dest)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); } else { DBFETCH(thing)->sp.room.dropto = dest; /* dropto */ sprintf(buf, CSUCC "%s's dropto set to %s.", NAME(thing), unparse_object(player, dest)); anotify_nolisten2(player, buf); } break; case TYPE_PROGRAM: anotify_nolisten2(player, CFAIL "You can't link programs to things!"); break; default: anotify_nolisten2(player, CFAIL "Weird object type."); log_status("*BUG: weird object: Typeof(%d) = %d\n", thing, Typeof(thing)); break; } DBDIRTY(thing); return; }
void do_force(int descr, dbref player, const char *what, char *command) { dbref victim, loc; struct match_data md; assert(what != NULL); assert(command != NULL); assert(player > 0); if (force_level > (tp_max_force_level - 1)) { notify(player, "Can't force recursively."); return; } if (!tp_zombies && (!Wizard(player) || Typeof(player) != TYPE_PLAYER)) { notify(player, "Zombies are not enabled here."); return; #ifdef DEBUG } else { notify(player, "[debug] Zombies are not enabled for nonwizards -- force succeeded."); #endif } /* get victim */ init_match(descr, player, what, NOTYPE, &md); match_neighbor(&md); match_possession(&md); match_me(&md); match_here(&md); match_absolute(&md); match_registered(&md); match_player(&md); if ((victim = noisy_match_result(&md)) == NOTHING) { #ifdef DEBUG notify(player, "[debug] do_force: unable to find your target!"); #endif /* DEBUG */ return; } if (Typeof(victim) != TYPE_PLAYER && Typeof(victim) != TYPE_THING) { notify(player, "Permission Denied -- Target not a player or thing."); return; } #ifdef GOD_PRIV if (God(victim)) { notify(player, "You cannot force God to do anything."); return; } #endif /* GOD_PRIV */ /* if (!controls(player, victim)) { * notify(player, "Permission denied. (you're not a wizard!)"); * return; * } */ if (!Wizard(player) && !(FLAGS(victim) & XFORCIBLE)) { notify(player, "Permission denied: forced object not @set Xforcible."); return; } if (!Wizard(player) && !test_lock_false_default(descr, player, victim, MESGPROP_FLOCK)) { notify(player, "Permission denied: Object not force-locked to you."); return; } loc = getloc(victim); if (!Wizard(player) && Typeof(victim) == TYPE_THING && loc != NOTHING && (FLAGS(loc) & ZOMBIE) && Typeof(loc) == TYPE_ROOM) { notify(player, "Sorry, but that's in a no-puppet zone."); return; } if (!Wizard(OWNER(player)) && Typeof(victim) == TYPE_THING) { const char *ptr = NAME(victim); char objname[BUFFER_LEN], *ptr2; if ((FLAGS(player) & ZOMBIE)) { notify(player, "Permission denied -- you cannot use zombies."); return; } if (FLAGS(victim) & DARK) { notify(player, "Permission denied -- you cannot force dark zombies."); return; } for (ptr2 = objname; *ptr && !isspace(*ptr);) *(ptr2++) = *(ptr++); *ptr2 = '\0'; if (lookup_player(objname) != NOTHING) { notify(player, "Puppet cannot share the name of a player."); return; } } log_status("FORCED: %s(%d) by %s(%d): %s", NAME(victim), victim, NAME(player), player, command); /* force victim to do command */ force_prog=NOTHING; force_level++; process_command(dbref_first_descr(victim), victim, command); force_level--; force_prog=NOTHING; }
void do_teleport(int descr, dbref player, const char *arg1, const char *arg2) { dbref victim; dbref destination; const char *to; struct match_data md; /* get victim, destination */ if (*arg2 == '\0') { victim = player; to = arg1; } else { init_match(descr, player, arg1, NOTYPE, &md); match_neighbor(&md); match_possession(&md); match_me(&md); match_here(&md); match_absolute(&md); match_registered(&md); match_player(&md); if ((victim = noisy_match_result(&md)) == NOTHING) { return; } to = arg2; } #ifdef GOD_PRIV if(tp_strict_god_priv && !God(player) && God(OWNER(victim))) { notify(player, "God has already set that where He wants it to be."); return; } #endif /* get destination */ init_match(descr, player, to, TYPE_PLAYER, &md); match_possession(&md); match_me(&md); match_here(&md); match_home(&md); match_absolute(&md); match_registered(&md); if (Wizard(OWNER(player))) { match_neighbor(&md); match_player(&md); } switch (destination = match_result(&md)) { case NOTHING: notify(player, "Send it where?"); break; case AMBIGUOUS: notify(player, "I don't know which destination you mean!"); break; case HOME: switch (Typeof(victim)) { case TYPE_PLAYER: destination = PLAYER_HOME(victim); if (parent_loop_check(victim, destination)) destination = PLAYER_HOME(OWNER(victim)); break; case TYPE_THING: destination = THING_HOME(victim); if (parent_loop_check(victim, destination)) { destination = PLAYER_HOME(OWNER(victim)); if (parent_loop_check(victim, destination)) { destination = (dbref) 0; } } break; case TYPE_ROOM: destination = GLOBAL_ENVIRONMENT; break; case TYPE_PROGRAM: destination = OWNER(victim); break; default: destination = tp_player_start; /* caught in the next * switch anyway */ break; } default: switch (Typeof(victim)) { case TYPE_PLAYER: if (!controls(player, victim) || !controls(player, destination) || !controls(player, getloc(victim)) || (Typeof(destination) == TYPE_THING && !controls(player, getloc(destination)))) { notify(player, "Permission denied. (must control victim, dest, victim's loc, and dest's loc)"); break; } if (Typeof(destination) != TYPE_ROOM && Typeof(destination) != TYPE_THING) { notify(player, "Bad destination."); break; } if (!Wizard(victim) && (Typeof(destination) == TYPE_THING && !(FLAGS(destination) & VEHICLE))) { notify(player, "Destination object is not a vehicle."); break; } if (parent_loop_check(victim, destination)) { notify(player, "Objects can't contain themselves."); break; } notify(victim, "You feel a wrenching sensation..."); enter_room(descr, victim, destination, DBFETCH(victim)->location); notify(player, "Teleported."); break; case TYPE_THING: if (parent_loop_check(victim, destination)) { notify(player, "You can't make a container contain itself!"); break; } case TYPE_PROGRAM: if (Typeof(destination) != TYPE_ROOM && Typeof(destination) != TYPE_PLAYER && Typeof(destination) != TYPE_THING) { notify(player, "Bad destination."); break; } if (!((controls(player, destination) || can_link_to(player, NOTYPE, destination)) && (controls(player, victim) || controls(player, DBFETCH(victim)->location)))) { notify(player, "Permission denied. (must control dest and be able to link to it, or control dest's loc)"); break; } /* check for non-sticky dropto */ if (Typeof(destination) == TYPE_ROOM && DBFETCH(destination)->sp.room.dropto != NOTHING && !(FLAGS(destination) & STICKY)) destination = DBFETCH(destination)->sp.room.dropto; if (tp_thing_movement && (Typeof(victim) == TYPE_THING)) { enter_room(descr, victim, destination, DBFETCH(victim)->location); } else { moveto(victim, destination); } notify(player, "Teleported."); break; case TYPE_ROOM: if (Typeof(destination) != TYPE_ROOM) { notify(player, "Bad destination."); break; } if (!controls(player, victim) || !can_link_to(player, NOTYPE, destination) || victim == GLOBAL_ENVIRONMENT) { notify(player, "Permission denied. (Can't move #0, dest must be linkable, and must control victim)"); break; } if (parent_loop_check(victim, destination)) { notify(player, "Parent would create a loop."); break; } moveto(victim, destination); notify(player, "Parent set."); break; case TYPE_GARBAGE: notify(player, "That object is in a place where magic cannot reach it."); break; default: notify(player, "You can't teleport that."); break; } break; } return; }