tinymush-3.1p1/game/backups/
tinymush-3.1p1/game/bin/
tinymush-3.1p1/game/data/
tinymush-3.1p1/game/modules/
tinymush-3.1p1/game/modules/old/
tinymush-3.1p1/src/modules/comsys/
tinymush-3.1p1/src/modules/hello/
tinymush-3.1p1/src/modules/mail/
tinymush-3.1p1/src/tools/
/* quota.c - quota management commands */
/* $Id: quota.c,v 1.18 2002/08/02 20:48:47 lwl Exp $ */

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

#include "alloc.h"	/* required by mudconf */
#include "flags.h"	/* required by mudconf */
#include "htab.h"	/* required by mudconf */
#include "mudconf.h"	/* required by code */

#include "db.h"		/* required by externs */
#include "externs.h"	/* required by code */

#include "match.h"	/* required by code */
#include "attrs.h"	/* required by code */
#include "powers.h"	/* required by code */


/* ---------------------------------------------------------------------------
 * load_quota: Load a quota into an array. Expects A_QUOTA or A_QUOTA.
 */

void load_quota(q_list, player, qtype)
int q_list[];
dbref player;
int qtype;
{
	int i, aowner, aflags, alen;
	char *quota_str, *p, *tokst;

	quota_str = atr_get(player, qtype, &aowner, &aflags, &alen);

	if (!*quota_str) {
		for (i = 0; i < 5; i++)
			q_list[i] = 0;
		free_lbuf(quota_str);
		return;
	}
	for (p = strtok_r(quota_str, " ", &tokst), i = 0;
	     p && (i < 5);
	     p = strtok_r(NULL, " ", &tokst), i++) {
		q_list[i] = atoi(p);
	}

	free_lbuf(quota_str);
}

/* ---------------------------------------------------------------------------
 * save_quota: turns a quota array into an attribute.
 */
void save_quota(q_list, player, qtype)
int q_list[];
dbref player;
int qtype;
{
	char buf[MBUF_SIZE];

	sprintf(buf, "%d %d %d %d %d", q_list[0], q_list[1], q_list[2],
		q_list[3], q_list[4]);
	atr_add_raw(player, qtype, buf);
}

/* ---------------------------------------------------------------------------
 * mung_quota, show_quota, do_quota: Manage quotas.
 */

static void count_objquota(player, aq, rq, eq, tq, pq)
dbref player;
int *aq, *rq, *eq, *tq, *pq;
{
	register int a, r, e, t, p, i;

	a = r = e = t = p = 0;

	DO_WHOLE_DB(i) {
		if ((Owner(i) != player) || (Going(i) && !isRoom(i)))
			continue;
		switch (Typeof(i)) {
		case TYPE_ROOM:
			a += mudconf.room_quota;
			r++;
			break;
		case TYPE_EXIT:
			a += mudconf.exit_quota;
			e++;
			break;
		case TYPE_THING:
			a += mudconf.thing_quota;
			t++;
			break;
		case TYPE_PLAYER:
			a += mudconf.player_quota;
			p++;
			break;
		}
	}
	*aq = a;
	*rq = r;
	*eq = e;
	*tq = t;
	*pq = p;
}


static void adjust_quota(player, qtype, value, key)
dbref player;
int qtype, value, key;
{
	register int aq, rq;
	int q_list[5], rq_list[5];

	load_quota(q_list, player, A_QUOTA);
	load_quota(rq_list, player, A_RQUOTA);

	aq = q_list[qtype];
	rq = rq_list[qtype];

	/* Adjust values */

	if (key & QUOTA_REM) {
		aq += (value - rq);
		rq = value;
	} else {
		rq += (value - aq);
		aq = value;
	}

	/* Set both abs and relative quota */

	q_list[qtype] = aq;
	rq_list[qtype] = rq;
	save_quota(q_list, player, A_QUOTA);
	save_quota(rq_list, player, A_RQUOTA);
}


static void mung_quotas(player, key, value)
dbref player;
int key, value;
{
	int xq, rooms, exits, things, players;
	int q_list[5], rq_list[5];

	if (key & QUOTA_FIX) {

		/* Get value of stuff owned and good value, set other values
		 * from that. */

		count_objquota(player, &xq, &rooms, &exits, &things, &players);
		if (key & QUOTA_TOT) {
			load_quota(rq_list, player, A_RQUOTA);
			rq_list[QTYPE_ALL] += xq;
			save_quota(rq_list, player, A_QUOTA);
		} else {
			load_quota(q_list, player, A_QUOTA);
			q_list[QTYPE_ALL] -= xq;
			q_list[QTYPE_ROOM] -= rooms;
			q_list[QTYPE_EXIT] -= exits;
			q_list[QTYPE_THING] -= things;
			q_list[QTYPE_PLAYER] -= players;
			save_quota(q_list, player, A_RQUOTA);
		}
	} else if (key & QUOTA_ROOM) {
		adjust_quota(player, QTYPE_ROOM, value, key);
	} else if (key & QUOTA_EXIT) {
		adjust_quota(player, QTYPE_EXIT, value, key);
	} else if (key & QUOTA_THING) {
		adjust_quota(player, QTYPE_THING, value, key);
	} else if (key & QUOTA_PLAYER) {
		adjust_quota(player, QTYPE_PLAYER, value, key);
	} else {
		adjust_quota(player, QTYPE_ALL, value, key);
	}
}

