fbmuck-6.01/contrib/jresolver/
fbmuck-6.01/contrib/jresolver/org/
fbmuck-6.01/contrib/jresolver/org/fuzzball/
fbmuck-6.01/docs/devel/
fbmuck-6.01/game/
fbmuck-6.01/game/logs/
fbmuck-6.01/game/muf/
fbmuck-6.01/scripts/
fbmuck-6.01/src_docs/
/* Primitives package */

#include "copyright.h"
#include "config.h"

#include <sys/types.h>
#include <stdio.h>
#include <time.h>
#include "db.h"
#include "inst.h"
#include "externs.h"
#include "match.h"
#include "interface.h"
#include "params.h"
#include "tune.h"
#include "fbstrings.h"
#include "interp.h"

static struct inst *oper1, *oper2, *oper3, *oper4;
static struct inst temp1, temp2;
static int tmp, result;
static dbref ref;

void
prim_awakep(PRIM_PROTOTYPE)
{
	CHECKOP(1);
	oper1 = POP();
	if (!valid_object(oper1))
		abort_interp("invalid argument.");
	ref = oper1->data.objref;
	if (Typeof(ref) == TYPE_THING && (FLAGS(ref) & ZOMBIE))
		ref = OWNER(ref);
	if (Typeof(ref) != TYPE_PLAYER)
		abort_interp("invalid argument.");
	result = online(ref);
	CLEAR(oper1);
	PushInt(result);
}

void
prim_online(PRIM_PROTOTYPE)
{
	CHECKOP(0);
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	result = pcount();
	CHECKOFLOW(result + 1);
	while (result) {
		ref = pdbref(result--);
		PushObject(ref);
	}
	result = pcount();
	PushInt(result);
}


void
prim_online_array(PRIM_PROTOTYPE)
{
	stk_array *nu;
	int i;

	CHECKOP(0);
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	result = pcount();
	CHECKOFLOW(1);

	temp1.type = PROG_INTEGER;
	temp2.type = PROG_OBJECT;
	temp1.line = 0;
	temp2.line = 0;
	nu = new_array_packed(result);
	for (i = 0; i < result; i++) {
		temp1.data.number = i;
		temp2.data.number = pdbref(i + 1);
		array_setitem(&nu, &temp1, &temp2);
	}
	PushArrayRaw(nu);
}


void
prim_concount(PRIM_PROTOTYPE)
{
	/* -- int */
	CHECKOP(0);
	result = pcount();
	CHECKOFLOW(1);
	PushInt(result);
}

void
prim_descr(PRIM_PROTOTYPE)
{
	/* -- int */
	CHECKOP(0);
	result = fr->descr;
	CHECKOFLOW(1);
	PushInt(result);
}

void
prim_condbref(PRIM_PROTOTYPE)
{
	/* int -- dbref */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	result = pdbref(result);
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushObject(result);
}


void
prim_descr_dbref(PRIM_PROTOTYPE)
{
	/* int -- dbref */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = pdescrdbref(oper1->data.number);
	if (result < 0)
		result = NOTHING;
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushObject(result);
}


