tinymush-3.1p2/game/backups/
tinymush-3.1p2/game/bin/
tinymush-3.1p2/game/data/
tinymush-3.1p2/game/modules/
tinymush-3.1p2/game/modules/old/
tinymush-3.1p2/src/modules/comsys/
tinymush-3.1p2/src/modules/hello/
tinymush-3.1p2/src/modules/mail/
tinymush-3.1p2/src/tools/
/* hello.c - demonstration module */
/* $Id: hello.c,v 1.19 2001/12/13 04:39:28 dpassmor Exp $ */

#include "../../api.h"

#define MOD_HELLO_HELLO_INFORMAL	1
#define MOD_HELLO_FOOF_SHOW		1

/* --------------------------------------------------------------------------
 * Conf table.
 */

struct mod_hello_confstorage {
	int show_name;
	char *hello_string;
	int hello_times;
} mod_hello_config;

CONF mod_hello_conftable[] = {
{(char *)"hello_shows_name",		cf_bool,	CA_GOD,		CA_PUBLIC,	(int *)&mod_hello_config.show_name,	(long)"Greet players by name"},
{(char *)"hello_string",		cf_string,	CA_GOD,		CA_WIZARD,	(int *)&mod_hello_config.hello_string,	MBUF_SIZE},
{(char *)"hello_times",			cf_int,		CA_GOD,		CA_PUBLIC,	(int *)&mod_hello_config.hello_times,	5},
{ NULL,					NULL,		0,		0,		NULL,				0}};

/* --------------------------------------------------------------------------
 * Database.
 */

unsigned int mod_hello_dbtype;

typedef struct mod_hello_dbobj MOD_HELLO_OBJ;
struct mod_hello_dbobj {
    int greeted;		/* counter for @hello */
    int foofed;			/* counter for @foof */
};

MOD_HELLO_OBJ *mod_hello_db = NULL;

#define OBJ_INIT_MODULE(x) \
    mod_hello_db[x].greeted = 0; \
    mod_hello_db[x].foofed = 0;

void mod_hello_db_grow(newsize, newtop)
    int newsize, newtop;
{
    DB_GROW_MODULE(mod_hello_db, newsize, newtop, MOD_HELLO_OBJ);
}

/* --------------------------------------------------------------------------
 * API export.
 */

API_FUNCTION mod_hello_exports[] = {
{ "print_greeting",		NULL },
{ NULL,				NULL }};

typedef struct greeting_input HI_INPUT;
struct greeting_input {
    dbref player;
    char *name;
};

typedef struct greeting_output HI_OUTPUT;
struct greeting_output {
    int success_code;
};

void mod_hello_print_greeting(in_ptr, out_ptr)
    void *in_ptr, *out_ptr;
{
    dbref target;
    HI_INPUT *in_p;
    HI_OUTPUT *out_p;

    in_p = (HI_INPUT *) in_ptr;
    out_p = (HI_OUTPUT *) out_ptr;

    target = lookup_player(in_p->player, in_p->name, 0);
    if (target == NOTHING) {
	out_p->success_code = 0;
	return;
    }

    notify(target, "Greetings!");
    out_p->success_code = 1;
}   

/* --------------------------------------------------------------------------
 * Handlers.
 */

int mod_hello_process_command(player, cause, interactive, command, args, nargs)
	dbref player, cause;
	int interactive;
	char *command, *args[];
	int nargs;
{
	/* Command intercept before normal matching */

	if (!strcmp(command, "hiya")) {
		notify(player, "Got hiya.");
		return 1;
	}
	return 0;
}

int mod_hello_process_no_match(player, cause, interactive, 
				lc_command, raw_command, args, nargs)
	dbref player, cause;
	int interactive;
	char *lc_command, *raw_command, *args[];
	int nargs;
{
	/* Command intercept before 'Huh?' */

	if (!strcmp(lc_command, "heythere")) {
		notify(player, "Got heythere.");
		return 1;
	}
	return 0;
}

int mod_hello_did_it(player, thing, master, what, def, owhat, odef, awhat,
		     now, args, nargs)
    dbref player, thing, master;
    int what, owhat, awhat, now, nargs;
    const char *def, *odef;
    char *args[];
{
    /* Demonstrate the different ways we can intercept did_it() calls.
     *
     * We intercept 'look' (by trapping A_DESC), and return a message of
     * our own, preventing other modules from showing something, and 
     * preventing the normal server defaults from being run. (Return 1.)
     *
     * We intercept 'move' (by trapping A_MOVE), and return a message of
     * our own, but don't prevent other modules from doing something,
     * or preventing the normal server defaults from being run. (Return 0.)
     *
     * We intercept 'use' (by trapping A_USE), and return a message
     * of our own. We prevent other modules from doing something, but
     * not the normal server defaults from being run. (Return -1.)
     *
     * If we don't get one of these, we just pass. (Return 0.)
     */

    int f, g;

    switch (what) {
	case A_DESC:
	    f = mod_hello_db[thing].foofed;
	    g = mod_hello_db[thing].greeted;
	    notify(player,
		   tprintf("%s has been greeted %d %s and foofed %d %s.",
			   Name(thing), g, ((g == 1) ? "time" : "times"),
			   f, ((f == 1) ? "time" : "times")));
	    return 1;
	    break;		/* NOTREACHED */
	case A_MOVE:
	    notify(GOD,
		   tprintf("%s(#%d) just moved.", Name(thing), thing));
	    return 0;
	    break;		/* NOTREACHED */
	case A_USE:
	    notify(GOD,
		   tprintf("%s(#%d) was used!", Name(thing), thing));
	    return -1;
	    break;		/* NOTREACHED */
	default:
	    return 0;
    }
}