static void show_quota(player, victim)
dbref player, victim;
{
	int q_list[5], rq_list[5], dq_list[5], i;

	load_quota(q_list, victim, A_QUOTA);
	load_quota(rq_list, victim, A_RQUOTA);

	for (i = 0; i < 5; i++)
		dq_list[i] = q_list[i] - rq_list[i];

	if (Free_Quota(victim)) {
		if (mudconf.typed_quotas)
			notify_quiet(player,
				     tprintf("%-16s: %4d - N/A  %4d - N/A  %4d - N/A  %4d - N/A  %4d - N/A",
					     Name(victim), dq_list[QTYPE_ALL],
					   dq_list[QTYPE_ROOM], dq_list[QTYPE_EXIT],
				      dq_list[QTYPE_THING], dq_list[QTYPE_PLAYER]));
		else
			notify_quiet(player,
				tprintf("%-16s: %4d - N/A", Name(victim),
				dq_list[QTYPE_ALL]));
	} else {
		if (mudconf.typed_quotas)
			notify_quiet(player,
				     tprintf("%-16s: %4d - %3d  %4d - %3d  %4d - %3d  %4d - %3d  %4d - %3d",
					     Name(victim),
					     dq_list[QTYPE_ALL], q_list[QTYPE_ALL],
					     dq_list[QTYPE_ROOM], q_list[QTYPE_ROOM],
					     dq_list[QTYPE_EXIT], q_list[QTYPE_EXIT],
					  dq_list[QTYPE_THING], q_list[QTYPE_THING],
				      dq_list[QTYPE_PLAYER], q_list[QTYPE_PLAYER]));
		else
			notify_quiet(player,
				tprintf("%-16s: %4d - %3d", Name(victim),
				dq_list[QTYPE_ALL], q_list[QTYPE_ALL]));
	}
}

static void show_quota_header(player)
dbref player;
{
	if (mudconf.typed_quotas)
		notify_quiet(player, "Name            : Quot - Lim  Room - Lim  Exit - Lim  Thin - Lim  Play - Lim");
	else
		notify_quiet(player, "Name            : Quot - Lim");
}

void do_quota(player, cause, key, arg1, arg2)
dbref player, cause;
int key;
char *arg1, *arg2;
{
	dbref who;
	register int set = 0, value = 0, i;

	if (!(mudconf.quotas || Can_Set_Quota(player))) {
		notify_quiet(player, "Quotas are not enabled.");
		return;
	}
	if ((key & QUOTA_TOT) && (key & QUOTA_REM)) {
		notify_quiet(player, "Illegal combination of switches.");
		return;
	}
	/* Show or set all quotas if requested */

	if (key & QUOTA_ALL) {
		if (arg1 && *arg1) {
			value = atoi(arg1);
			set = 1;
			if (value < 0) {
			    notify(player, "Illegal quota value.");
			    return;
			}
		} else if (key & (QUOTA_SET | QUOTA_FIX)) {
			value = 0;
			set = 1;
		}
		if (set) {
			STARTLOG(LOG_WIZARD, "WIZ", "QUOTA")
				log_name(player);
				log_printf(" changed everyone's quota.");
			ENDLOG
		}
		show_quota_header(player);
		DO_WHOLE_DB(i) {
			if (isPlayer(i)) {
				if (set)
					mung_quotas(i, key, value);
				show_quota(player, i);
			}
		}
		return;
	}
	/* Find out whose quota to show or set */

	if (!arg1 || *arg1 == '\0') {
		who = Owner(player);
	} else {
		who = lookup_player(player, arg1, 1);
		if (!Good_obj(who)) {
			notify_quiet(player, "Not found.");
			return;
		}
	}

	/* Make sure we have permission to do it */

	if (!Can_Set_Quota(player)) {
		if (arg2 && *arg2) {
			notify_quiet(player, NOPERM_MESSAGE);
			return;
		}
		if (Owner(player) != who) {
			notify_quiet(player, NOPERM_MESSAGE);
			return;
		}
	}
	if (arg2 && *arg2) {
		set = 1;
		value = atoi(arg2);
		if (value < 0) {
		    notify(player, "Illegal quota value.");
		    return;
		}
	} else if (key & QUOTA_FIX) {
		set = 1;
		value = 0;
	}
	if (set) {
		STARTLOG(LOG_WIZARD, "WIZ", "QUOTA")
			log_name(player);
			log_printf(" changed the quota of ");
			log_name(who);
		ENDLOG
			mung_quotas(who, key, value);
	}
	show_quota_header(player);
	show_quota(player, who);
}