Пример #1
0
// game logging to std error.. now with sprintf support
void mudlog(const char *str, ...)
{
	MSOCKET *sock;
	char logstr[MAX_BUFFER*2];
	char buf[MAX_BUFFER];
	char imm[MAX_BUFFER];
	va_list ap;
	static long numlogs=0;

	if(++numlogs > MUDLOG_LIMIT)
		return;

	va_start(ap, str);
	(void)vsnprintf(buf, MAX_BUFFER, str, ap);

	sprintf(imm,"&+M[LOG] &+W");
	strcat(imm,buf);
	for(sock = socket_list; sock; sock = sock->next)
	{
		if(sock->pc && (!IsPlaying(sock->pc) || !flag_isset(sock->pc->flags, CFLAG_NOTIFY)))
			continue;
		sendcrit(sock->pc, imm);
	}

	strftime(logstr, MAX_BUFFER, "%m/%d/%Y %H:%M:%S :: ", localtime(&current_time) );
	strcat(logstr,buf);

//	fprintf(stderr, "%s\n", wraptext(23,logstr,100));
	fprintf(stderr, "%s\n", logstr);

	va_end(ap);
}
Пример #2
0
void use_channel(CREATURE *crit, char *name, char *text, long level, long flag, char *color)
{
	MSOCKET *sock;
	char buf[MAX_BUFFER];

	sprintf(buf,"%s(%s) [&N&+W%s&N%s]: %s&N",color,name,crit->name,color,text);

	for(sock = socket_list; sock; sock = sock->next)
	{
		if(!IsPlaying(sock->pc) || sock->pc->level < level
		|| flag_isset(sock->pc->flags, flag))
			continue;

		sendcrit(sock->pc,buf);
	}
}
Пример #3
0
// game boot up stuff
void init_mud(long hotreboot)
{
	char buf[MAX_BUFFER];
	MSOCKET *socket;
	extern CREATURE *hash_creature[HASH_KEY];
	extern OBJECT *hash_object[HASH_KEY];
	extern ROOM *hash_room[HASH_KEY];
	extern char **connect_attempts;
	extern void backup_update();
#ifndef WIN32
	struct itimerval itime;
	struct timeval time;
#endif
	extern char * const months[];
	extern char * const days[];
	long x;

	for(x = 0; months[x]; x++) ;
	mudtime.months = x;
	for(x = 0; days[x]; x++) ;
	mudtime.days = x;

	// init hash tables
	memset(hash_creature,	0,sizeof(hash_creature));
	memset(hash_object,	0,sizeof(hash_object));
	memset(hash_room,	0,sizeof(hash_room));
	memset(hash_reset,	0,sizeof(hash_reset));

	// set up process signals to catch and deal with
	signal(SIGINT,		signal_handler);
	signal(SIGILL,		signal_handler);
	signal(SIGFPE,		signal_handler);

	signal(SIGSEGV,		signal_handler);
	signal(SIGPIPE,		SIG_IGN);	// ignore pipes! tx to unix socket faq for help
						// with this.  http://http://www.developerweb.net/forum/
#ifndef WIN32
	signal(SIGTRAP,		signal_handler);
	signal(SIGVTALRM,	signal_handler);

	// this code is to check for infinite looping
	time.tv_sec		= 5;
	time.tv_usec		= 0;
	itime.it_interval	= time;
	itime.it_value		= time;
	if( setitimer(ITIMER_VIRTUAL, &itime, 0) < 0 )
		mudlog("Error starting setitimer.");
#endif

	// initialize the random number generator
	init_rand();

	// connect_attempts array, to keep people from spam connecting to slow down the mud
        connect_attempts        = malloc(sizeof(char*));
        connect_attempts[0]     = 0;

	mysql = mysql_init(NULL);       
       if (!mysql)
       {
               mudlog("Error initializing MySQL: %s", mysql_error(mysql));
               abort();
       }

        // connect to MySQL database
       if (!mysql_real_connect(mysql, DB_HOST, DB_LOGIN, DB_PASSWORD, DB_NAME, 0, NULL, 0))
        {
               mudlog("Error opening mysql database: %s", mysql_error(mysql));
                abort();
        }

        if (mysql_select_db(mysql, DB_NAME))
        {
               mudlog("Error opening main database: %s",mysql_error(mysql));
               if (mysql)
                       mysql_close(mysql);
                abort();
        }

	// time of da mud !
	fread_time();

	// load areas/rooms/objects/creatures
	load_db();

	// check if hotreboot and reconnect everything
	if(hotreboot)
	{
		MSOCKET *socket=0;
		char buf[MAX_BUFFER];
		MYSQL_RES *result;
		MYSQL_ROW row;

		mysql_query(mysql, "SELECT * FROM player WHERE online='1'");
		result = mysql_store_result(mysql);

		if (mysql_num_rows(result) < 0)
		{
			mudlog("hotreboot: mysql error is: %s",mysql_error(mysql));
			exit(1);
		}

		while((row = mysql_fetch_row(result)))
		{
			strcpy(buf, row[P_NAME]);

			// check for "host" player.. holds control descriptor
			if(!strcasecmp("host", row[C_NAME]))
			{
				host = atoi(row[P_DESCRIPTOR]);
			}
			else
			{
				socket = init_socket();
				fread_player(socket, buf);

				str_dup(&socket->host,		row[P_HOST]);
				str_dup(&socket->ip,		row[P_IP]);

				socket->desc = atoi(row[P_DESCRIPTOR]);
				socket->connected = CON_PLAYING;

				trans(socket->pc, socket->pc->in_room);

				sendcrit(socket->pc, "Hotreboot completed.");
			}
		}
		mysql_free_result(result);
	}

	// make sure nobody has non-existant connections, in the event of a crash + hotreboot
	// then go through and update people who are online
	// this is also a good time to get host address, as players will be expecting lag
	mysql_query(mysql, "UPDATE player SET online='0', descriptor='0'");

	for(socket = socket_list; socket; socket = socket->next)
	{
		get_hostname(socket);
		sprintf(buf,"UPDATE player SET online='1', host=\"%s\" WHERE id='%li'",
			smash_quotes(socket->host), socket->id);
		mysql_query(mysql, buf);
	}

	// see how many players are in each area, to see if area should be 'alive'
	for(socket = socket_list; socket; socket = socket->next)
	{
		if(IsPlaying(socket->pc))
			socket->pc->in_room->area->players++;
	}

	// check if we need to backup
	backup_update();
}
Пример #4
0
// MESSAGE -- main messaging utility for the mud.  Can message everyone in room, and you can
// use "triggers", for lack of a better word, so the messages make more sense.  An example:
// message("$n hit$x $N with $p!",crit,xcrit,obj);  --> the $n is the actor, all the lowercase
// triggers refer to the actor, and upper case refers to the stage.  $p refers to the extra.
// This would create three messages->
// ACTOR(You hit Pip with a big pointy stick!)
// STAGE(Borlak hits you with a big pointy stick!)
// EXTRA(Borlak hits Pip with a big pointy stick!)
//
// Notice what changed.. The 's' on "hits" is removed for the actor.  You may supply
// a character string for $p. for example, a door exit (borlak exits west...)
//
// $n/$N->name of actor/stage, $s/$S->his/her, $m/$M->him/her, $x/$X->s or es
// $r/$R->is/are $t/$T->your/their $z/$Z->your/Borlak's
// world->1 for all players, 2 for all players get the message _immediately_ (shutdown)
void create_message(char *buf, void *actor, void *stage, void *extra, bool world)
{
	char bufactor[MAX_BUFFER*2];
	char bufstage[MAX_BUFFER*2];
	char bufextra[MAX_BUFFER*2];
	char actor_name[MAX_BUFFER];
	char stage_name[MAX_BUFFER];
	char extra_name[MAX_BUFFER];
	char temp[24];
	CREATURE *crit = 0;
	CREATURE *xcrit = 0;
	CREATURE *ppl = 0;
	MSOCKET *sock = 0;
	OBJECT *obj = 0;
	OBJECT *xobj = 0;
	ROOM *room = 0;
	char *abuf;
	char *sbuf;
	char *ebuf;
	char *acopy;
	char *scopy;
	char *ecopy;
	long to_room_only = 0;
	long possessive = 0;

	actor_name[0]	= '\0';
	stage_name[0]	= '\0';
	extra_name[0]	= '\0';
	bufactor[0]	= '\0';
	abuf		= bufactor;
	bufstage[0]	= '\0';
	sbuf		= bufstage;
	bufextra[0]	= '\0';
	ebuf		= bufextra;
	acopy		= "";
	scopy		= "";
	ecopy		= "";

	if(actor)
	{
		switch(*(unsigned int*)actor)
		{
		case TYPE_CREATURE:
			crit = (CREATURE*)actor;
			room = crit->in_room;
			strcpy(actor_name,crit->name);
			break;
		case TYPE_OBJECT:
			obj = (OBJECT*)actor;
			     if(obj->in_room)	room = obj->in_room;
			else if(obj->held_by)	room = obj->held_by->in_room;
			else if(obj->in_obj)
			{
				if(obj->in_obj->in_room)	room = obj->in_obj->in_room;
				else if(obj->in_obj->held_by)	room = obj->in_obj->held_by->in_room;
			}
			if(obj->objtype == OBJ_COIN)
					sprintf(actor_name,"some %s",coin_table[obj->values[0]].ansi_name);
			else
				strcpy(actor_name,obj->name);
			break;
		case TYPE_ROOM:
			room = (ROOM*)actor;
			strcpy(actor_name,room->name);
			break;
		default:
			mudlog("MESSAGE(%s): bad actor type!",buf);
			return;
		}
	}
	if(stage)
	{
		switch(*(unsigned int*)stage)
		{
		case TYPE_CREATURE:
			xcrit = (CREATURE*)stage;
			strcpy(stage_name,xcrit->name);
			break;
		case TYPE_OBJECT:
			xobj = (OBJECT*)stage;
			if(xobj->objtype == OBJ_COIN)
				sprintf(stage_name,"some %s",coin_table[xobj->values[0]].ansi_name);
			else
				strcpy(stage_name,xobj->name);
			break;
		case TYPE_ROOM:
			// decided to make TYPE_ROOM stages go NOT to the crit.
			// so basically, you have a crit that doesn't get message.
			to_room_only = 1;
			// mudlog("MESSAGE(%s): can't have room as stage!",buf);
			break;
		default:
			mudlog("MESSAGE(%s): bad stage type!",buf);
			return;
		}
	}
	if(extra)
	{
		switch(*(unsigned int*)extra)
		{
		case TYPE_CREATURE:
			mudlog("MESSAGE(%s): can't have creature as extra!",buf);
			break;
		case TYPE_OBJECT:
			xobj = (OBJECT*)extra;
			if(xobj->objtype == OBJ_COIN)
				sprintf(extra_name,"some %s",coin_table[xobj->values[0]].ansi_name);
			else
				strcpy(extra_name,xobj->name);
			break;
		case TYPE_ROOM:
			mudlog("MESSAGE(%s): can't have room as extra!",buf);
			break;
		default:
			strcpy(extra_name,(char*)extra);
			break;
		}
	}

	for(; *buf != '\0'; buf++)
	{
		switch(*buf)
		{
		case '$':
			buf++;
			switch(*buf)
			{
			case '\0':
				break;
			case 'e':
				acopy = "you";
				scopy = ecopy = heshe[crit->sex];
				break;
			case 'E':
				scopy = "you";
				if (xcrit)
					acopy = ecopy = heshe[xcrit->sex];
				else
					acopy = ecopy = "their";
				break;
			case 'm':
				acopy = "your";
				scopy = ecopy = himher[crit->sex];
				break;
			case 'M':
				scopy = "your";
				if (xcrit)
					acopy = ecopy = himher[xcrit->sex];
				else
					acopy = ecopy = "their";
				break;
			case 'n':
				acopy = "you";
				scopy = ecopy = actor_name;
				break;
			case 'N':
				acopy = ecopy = stage_name;
				scopy = "you";
				break;
			case 'z':
				acopy = "your";
				scopy = ecopy = actor_name;
				possessive = 1;
				break;
			case 'Z':
				acopy = ecopy = stage_name;
				scopy = "your";
				possessive = 2;
				break;
			case 'g':
			case 'G':
				acopy = "go";
				scopy = ecopy = "goes";
				break;
			case 'd':
			case 'D':
				acopy = "don't";
				scopy = ecopy = "doesn't";
				break;
			case 'p':
			case 'P':
				acopy = scopy = ecopy = extra_name;
				break;
			case 'r':
			case 'R':
				ecopy = "is";
				scopy = acopy = "are";
				break;
			case 's':
				acopy = "your";
				scopy = ecopy = hisher[crit->sex];
				break;
			case 'S':
				scopy = "your";
				if (xcrit)
					acopy = ecopy = hisher[xcrit->sex];
				else
					acopy = ecopy = "their";
				break;
			case 'y':
				acopy = "y";
				scopy = ecopy = "ies";
				break;
			case 't':
			case 'T':
				acopy = scopy = "your";
				ecopy = "their";
				break;
			case 'x':
				acopy = "";
				scopy = ecopy = "s";
				break;
				
			case 'X':
				acopy = "s";
				scopy = ecopy = "";
				break;
			case 'v':
			case 'V':
				ecopy = "has";
				scopy = acopy = "have";
				break;
			case 'b':
				acopy = "";
				scopy = ecopy = "es";
				break;
			case 'B':
				acopy = "es";
				scopy = ecopy = "";
				break;
			default:
				sprintf(temp, "%c%c", *(buf-1), *buf);
				acopy = scopy = ecopy = temp;
				break;
			}
			while(*acopy != '\0')
				*abuf++ = *acopy++;
			while(*scopy != '\0')
				*sbuf++ = *scopy++;
			while(*ecopy != '\0')
				*ebuf++ = *ecopy++;

			if(possessive == 1)
			{
				*sbuf++ = '\''; *sbuf++ = 's';
				*ebuf++ = '\''; *ebuf++ = 's';
				possessive = 0;
			}
			else if(possessive == 2)
			{
				*abuf++ = '\''; *abuf++ = 's';
				*ebuf++ = '\''; *ebuf++ = 's';
				possessive = 0;
			}

			break;
		default:
			*abuf++ = *buf;
			*sbuf++ = *buf;
			*ebuf++ = *buf;
			break;
		}
	}
	*abuf = '\0';
	*sbuf = '\0';
	*ebuf = '\0';

	ansicap(bufactor);
	ansicap(bufstage);
	ansicap(bufextra);

	if (world)
	{
		for (sock = socket_list; sock; sock = sock->next)
		{
			ppl = sock->pc;

			if(!ppl || !IsPlaying(ppl))
				continue;

			if (ppl == crit)
			{
				if(world > 1 && IsPlayer(crit))
					send_immediately(crit->socket,bufactor);
				else
					sendcrit(crit,bufactor);
			}
			else
			{
				if(world > 1 && IsPlayer(ppl))
					send_immediately(ppl->socket,bufstage);
				else
					sendcrit(ppl,bufstage);
			}
		}
		return;
	}

	for(ppl = room->crits; ppl; ppl = ppl->next_content)
	{
		if(!IsPlaying(ppl) || ppl->state >= STATE_SLEEPING)
			continue;

		if(ppl == crit)
		{
			if(!to_room_only)
				sendcrit(crit,bufactor);
		}
		else if(ppl == xcrit)
			sendcrit(xcrit,bufstage);
		else
			sendcrit(ppl,bufextra);
	}
}
Пример #5
0
///////////////
// FUNCTIONS //
///////////////
void interpret(CREATURE *crit, char *buf)
{
	CREATURE *xcrit=0;
	OBJECT *obj=0;
	SOCIAL *social=0;
	EXIT *exit=0;
	ROOM *room=0;
	char command[MAX_BUFFER];
	char temp[MAX_BUFFER];
	char *pbuf = command;
	char **arguments;
	char **editargs;
	long i = 0, x = 0;
	long string = 0;
	bool found = 0;
	bool command_ok = 0;
	bool social_ok = 0;

	strcpy(temp,buf);

	while( isspace(*buf) )
		buf++;

	// check for one character commands without spaces to 
	// seperate arguments. - i.e. chat yo = .yo | pip
	if(ispunct(*buf))
		*pbuf++ = *buf++;
	else
	{
		while( !isspace(*buf) && *buf != '\0' )
			*pbuf++ = *buf++;
	}
	*pbuf = '\0';

	while( isspace(*buf) )
		buf++;

	// moved exits before other commands - pip.
	// insert full exit name for abbreviated one.
	for( i = 0; directions[i].abbr; i++)
	{
		if (directions[i].abbr[0] != '\0' && !strcasecmp(command,directions[i].abbr))
		{
			sprintf(command,"%s",directions[i].name);
			break;
		}
	}

	if(!IsDisabled(crit))
	{
		for(exit = crit->in_room->exits; exit; exit = exit->next )
		{
			if( !strindex(exit->name, command) )
			{
				if((room = hashfind_room(exit->to_vnum)) == 0)
				{
					sendcrit(crit,"That exit enters into a domain far too powerful for you to handle.");
					mudlog("exit(%s) in room(%s:%d) has bad to_vnum(%d)!",
						exit->name, crit->in_room->name, crit->in_room->vnum,
						exit->to_vnum);
					continue;
				}

				if (exit->door >= DOOR_CLOSED && !IsImmortal(crit))
				{
					sendcritf(crit,"The %s door is closed.",exit->name);
					return;
				}
				if (crit->rider)
				{
					sendcritf(crit,"You can't move on your own until %s dismounts you.",crit->rider->name);
					return;
				}
				// adding mounts!
				if (crit->mount)
					message("$n ride$x $p on $N.",crit,crit->mount,exit->name);
				else					
					message("$n leave$x $p.",crit,0,exit->name);
				trans(crit,room);
				if (crit->mount)
				{
					trans(crit->mount,crit);
					message("$n arrive$x riding $N.",crit,crit->mount,crit->in_room);
				}
				message("$n $v arrived.",crit,crit->in_room,0);
				interpret(crit,"look");
				return;
			}
		}
	}

	// check if they in editor and get a successful return (edited something)
	// otherwise let them use normal commands
	if(IsEditing(crit))
	{
		if(crit->socket->string)
		{
			if(!(string = string_editor(crit,temp)))
				return;
			
			str_dup(&(*crit->socket->variable), crit->socket->string);
			DeleteObject(crit->socket->string)
			return;
		}
		else
			temp[0] = '\0';

		if(!ValidString(command))
			strcat(temp,"");
		else
			sprintf(temp,"%s %s",command,buf);

		editargs = make_arguments(temp);
		if(editor(crit,editargs))
		{
			free_arguments(editargs);
			return;
		}
		free_arguments(editargs);
	}