void mod_hello_create_obj(player, obj)
	dbref player, obj;
{
	notify(player, tprintf("You created #%d -- hello says so.", obj));
}

void mod_hello_destroy_obj(player, obj)
	dbref player, obj;
{
	notify(GOD, tprintf("Destroyed #%d -- hello says so.", obj));
}

void mod_hello_destroy_player(player, victim)
	dbref player, victim;
{
	notify(player, tprintf("Say goodbye to %s!", Name(victim)));
}

void mod_hello_announce_connect(player, reason, num)
	dbref player;
	const char *reason;
	int num;
{
	notify(GOD, tprintf("%s(#%d) just connected -- hello says so.",
				Name(player), player));
}

void mod_hello_announce_disconnect(player, reason, num)
	dbref player;
	const char *reason;
	int num;
{
	notify(GOD, tprintf("%s(#%d) just disconnected -- hello says so.",
				Name(player), player));
}

void mod_hello_examine(player, cause, thing, control, key)
    dbref player, cause, thing;
    int control, key;
{
    if (control) {
	notify(player,
	       tprintf("Greeted: %d  Foofed: %d",
		       mod_hello_db[thing].greeted,
		       mod_hello_db[thing].foofed));
    }
}

/* --------------------------------------------------------------------------
 * Commands.
 */

DO_CMD_NO_ARG(mod_hello_do_hello)
{
    int i;


    if (key & MOD_HELLO_HELLO_INFORMAL) {
	for (i = 0; i < mod_hello_config.hello_times; i++) 
	    notify(player, "Hi there!");
    } else {
	if (mod_hello_config.show_name)
	    notify(player, tprintf("Hello, %s!", Name(player)));
	else
	    notify(player, mod_hello_config.hello_string);
    }

    mod_hello_db[player].greeted += 1;
    notify(player, tprintf("You have been greeted %d times.", 
			   mod_hello_db[player].greeted));
}

DO_CMD_ONE_ARG(mod_hello_do_foof)
{
    DBData dbkey;
    DBData data;

    /* Demonstrate what we can do:
     *   @foof greets you with a generic message.
     *
     *   @foof <message> greets you with a customized message that is
     *	 preserved in the database.
     *
     *   @foof/show will show you the message you were last 'foofed' with.
     *   This illustrates the use of the database cache.
     */

    /* Set up our DB key. We'll either be getting, adding or deleting an
     * entry */
    
    dbkey.dptr = &player;
    dbkey.dsize = sizeof(dbref);
    
    if (key & MOD_HELLO_FOOF_SHOW) {
    	data = cache_get(dbkey, mod_hello_dbtype);
    	if (data.dptr) {
    		notify(player, tprintf("You were last foofed with: %s", data.dptr));
    	} else {
    		notify(player, "You have not been foofed with a message.");
    	}
    	return;
    }
    
    if (arg1 && *arg1) {
    	notify(player, tprintf("Yay: \"%s\"", arg1));
    	
    	/* Set up data and store it in cache */
    	
    	data.dptr = XSTRDUP(arg1, "mod_hello_do_foof");
    	data.dsize = strlen(arg1) + 1;
    	cache_put(dbkey, data, mod_hello_dbtype);
    } else {
	notify(player, "Yay.");
	
	/* Delete the entry from cache if it exists */
	
	cache_del(dbkey, mod_hello_dbtype);
    }
    
    mod_hello_db[player].foofed += 1;
    notify(player, tprintf("You have been foofed %d times.", 
			   mod_hello_db[player].foofed));
}

NAMETAB mod_hello_hello_sw[] = {
{(char *)"informal",	1,	CA_PUBLIC,	MOD_HELLO_HELLO_INFORMAL},
{ NULL,			0,	0,		0}};

NAMETAB mod_hello_foof_sw[] = {
{(char *)"show",	1,	CA_PUBLIC,	MOD_HELLO_FOOF_SHOW},
{ NULL,			0,	0,		0}};

