/*
* This file contains all sorts of utility functions used
* all sorts of places in the code.
*/
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
/* include main header file */
#include "mud.h"
/*
* Check to see if a given name is
* legal, returning FALSE if it
* fails our high standards...
*/
bool check_name(const char *name)
{
int size, i;
if ((size = strlen(name)) < 3 || size > 12)
return FALSE;
for (i = 0 ;i < size; i++)
if (!isalpha(name[i])) return FALSE;
return TRUE;
}
void clear_mobile(D_MOBILE *dMob)
{
memset(dMob, 0, sizeof(*dMob));
dMob->name = NULL;
dMob->password = NULL;
dMob->admin_level = LEVEL_PLAYER;
dMob->events = AllocList();
}
void free_mobile(D_MOBILE *dMob)
{
EVENT_DATA *pEvent;
ITERATOR *pIter;
DetachFromList(dMob, dmobile_list);
if (dMob->socket) dMob->socket->player = NULL;
pIter = AllocIterator(dMob->events);
while ((pEvent = (EVENT_DATA *) NextInList(pIter)) != NULL)
dequeue_event(pEvent);
FreeIterator(pIter);
FreeList(dMob->events);
/* free allocated memory */
free(dMob->name);
free(dMob->password);
PushStack(dMob, dmobile_free);
}
void communicate(D_MOBILE *dMob, char *txt, int range)
{
D_MOBILE *xMob;
ITERATOR *pIter;
char buf[MAX_BUFFER];
char message[MAX_BUFFER];
switch(range)
{
default:
bug("Communicate: Bad Range %d.", range);
return;
break;
case COMM_LOCAL: /* everyone is in the same room for now... */
sprintf(message, "%s says '%s'.\n\r", dMob->name, txt);
sprintf(buf, "You say '%s'.\n\r", txt);
text_to_mobile(dMob, buf);
pIter = AllocIterator(dmobile_list);
while ((xMob = (D_MOBILE *) NextInList(pIter)) != NULL)
{
if (xMob == dMob) continue;
text_to_mobile(xMob, message);
}
FreeIterator(pIter);
MySQL_log_chat(dMob->name, "Local", txt);
break;
case COMM_OOC: /* everyone is in the same room for now... */
sprintf(message, "#C[#POOC#C]#n %s: '%s'.\n\r", dMob->name, txt);
sprintf(buf, "#C[#POOC#C]#n You: '%s'.\n\r", txt);
text_to_mobile(dMob, buf);
pIter = AllocIterator(dmobile_list);
while ((xMob = (D_MOBILE *) NextInList(pIter)) != NULL)
{
if (xMob == dMob) continue;
text_to_mobile(xMob, message);
}
FreeIterator(pIter);
MySQL_log_chat(dMob->name, "OOC", txt);
break;
case COMM_LOG:
sprintf(message, "[LOG: %s]\n\r", txt);
pIter = AllocIterator(dmobile_list);
while ((xMob = (D_MOBILE *) NextInList(pIter)) != NULL)
{
if (!IS_ADMIN(xMob)) continue;
text_to_mobile(xMob, message);
}
FreeIterator(pIter);
break;
}
return;
}
/*
* Loading of help files, areas, etc, at boot time.
*/
void load_muddata(bool fCopyOver)
{
log_string("*** MySQL ************: Connecting to MySQL");
load_mysql();
log_string("*** Help System ******: Loaded Greeting & MOTD");
load_helps();
/* copyover */
if (fCopyOver)
copyover_recover();
}
char *get_time()
{
static char buf[16];
char *strtime;
int i;
strtime = ctime(¤t_time);
for (i = 0; i < 15; i++)
buf[i] = strtime[i + 4];
buf[15] = '\0';
return buf;
}
/* Recover from a copyover - load players */
void copyover_recover()
{
D_MOBILE *dMob;
D_SOCKET *dsock;
FILE *fp;
char name [100];
char host[MAX_BUFFER];
int desc;
log_string("Copyover recovery initiated");
if ((fp = fopen(COPYOVER_FILE, "r")) == NULL)
{
log_string("Copyover file not found. Exitting.");
exit (1);
}
/* In case something crashes - doesn't prevent reading */
unlink(COPYOVER_FILE);
for (;;)
{
fscanf(fp, "%d %s %s\n", &desc, name, host);
if (desc == -1)
break;
dsock = malloc(sizeof(*dsock));
clear_socket(dsock, desc);
dsock->hostname = strdup(host);
AttachToList(dsock, dsock_list);
/* load player data */
if ((dMob = load_player(name)) != NULL)
{
/* attach to socket */
dMob->socket = dsock;
dsock->player = dMob;
/* attach to mobile list */
AttachToList(dMob, dmobile_list);
/* initialize events on the player */
init_events_player(dMob);
}
else /* ah bugger */
{
close_socket(dsock, FALSE);
continue;
}
/* Write something, and check if it goes error-free */
if (!text_to_socket(dsock, "\n\r <*> And before you know it, everything has changed <*>\n\r"))
{
close_socket(dsock, FALSE);
continue;
}
/* make sure the socket can be used */
dsock->bust_prompt = TRUE;
dsock->lookup_status = TSTATE_DONE;
dsock->state = STATE_PLAYING;
/* negotiate compression */
text_to_buffer(dsock, (char *) compress_will2);
text_to_buffer(dsock, (char *) compress_will);
}
fclose(fp);
}
D_MOBILE *check_reconnect(char *player)
{
D_MOBILE *dMob;
ITERATOR *pIter;
pIter = AllocIterator(dmobile_list);
while ((dMob = (D_MOBILE *) NextInList(pIter)) != NULL)
{
if (!strcasecmp(dMob->name, player))
{
if (dMob->socket)
close_socket(dMob->socket, TRUE);
break;
}
}
FreeIterator(pIter);
return dMob;
}