void
prim_conidle(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	result = pidle(result);
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descr_idle(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = pdescridle(oper1->data.number);
	if (result < 0)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descr_least_idle(PRIM_PROTOTYPE)
{
	/* obj -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Argument not a dbref.");
	if (!valid_object(oper1))
		abort_interp("Bad dbref.");
	result = pdescr(least_idle_player_descr(oper1->data.objref));
	if (result == 0)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descr_most_idle(PRIM_PROTOTYPE)
{
	/* obj -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Argument not a dbref.");
	if (!valid_object(oper1))
		abort_interp("Bad dbref.");
	result = pdescr(most_idle_player_descr(oper1->data.objref));
	if (result == 0)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_contime(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	result = pontime(result);
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descr_time(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = pdescrontime(oper1->data.number);
	if (result < 0)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_conhost(PRIM_PROTOTYPE)
{
	/* int -- char * */
	char *pname;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	pname = phost(result);
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushString(pname);
}

void
prim_descr_host(PRIM_PROTOTYPE)
{
	/* int -- char * */
	char *pname;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	pname = pdescrhost(result);
	if (!pname)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushString(pname);
}

void
prim_conuser(PRIM_PROTOTYPE)
{
	/* int -- char * */
	char *pname;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	pname = puser(result);
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushString(pname);
}

void
prim_descr_user(PRIM_PROTOTYPE)
{
	/* int -- char * */
	char *pname;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	pname = pdescruser(result);
	if (!pname)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushString(pname);
}

void
prim_conboot(PRIM_PROTOTYPE)
{
	/* int --  */
	CHECKOP(1);
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	oper1 = POP();
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	CLEAR(oper1);
	pboot(result);
}


void
prim_descr_boot(PRIM_PROTOTYPE)
{
	/* int --  */
	CHECKOP(1);
	if (mlev < 4)
		abort_interp("Primitive is a wizbit only command.");
	oper1 = POP();
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = pdescrboot(oper1->data.number);
	if (!result)
		abort_interp("Invalid descriptor number. (1)");
	CLEAR(oper1);
}


void
prim_connotify(PRIM_PROTOTYPE)
{
	/* int string --  */
	CHECKOP(2);
	oper2 = POP();				/* string */
	oper1 = POP();				/* int */
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	if (oper2->type != PROG_STRING)
		abort_interp("Argument not an string. (2)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	if (oper2->data.string)
		pnotify(result, oper2->data.string->data);
	CLEAR(oper1);
	CLEAR(oper2);
}


void
prim_descr_notify(PRIM_PROTOTYPE)
{
	/* int string --  */
	CHECKOP(2);
	oper2 = POP();				/* string */
	oper1 = POP();				/* int */
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	if (oper2->type != PROG_STRING)
		abort_interp("Argument not an string. (2)");
	if (oper2->data.string)
		result = pdescrnotify(oper1->data.number, oper2->data.string->data);
	if (!result)
		abort_interp("Invalid descriptor number. (1)");
	CLEAR(oper1);
	CLEAR(oper2);
}


void
prim_condescr(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	if ((result < 1) || (result > pcount()))
		abort_interp("Invalid connection number. (1)");
	result = pdescr(result);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descrcon(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	result = pdescrcon(result);
	CLEAR(oper1);
	PushInt(result);
}

void
prim_nextdescr(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = oper1->data.number;
	result = pnextdescr(result);
	CLEAR(oper1);
	PushInt(result);
}


void
prim_descriptors(PRIM_PROTOTYPE)
{
	int mydescr, mycount = 0;
	int* darr;
	int di, dcount;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Argument not a dbref.");
	if (oper1->data.objref != NOTHING && !valid_object(oper1))
		abort_interp("Bad dbref.");
	ref = oper1->data.objref;
	if ((ref != NOTHING) && (!valid_player(oper1)))
		abort_interp("Non-player argument.");
	CLEAR(oper1);
	CHECKOP(0);

    if (ref == NOTHING) {
        result = pcount();
		CHECKOFLOW(result + 1);
        while (result) {
            mydescr = pdescr(result);
            PushInt(mydescr);
            mycount++;
			result--;
        }
    } else {
		darr = get_player_descrs(ref, &dcount);
		CHECKOFLOW(dcount + 1);
        for (di = 0; di < dcount; di++) {
            PushInt(darr[di]);
            mycount++;
        }
    }
	PushInt(mycount);
}

void
prim_descr_array(PRIM_PROTOTYPE)
{
	stk_array *newarr;
	int* darr;
	int di, dcount;
	int i;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Argument not a dbref.");
	if (oper1->data.objref != NOTHING && !valid_object(oper1))
		abort_interp("Bad dbref.");
	ref = oper1->data.objref;
	if ((ref != NOTHING) && (!valid_player(oper1)))
		abort_interp("Non-player argument.");

	CLEAR(oper1);

	temp1.type = PROG_INTEGER;
	temp2.type = PROG_INTEGER;
	temp1.line = 0;
	temp2.line = 0;
    if (ref == NOTHING) {
		result = pcount();
		newarr = new_array_packed(result);
		for (i = 0; i < result; i++) {
			temp1.data.number = i;
			temp2.data.number = pdescr(i + 1);
			array_setitem(&newarr, &temp1, &temp2);
        }
	} else {
		darr = get_player_descrs(ref, &dcount);
		newarr = new_array_packed(dcount);
        for (di = 0; di < dcount; di++) {
			temp1.data.number = (dcount - 1) - di;
			temp2.data.number = darr[di];
			array_setitem(&newarr, &temp1, &temp2);
        }
	}
	PushArrayRaw(newarr);
}


void
prim_descr_setuser(PRIM_PROTOTYPE)
{
	char *ptr;

	CHECKOP(3);
	oper3 = POP();
	oper2 = POP();
	oper1 = POP();

	if (mlev < 4)
		abort_interp("Requires Wizbit.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Integer descriptor number expected. (1)");
	if (oper2->type != PROG_OBJECT)
		abort_interp("Player dbref expected. (2)");
	ref = oper2->data.objref;
	if (ref != NOTHING && !valid_player(oper2))
		abort_interp("Player dbref expected. (2)");
	if (oper3->type != PROG_STRING)
		abort_interp("Password string expected.");
	ptr = oper3->data.string ? oper3->data.string->data : NULL;
	if (ref != NOTHING) {
		if (!check_password(ref, ptr))
			abort_interp("Incorrect password.");
	}

	if (ref != NOTHING) {
		const char* destname = "*NOBODY*";
		if (ref != NOTHING) {
			destname = NAME(ref);
		}
		log_status("DESCR_SETUSER: %s(%d) to %s(%d) on descriptor %d\n",
				   NAME(player), player, destname, ref, oper1->data.number);
	}
	tmp = oper1->data.number;

	CLEAR(oper1);
	CLEAR(oper2);
	CLEAR(oper3);

	result = pset_user(tmp, ref);

	PushInt(result);
}


void
prim_descrflush(PRIM_PROTOTYPE)
{
	CHECKOP(1);
	oper1 = POP();

	if (mlev < 3)
		abort_interp("Requires Mucker Level 3 or better.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Integer descriptor number expected.");
	tmp = oper1->data.number;
	CLEAR(oper1);
	result = pdescrflush(tmp);
}



void
prim_firstdescr(PRIM_PROTOTYPE)
{
	/* ref -- int */
	int* darr;
	int  dcount;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Requires Mucker Level 3.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Player dbref expected (2)");
	ref = oper1->data.objref;
	if (ref != NOTHING && !valid_player(oper1))
		abort_interp("Player dbref expected (2)");
	if(ref == NOTHING) {
		result = pfirstdescr();
	} else {
		if (Typeof(ref) != TYPE_PLAYER)
            abort_interp("invalid argument");
		if (online(ref)) {
            darr = get_player_descrs(ref, &dcount);
            result = index_descr(darr[dcount - 1]);
		} else {
            result = 0;
		}
	}
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}

void
prim_lastdescr(PRIM_PROTOTYPE)
{
	/* ref -- int */
	int* darr;
	int  dcount;

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Requires Mucker Level 3.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Player dbref expected (2)");
	ref = oper1->data.objref;
	if (ref != NOTHING && !valid_player(oper1))
		abort_interp("Player dbref expected (2)");
	if(ref == NOTHING) {
		result = plastdescr();
	} else {
		if (Typeof(ref) != TYPE_PLAYER)
            abort_interp("invalid argument");
		if (online(ref)) {
            darr = get_player_descrs(ref, &dcount);
            result = index_descr(darr[0]);
		} else {
            result = 0;
		}
	}
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}

void
prim_descr_securep(PRIM_PROTOTYPE)
{
	/* descr -> bool */

	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Requires Mucker Level 3.");
	if (oper1->type != PROG_INTEGER)
			abort_interp("Integer descriptor number expected.");

	result = pdescrsecure(oper1->data.number);
	PushInt(result);
}

void
prim_descr_bufsize(PRIM_PROTOTYPE)
{
	/* int -- int */
	CHECKOP(1);
	oper1 = POP();
	if (mlev < 3)
		abort_interp("Mucker level 3 primitive.");
	if (oper1->type != PROG_INTEGER)
		abort_interp("Argument not an integer. (1)");
	result = pdescrbufsize(oper1->data.number);
	if (result < 0)
		abort_interp("Invalid descriptor number. (1)");
	CHECKOFLOW(1);
	CLEAR(oper1);
	PushInt(result);
}