asgard/
asgard/.settings/
asgard/area/
asgard/data/clans/
asgard/data/clans/history/
asgard/data/rosters/
asgard/src/notice/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#include "merc.h"
#include "newclan.h"
#include "recycle.h"
#include "global_mods.h"

bool load_ch_obj_nodesc(CHAR_DATA *ch, char *name);

// Effectively the normal game function pointer, but defined here
// in case we want to change it in the future.
typedef void (*TEST_FUN)(CHAR_DATA*, char*);
#define TEST_FUN_NAME(Name) testfunc_ ## Name

#define TEST_FUN_DEF(Name) \
	void TEST_FUN_NAME(Name) (CHAR_DATA *ch, char *argument)

#define TEST_FUN_ENTRY(Name) \
	#Name, TEST_FUN_NAME(Name)

#define MAX_NAME_LENGTH		128

typedef struct test_func_entry
{
	const char *name; // Command name
	TEST_FUN func; // Function pointer
	int min_trust; // Min trust to see the command
	const char *desc; // Description of the command
	char *restrict_people[MAX_NAME_LENGTH]; // If { NULL }, anyone with > min_trust can run this, otherwise a list of the only people who can run this
} TEST_TAB_ENTRY;

// Define functions here in the same way as TEST_FUN_DEF(crash).

TEST_FUN_DEF(crash)
{
	send_to_char("Crashing the mud!\r\n", ch);
	// Since the character isn't an NPC, this should crash it.
	int vnum;
	vnum = ch->pIndexData->vnum;
}

// Defining this here instead of just inserting make_rosters into table.
TEST_FUN_DEF(make_rost)
{
	send_to_char("Making rosters from rosterlist.txt", ch);
	make_rosters(ch, argument);
}

TEST_FUN_DEF(fix_noob)
{
	ROSTER_DATA *roster;
	FILE *fp;
	char name[MAX_STRING_LENGTH];

	if ((fp = fopen("../../rostlist.txt", "r")) == NULL)
	{
		send_to_char("No rostlist.\n\r", ch);
		return;
	}

	while (!feof(fp))
	{
		strcpy(name, fread_word(fp));

		if (name[0] == '#')
			break;

		if ((roster = get_roster_by_name(name, FALSE)) == NULL)
		{
			send_to_char("No roster for ", ch);
			send_to_char(name, ch);
			send_to_char("\r\n", ch);
		}

		fread_number(fp);
		fread_number(fp);

		if (fread_number(fp) > 0)
		{
			SET_BIT( roster->flags, ROST_NEWBIE );

			send_to_char("Newbied ", ch);
			send_to_char(name, ch);
			send_to_char("\r\n", ch);
		}

		fread_number(fp);
	}
	update_all_rosters();
	fclose(fp);
}

TEST_FUN_DEF(ref_pfiles) {
	CHAR_DATA *vch;
	DIR *plrdir;
	struct dirent *entry;
	char dirname[512], letter, buf[MAX_STRING_LENGTH];

	for (letter = 'a'; letter <= 'z'; letter++) {
		sprintf(dirname, "../player/%c/", letter);
		if ((plrdir = opendir(dirname)) != NULL) {
			while ((entry = readdir(plrdir)) != NULL) {
				if (entry->d_name && isupper(entry->d_name[0])) {
					for (vch = char_list; vch != NULL; vch = vch->next)
						if (!str_cmp(entry->d_name, vch->name))
							break;
					if (vch != NULL) {
						sprintf(buf, "Skipping %s\r\n", vch->name);
						send_to_char(buf, ch);
						continue;
					}
					sprintf(buf, "Refreshing %s\r\n", entry->d_name);
					send_to_char(buf, ch);
					vch = new_char();
					vch->pcdata = new_pcdata();
					if (load_ch_obj_nodesc(vch, entry->d_name))
						save_char_obj(vch);
					extract_char(vch, TRUE);
				}
			}
			closedir(plrdir);
		}
	}
}

TEST_FUN_DEF(inc_xpmod) {
	send_to_char("Increasing xpmod.\r\n", ch);
	printf_debug("XPMOD increased: %s.", gmod_add(GMOD_XP, 0.25f) ? "success" : "fail");
}