CMDENT mod_hello_cmdtable[] = {
{(char *)"@hello",		mod_hello_hello_sw,	CA_PUBLIC,
	0,		CS_NO_ARGS,
	NULL,		NULL,	NULL,			{mod_hello_do_hello}},
{(char *)"@foof",		mod_hello_foof_sw,	CA_PUBLIC,
	0,		CS_ONE_ARG,
	NULL,		NULL,	NULL,			{mod_hello_do_foof}},
{(char *)NULL,			NULL,		0,
	0,		0,
	NULL,		NULL,	NULL,		{NULL}}};

/* --------------------------------------------------------------------------
 * Functions.
 */

FUNCTION(mod_hello_fun_hello)
{
    safe_str("Hello, world!", buff, bufc);
}

FUNCTION(mod_hello_fun_hi)
{
    /* Normally we would not call our own API, but here's just an
     * example.
     */

    static void (*handler)(void *, void *) = NULL;
    HI_INPUT in_info;
    HI_OUTPUT out_info;

    if (!handler)
	handler = request_api_function("hi", "print_greeting");

    if (!handler) {
	safe_str("#-1 API FUNCTION MISSING", buff, bufc);
	return;
    }

    in_info.player = player;
    in_info.name = fargs[0];
    handler(&in_info, &out_info);

    if (out_info.success_code == 0)
	safe_str("#-1 NO SUCH PLAYER", buff, bufc);
}


FUN mod_hello_functable[] = {
{"HELLO",	mod_hello_fun_hello,	0,	0,	CA_PUBLIC,	NULL},
{"HI",		mod_hello_fun_hi,	1,	0,	CA_PUBLIC,	NULL},
{NULL,		NULL,			0,	0,	0,		NULL}};

/* --------------------------------------------------------------------------
 * Hash tables.
 * (We don't use any of this data. It's just here for demo purposes.)
 */

HASHTAB mod_hello_greetings;
HASHTAB mod_hello_farewells;

MODHASHES mod_hello_hashtable[] = {
{ "Hello greetings",	&mod_hello_greetings,	5,	8},
{ "Hello farewells",	&mod_hello_farewells,	15,	32},
{ NULL,			NULL,			0,	0}};

NHSHTAB mod_hello_numbers;

MODNHASHES mod_hello_nhashtable[] = {
{ "Hello numbers",	&mod_hello_numbers,	5,	16},
{ NULL,			NULL,			0,	0}};

/* --------------------------------------------------------------------------
 * Initialization.
 */
	
void mod_hello_init()
{
    /* Give our configuration some default values. */

    mod_hello_config.show_name = 0;
    mod_hello_config.hello_string = XSTRDUP("Hello, world!", "mod_hello_init");
    mod_hello_config.hello_times = 1;

    /* Register everything we have to register. */

    register_hashtables(mod_hello_hashtable, mod_hello_nhashtable); 
    register_commands(mod_hello_cmdtable);
    register_functions(mod_hello_functable);
    register_api("hello", "hi", mod_hello_exports);
}

void mod_hello_cleanup_startup()
{
    mod_hello_dbtype = register_dbtype("hello");
}

/* --------------------------------------------------------------------------
 * Database routines: read and write a flatfile at db conversion time.
 */

void mod_hello_db_write_flatfile(f)
FILE *f;
{
	unsigned int dbtype;
	dbref thing;
	DBData key;
	DBData data;
	
	/* Find out our dbtype */

	mod_hello_dbtype = register_dbtype("hello");
		
	/* Write out our version number */
	
	fprintf(f, "+V1\n");
	
	DO_WHOLE_DB(thing) {
		key.dptr = &thing;
		key.dsize = sizeof(dbref);
		data = cache_get(key, mod_hello_dbtype);
		if (data.dptr) {
			fprintf(f, "!%d\n", thing);
			putstring(f, data.dptr);
		}
	}
	
	fputs("***END OF DUMP***\n", f);
}

void mod_hello_db_read_flatfile(f)
FILE *f;
{
	unsigned int dbtype, version;
	char c;
	dbref thing;
	DBData key;
	DBData data;
	
	/* Find out our dbtype */

	mod_hello_dbtype = register_dbtype("hello");

	/* Load entries */
	
	while(1) {
		switch(c = getc(f)) {
		case '+':	/* Header */
			switch(c = getc(f)) {
				case 'V':	/* Version number */
					version = getref(f);
					break;
				default:
					(void)getstring_noalloc(f, 1);
				}
				break;
		case '!':	/* DBref */
			thing = getref(f);
			
			/* Grab the string and put it in cache */
			
			data.dptr = XSTRDUP(getstring_noalloc(f, 1), "mod_hello_db_read_flatfile");
			data.dsize = strlen(data.dptr) + 1;
			key.dptr = &thing;
			key.dsize = sizeof(dbref);
			
			cache_put(key, data, mod_hello_dbtype);
			break;
		case '*':	/* EOF marker */
			return;
		}
	}
}