Exemple #1
0
void do_kill (dbref player, dbref cause, int key, char *what, char *costchar)
{
dbref	victim;
char	*buf1, *buf2;
int	cost;

	init_match(player, what, TYPE_PLAYER);
	match_neighbor();
	match_me();
	match_here();
	if (Wizard(player)) {
		match_player();
		match_absolute();
	}
	victim = match_result();

	switch (victim) {
	case NOTHING:
		notify(player, "I don't see that player here.");
		break;
	case AMBIGUOUS:
		notify(player, "I don't know who you mean!");
		break;
	default:
		if ((Typeof(victim) != TYPE_PLAYER) &&
		    (Typeof(victim) != TYPE_THING)) {
			notify(player,
				"Sorry, you can only kill players and things.");
			break;
		}
		if ((Haven(Location(victim)) && !Wizard(player)) ||
		    (controls(victim, Location(victim)) &&
		     !controls(player, Location(victim))) ||
		    Immortal(victim)) {
			notify(player, "Sorry.");
			break;
		}
		if (key == KILL_SLAY) {
		  if (Builder(player) && Builder(victim)) {
			notify(player, "Sorry.");
			break;
		  }
		}

		/* go for it */

		cost = atoi(costchar);
		if (key == KILL_KILL) {
			if (HasPriv(victim,player,POWER_NOKILL,POWER4,NOTHING)) {
			  notify(player, "Sorry.");
			  break;
			}
			if (cost < mudconf.killmin)
				cost = mudconf.killmin;
			if (cost > mudconf.killmax)
				cost = mudconf.killmax;

			/* see if it works */

			if (!payfor(player, cost)) {
				notify(player,
					unsafe_tprintf("You don't have enough %s.",
						mudconf.many_coins));
				return;
			}
		} else {
			cost = 0;
		}

		if (!(((random() % mudconf.killguarantee) < cost) ||
		      (key == KILL_SLAY)) ||
		    Wizard(victim)) {

			/* Failure: notify player and victim only */

			notify(player, "Your murder attempt failed.");
			buf1 = alloc_lbuf("do_kill.failed");
			sprintf(buf1, "%s tried to kill you!", Name(player));
			notify_with_cause(victim, player, buf1);
			if (Suspect(player)) {
				strcpy(buf1, Name(player));
				if (player == Owner(player)) {
					raw_broadcast(0, WIZARD,
						"[Suspect] %s tried to kill %s(#%d).",
						buf1, Name(victim), victim);
				} else {
					buf2 = alloc_lbuf("do_kill.SUSP.failed");
					strcpy(buf2, Name(Owner(player)));
					raw_broadcast(0, WIZARD,
						"[Suspect] %s <via %s(#%d)> tried to kill %s(#%d).",
						buf2, buf1, player,
						Name(victim), victim);
					free_lbuf(buf2);
				}
			}
			free_lbuf(buf1);
			break;
		}

		/* Success!  You killed him */

		buf1 = alloc_lbuf("do_kill.succ.1");
		buf2 = alloc_lbuf("do_kill.succ.2");
		if (Suspect(player)) {
			strcpy(buf1, Name(player));
			if (player == Owner(player)) {
				raw_broadcast(0, WIZARD,
					"[Suspect] %s killed %s(#%d).",
					buf1, Name(victim), victim);
			} else {
				strcpy(buf2, Name(Owner(player)));
				raw_broadcast(0, WIZARD,
					"[Suspect] %s <via %s(#%d)> killed %s(#%d).",
					buf2, buf1, player, Name(victim),
					victim);
			}
		}
		sprintf(buf1, "You killed %s!", Name(victim));
		sprintf(buf2, "killed %s!", Name(victim));
		if (Typeof(victim) != TYPE_PLAYER)
			if (halt_que(NOTHING, victim) > 0)
				if (!Quiet(victim))
					notify(Owner(victim), "Halted.");
		did_it(player, victim, A_KILL, buf1, A_OKILL, buf2, A_AKILL,
			(char **)NULL, 0);

		/* notify victim */

		sprintf(buf1, "%s killed you!", Name(player));
		notify_with_cause(victim, player, buf1);

		/* Pay off the bonus */

		if (key == KILL_KILL) {
			cost /= 2; 	/* victim gets half */
			if (Pennies(Owner(victim)) < mudconf.paylimit) {
				sprintf(buf1,
					"Your insurance policy pays %d %s.",
					cost, mudconf.many_coins);
				notify(victim, buf1);
				giveto(Owner(victim), cost, NOTHING);
			} else {
				notify(victim,
					"Your insurance policy has been revoked.");
			}
		}
		free_lbuf(buf1);
		free_lbuf(buf2);

		/* send him home */

		move_via_generic(victim, HOME, NOTHING, 0);
		divest_object(victim);
		break;
	}
}
Exemple #2
0
// ---------------------------------------------------------------------------
// setup_que: Set up a queue entry.
//
static BQUE *setup_que
(
    dbref    executor,
    dbref    caller,
    dbref    enactor,
    int      eval,
    char    *command,
    int      nargs,
    char    *args[],
    reg_ref *sargs[]
)
{
    // Can we run commands at all?
    //
    if (Halted(executor))
    {
        return NULL;
    }

    // Make sure executor can afford to do it.
    //
    int a = mudconf.waitcost;
    if (mudconf.machinecost && RandomINT32(0, mudconf.machinecost-1) == 0)
    {
        a++;
    }
    if (!payfor(executor, a))
    {
        notify(Owner(executor), "Not enough money to queue command.");
        return NULL;
    }

    // Wizards and their objs may queue up to db_top+1 cmds. Players are
    // limited to QUEUE_QUOTA. -mnp
    //
    a = QueueMax(Owner(executor));
    if (a_Queue(Owner(executor), 1) > a)
    {
        a_Queue(Owner(executor), -1);

        notify(Owner(executor),
            "Run away objects: too many commands queued.  Halted.");
        halt_que(Owner(executor), NOTHING);

        // Halt also means no command execution allowed.
        //
        s_Halted(executor);
        return NULL;
    }

    // We passed all the tests.
    //

    // Calculate the length of the save string.
    //
    size_t tlen = 0;
    static size_t nCommand;
    static size_t nLenEnv[NUM_ENV_VARS];

    if (command)
    {
        nCommand = strlen(command) + 1;
        tlen = nCommand;
    }

    if (nargs > NUM_ENV_VARS)
    {
        nargs = NUM_ENV_VARS;
    }

    for (a = 0; a < nargs; a++)
    {
        if (args[a])
        {
            nLenEnv[a] = strlen(args[a]) + 1;
            tlen += nLenEnv[a];
        }
    }

    // Create the qeue entry and load the save string.
    //
    BQUE *tmp = alloc_qentry("setup_que.qblock");
    tmp->comm = NULL;

    char *tptr = tmp->text = (char *)MEMALLOC(tlen);
    ISOUTOFMEMORY(tptr);

    if (command)
    {
        memcpy(tptr, command, nCommand);
        tmp->comm = tptr;
        tptr += nCommand;
    }

    for (a = 0; a < nargs; a++)
    {
        if (args[a])
        {
            memcpy(tptr, args[a], nLenEnv[a]);
            tmp->env[a] = tptr;
            tptr += nLenEnv[a];
        }
        else
        {
            tmp->env[a] = NULL;
        }
    }

    for ( ; a < NUM_ENV_VARS; a++)
    {
        tmp->env[a] = NULL;
    }

    if (sargs)
    {
        for (a = 0; a < MAX_GLOBAL_REGS; a++)
        {
            tmp->scr[a] = sargs[a];
            if (sargs[a])
            {
                RegAddRef(sargs[a]);
            }
        }
    }
    else
    {
        for (a = 0; a < MAX_GLOBAL_REGS; a++)
        {
            tmp->scr[a] = NULL;
        }
    }

    // Load the rest of the queue block.
    //
    tmp->executor = executor;
    tmp->IsTimed = false;
    tmp->sem = NOTHING;
    tmp->attr = 0;
    tmp->enactor = enactor;
    tmp->caller = caller;
    tmp->eval = eval;
    tmp->nargs = nargs;
    return tmp;
}
Exemple #3
0
// This Task assumes that pEntry is already unlinked from any lists it may
// have been related to.
//
static void Task_RunQueueEntry(void *pEntry, int iUnused)
{
    UNUSED_PARAMETER(iUnused);

    BQUE *point = (BQUE *)pEntry;
    dbref executor = point->executor;

    if (  Good_obj(executor)
       && !Going(executor))
    {
        giveto(executor, mudconf.waitcost);
        mudstate.curr_enactor = point->enactor;
        mudstate.curr_executor = executor;
        a_Queue(Owner(executor), -1);
        point->executor = NOTHING;
        if (!Halted(executor))
        {
            // Load scratch args.
            //
            for (int i = 0; i < MAX_GLOBAL_REGS; i++)
            {
                if (mudstate.global_regs[i])
                {
                    RegRelease(mudstate.global_regs[i]);
                    mudstate.global_regs[i] = NULL;
                }
                mudstate.global_regs[i] = point->scr[i];
                point->scr[i] = NULL;
            }

            char *command = point->comm;

            mux_assert(!mudstate.inpipe);
            mux_assert(mudstate.pipe_nest_lev == 0);
            mux_assert(mudstate.poutobj == NOTHING);
            mux_assert(!mudstate.pout);

            break_called = false;
            while (  command
                  && !break_called)
            {
                mux_assert(!mudstate.poutnew);
                mux_assert(!mudstate.poutbufc);

                char *cp = parse_to(&command, ';', 0);

                if (  cp
                   && *cp)
                {
                    // Will command be piped?
                    //
                    if (  command
                       && *command == '|'
                       && mudstate.pipe_nest_lev < mudconf.ntfy_nest_lim)
                    {
                        command++;
                        mudstate.pipe_nest_lev++;
                        mudstate.inpipe = true;

                        mudstate.poutnew  = alloc_lbuf("process_command.pipe");
                        mudstate.poutbufc = mudstate.poutnew;
                        mudstate.poutobj  = executor;
                    }
                    else
                    {
                        mudstate.inpipe = false;
                        mudstate.poutobj = NOTHING;
                    }

                    CLinearTimeAbsolute ltaBegin;
                    ltaBegin.GetUTC();
                    MuxAlarm.Set(mudconf.max_cmdsecs);
                    CLinearTimeDelta ltdUsageBegin = GetProcessorUsage();

                    char *log_cmdbuf = process_command(executor, point->caller,
                        point->enactor, point->eval, false, cp, point->env,
                        point->nargs);

                    CLinearTimeAbsolute ltaEnd;
                    ltaEnd.GetUTC();
                    if (MuxAlarm.bAlarmed)
                    {
                        notify(executor, "GAME: Expensive activity abbreviated.");
                        s_Flags(point->enactor, FLAG_WORD1, Flags(point->enactor) | HALT);
                        s_Flags(point->executor, FLAG_WORD1, Flags(point->executor) | HALT);
                        halt_que(point->enactor, NOTHING);
                        halt_que(executor, NOTHING);
                    }
                    MuxAlarm.Clear();

                    CLinearTimeDelta ltdUsageEnd = GetProcessorUsage();
                    CLinearTimeDelta ltd = ltdUsageEnd - ltdUsageBegin;
                    db[executor].cpu_time_used += ltd;

                    ltd = ltaEnd - ltaBegin;
                    if (ltd > mudconf.rpt_cmdsecs)
                    {
                        STARTLOG(LOG_PROBLEMS, "CMD", "CPU");
                        log_name_and_loc(executor);
                        char *logbuf = alloc_lbuf("do_top.LOG.cpu");
                        mux_sprintf(logbuf, LBUF_SIZE, " queued command taking %s secs (enactor #%d): ",
                            ltd.ReturnSecondsString(4), point->enactor);
                        log_text(logbuf);
                        free_lbuf(logbuf);
                        log_text(log_cmdbuf);
                        ENDLOG;
                    }
                }

                // Transition %| value.
                //
                if (mudstate.pout)
                {
                    free_lbuf(mudstate.pout);
                    mudstate.pout = NULL;
                }
                if (mudstate.poutnew)
                {
                    *mudstate.poutbufc = '\0';
                    mudstate.pout = mudstate.poutnew;
                    mudstate.poutnew  = NULL;
                    mudstate.poutbufc = NULL;
                }
            }

            // Clean up %| value.
            //
            if (mudstate.pout)
            {
                free_lbuf(mudstate.pout);
                mudstate.pout = NULL;
            }
            mudstate.pipe_nest_lev = 0;
            mudstate.inpipe = false;
            mudstate.poutobj = NOTHING;
        }
    }

    for (int i = 0; i < MAX_GLOBAL_REGS; i++)
    {
        if (point->scr[i])
        {
            RegRelease(point->scr[i]);
            point->scr[i] = NULL;
        }

        if (mudstate.global_regs[i])
        {
            RegRelease(mudstate.global_regs[i]);
            mudstate.global_regs[i] = NULL;
        }
    }

    MEMFREE(point->text);
    point->text = NULL;
    free_qentry(point);
}
Exemple #4
0
// ---------------------------------------------------------------------------
// do_halt: Command interface to halt_que.
//
void do_halt(dbref executor, dbref caller, dbref enactor, int eval, int key, char *target)
{
    UNUSED_PARAMETER(caller);
    UNUSED_PARAMETER(enactor);
    UNUSED_PARAMETER(eval);

    dbref executor_targ, obj_targ;

    if ((key & HALT_ALL) && !Can_Halt(executor))
    {
        notify(executor, NOPERM_MESSAGE);
        return;
    }

    // Figure out what to halt.
    //
    if (!target || !*target)
    {
        obj_targ = NOTHING;
        if (key & HALT_ALL)
        {
            executor_targ = NOTHING;
        }
        else
        {
            executor_targ = Owner(executor);
            if (!isPlayer(executor))
            {
                obj_targ = executor;
            }
        }
    }
    else
    {
        if (Can_Halt(executor))
        {
            obj_targ = match_thing(executor, target);
        }
        else
        {
            obj_targ = match_controlled(executor, target);
        }
        if (!Good_obj(obj_targ))
        {
            return;
        }
        if (key & HALT_ALL)
        {
            notify(executor, "Can't specify a target and /all");
            return;
        }
        if (isPlayer(obj_targ))
        {
            executor_targ = obj_targ;
            obj_targ = NOTHING;
        }
        else
        {
            executor_targ = NOTHING;
        }
    }

    int numhalted = halt_que(executor_targ, obj_targ);
    if (Quiet(executor))
    {
        return;
    }
    notify(Owner(executor), tprintf("%d queue entr%s removed.", numhalted, numhalted == 1 ? "y" : "ies"));
}