TEST_FUN_DEF(inc_qpmod) {
	send_to_char("Increasing qpmod.\r\n", ch);
	printf_debug("QPMOD increased: %s.", gmod_add(GMOD_QP, 0.25f) ? "success" : "fail");
}

void clanskill_check();

TEST_FUN_DEF(reset_cskills) {
	CLAN_DATA *clan;
	char buf[MAX_STRING_LENGTH];
	int i;

	for (clan = clan_list; clan != NULL; clan = clan->next) {
		for (i = 0; i < 2; i++) {
			if (clan->skills[i] != -1) {
				sprintf(buf, "Resetting %s{x on %s{x.\r\n",
					clan_skill_table[clan->skills[i]].name, clan->c_name);
				send_to_char(buf, ch);
				clan->platinum += clan_skill_table[clan->skills[i]].platinum;
				clan->qps += clan_skill_table[clan->skills[i]].qps;
				clan->skills[i] = -1;
			}
		}
	}

	CHAR_DATA *vch;
	for (vch = char_list; vch != NULL; vch = vch->next)
		if (!IS_NPC(vch))
			clanskill_check();
	save_all_clans();
}

void populate_items();

// Add entries so your functions are exposed to the wide world.

TEST_TAB_ENTRY test_func_table[] =
{
/* { TEST_FUN_ENTRY(your_func_name),
 Trust to see command,
 Description of the command,
 {NULL} if not restricted, otherwise { "Name", "Name", NULL } for a whitelist of people who can use the command }
 */
{ TEST_FUN_ENTRY(crash), 110, "Crash the mud", { "Nico", NULL}},
{ TEST_FUN_ENTRY(make_rost), 110, "Make rosters", { "Nico", NULL}},
{ TEST_FUN_ENTRY(fix_noob), 110, "Fix newbie status", { "Nico", NULL }},
{ TEST_FUN_ENTRY(ref_pfiles), 110, "Refresh Pfiles", {NULL}},
{ TEST_FUN_ENTRY(inc_xpmod), 110, "Increment expmod", {NULL}},
{ TEST_FUN_ENTRY(inc_qpmod), 110, "Increment qpmod", {NULL}},
{ TEST_FUN_ENTRY(reset_cskills), 110, "Reset all the clanskills", {NULL}},

// DO NOT REMOVE THE FOLLOWING LINE OR PUT ENTRIES AFTER IT.

		{	NULL, NULL, 0, NULL,
			{	NULL}}
	};

// Housekeeping code. Shouldn't need to change this stuff.

bool is_in_list(char *elem, char **list)
{
	if (list[0] == NULL)
		return TRUE; // Short circuit if there are no names.
	while (*list != NULL)
		if (!str_cmp(elem, *(list++)))
			return TRUE;
	return FALSE;
}

void do_test(CHAR_DATA *ch, char *argument)
{
	if (IS_NPC(ch))
	{
		send_to_char("NPCs can't test things.\r\n", ch);
		return;
	}

	TEST_TAB_ENTRY *entry;
	int trust = get_trust(ch);

	if (argument[0] == '\0')
	{
		char buf[MAX_STRING_LENGTH];
		bool found = FALSE;
		send_to_char("Available choices:\r\n", ch);
		for (entry = test_func_table; entry->name != NULL; entry++)
		{
			if (entry->min_trust > trust)
				continue;
			sprintf(buf, " [%-10s] - %s%s\r\n", entry->name, entry->desc,
					(is_in_list(ch->name, entry->restrict_people) ? ""
							: " ({RRestricted{x)"));
			send_to_char(buf, ch);
			found = TRUE;
		}
		if (!found)
			send_to_char(" NOTHING!\r\n", ch);
		return;
	}

	char arg[MAX_INPUT_LENGTH];
	argument = one_argument(argument, arg);

	for (entry = test_func_table; entry->name != NULL; entry++)
	{
		if (entry->min_trust > trust)
			continue;
		if (!str_cmp(arg, entry->name))
		{
			if (!is_in_list(ch->name, entry->restrict_people))
				send_to_char(
						"This command is restricted to a list of people.\r\n",
						ch);
			else
				(*entry->func)(ch, argument);
			return;
		}
	}

	send_to_char("Test command not found.\r\n", ch);
	do_test(ch, "");
}