/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku vMud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Thanks to abaddon for proof-reading our comm.c and pointing out bugs. *
* Any remaining bugs are, of course, our work, not his. :) *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
/***************************************************************************
* ROM 2.4 is copyright 1993-1995 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@pacinfo.com) *
* Gabrielle Taylor (gtaylor@pacinfo.com) *
* Brian Moore (rom@rom.efn.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************/
/***************************************************************************
* ROT 1.4 is copyright 1996-1997 by Russ Walsh *
* By using this code, you have agreed to follow the terms of the *
* ROT license, in the file doc/rot.license *
***************************************************************************/
/*
* This file contains all of the OS-dependent stuff:
* startup, signals, BSD sockets for tcp/ip, i/o, timing.
*
* The data flow for input is:
* Game_loop ---> Read_from_descriptor ---> Read
* Game_loop ---> Read_from_buffer
*
* The data flow for output is:
* Game_loop ---> Process_Output ---> Write_to_descriptor -> Write
*
* The OS-dependent functions are Read_from_descriptor and Write_to_descriptor.
* -- Furey 26 Jan 1993
*/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include <unistd.h>
#include "merc.h"
#include "recycle.h"
#include "tables.h"
/*
* Malloc debugging stuff.
*/
#if defined(sun)
#undef MALLOC_DEBUG
#endif
#if defined(MALLOC_DEBUG)
#include <malloc.h>
extern int malloc_debug args ( ( int ) );
extern int malloc_verify args ( ( void ) );
#endif
/*
* Signal handling.
* Apollo has a problem with __attribute(atomic) in signal.h,
* I dance around it.
*/
#if defined(apollo)
#define __attribute(x)
#endif
#if defined(unix)
#include <signal.h>
#endif
#if defined(apollo)
#undef __attribute
#endif
/*
* Socket and TCP/IP stuff.
*/
#if defined(macintosh) || defined(MSDOS)
const char echo_off_str[] = { '\0' };
const char echo_on_str[] = { '\0' };
const char go_ahead_str[] = { '\0' };
#endif
#if defined(unix)
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "telnet.h"
const char echo_off_str[] = { IAC, WILL, TELOPT_ECHO, '\0' };
const char echo_on_str[] = { IAC, WONT, TELOPT_ECHO, '\0' };
const char go_ahead_str[] = { IAC, GA, '\0' };
#endif
/*
* OS-dependent declarations.
*/
#if defined(_AIX)
#include <sys/select.h>
/*int accept args( ( int s, struct sockaddr *addr, int *addrlen
) );*/
/*int bind args( ( int s, struct sockaddr *name, int namelen
) );*/
void bzero args ( ( char *b, int length ) );
int getpeername args ( ( int s, struct sockaddr * name, int *namelen ) );
int getsockname args ( ( int s, struct sockaddr * name, int *namelen ) );
int gettimeofday args ( ( struct timeval * tp, struct timezone * tzp ) );
int listen args ( ( int s, int backlog ) );
int setsockopt
args ( ( int s, int level, int optname, void *optval, int optlen ) );
int socket args ( ( int domain, int type, int protocol ) );
#endif
#if defined(apollo)
#include <unistd.h>
void bzero args ( ( char *b, int length ) );
#endif
#if defined(__hpux)
/*int accept args( ( int s, void *addr, int *addrlen ) );*/
/*int bind args( ( int s, const void *addr, int addrlen )
);*/
void bzero args ( ( char *b, int length ) );
int getpeername args ( ( int s, void *addr, int *addrlen ) );
int getsockname args ( ( int s, void *name, int *addrlen ) );
int gettimeofday args ( ( struct timeval * tp, struct timezone * tzp ) );
int listen args ( ( int s, int backlog ) );
int setsockopt
args ( ( int s, int level, int optname, const void *optval, int optlen ) );
int socket args ( ( int domain, int type, int protocol ) );
#endif
#if defined(interactive)
#include <net/errno.h>
#include <sys/fnctl.h>
#endif
/*
#if defined(linux)
//int accept args( ( int s, struct sockaddr *addr, int *addrlen ) );
//int bind args( ( int s, struct sockaddr *name, int namelen ) );
int close args( ( int fd ) );
int getpeername args( ( int s, struct sockaddr *name, int *namelen ) );
int getsockname args( ( int s, struct sockaddr *name, int *namelen ) );
int gettimeofday args( ( struct timeval *tp, struct timezone *tzp ) );
int listen args( ( int s, int backlog ) );
int read args( ( int fd, char *buf, int nbyte ) );
int select args( ( int width, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout ) );
int socket args( ( int domain, int type, int protocol ) );
int write args( ( int fd, char *buf, int nbyte ) );
#endif
*/
#if defined(macintosh)
#include <console.h>
#include <fcntl.h>
#include <unix.h>
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
#if !defined(isascii)
#define isascii(c) ( (c) < 0200 )
#endif
static long theKeys[4];
int gettimeofday args ( ( struct timeval * tp, void *tzp ) );
#endif
#if defined(MIPS_OS)
extern int errno;
#endif
#if defined(MSDOS)
int gettimeofday args ( ( struct timeval * tp, void *tzp ) );
int kbhit args ( ( void ) );
#endif
#if defined(NeXT)
int close args ( ( int fd ) );
int fcntl args ( ( int fd, int cmd, int arg ) );
#if !defined(htons)
u_short htons args ( ( u_short hostshort ) );
#endif
#if !defined(ntohl)
u_long ntohl args ( ( u_long hostlong ) );
#endif
int read args ( ( int fd, char *buf, int nbyte ) );
int select
args ( ( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
struct timeval * timeout ) );
int write args ( ( int fd, char *buf, int nbyte ) );
#endif
#if defined(sequent)
/*int accept args( ( int s, struct sockaddr *addr, int *addrlen
) );*/
/*int bind args( ( int s, struct sockaddr *name, int namelen
) );*/
int close args ( ( int fd ) );
int fcntl args ( ( int fd, int cmd, int arg ) );
int getpeername args ( ( int s, struct sockaddr * name, int *namelen ) );
int getsockname args ( ( int s, struct sockaddr * name, int *namelen ) );
int gettimeofday args ( ( struct timeval * tp, struct timezone * tzp ) );
#if !defined(htons)
u_short htons args ( ( u_short hostshort ) );
#endif
int listen args ( ( int s, int backlog ) );
#if !defined(ntohl)
u_long ntohl args ( ( u_long hostlong ) );
#endif
int read args ( ( int fd, char *buf, int nbyte ) );
int select
args ( ( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
struct timeval * timeout ) );
int setsockopt
args ( ( int s, int level, int optname, caddr_t optval, int optlen ) );
int socket args ( ( int domain, int type, int protocol ) );
int write args ( ( int fd, char *buf, int nbyte ) );
#endif
/* This includes Solaris Sys V as well */
#if defined(sun)
int accept args ( ( int s, struct sockaddr * addr, int *addrlen ) );
int bind args ( ( int s, struct sockaddr * name, int namelen ) );
void bzero args ( ( char *b, int length ) );
int close args ( ( int fd ) );
int getpeername args ( ( int s, struct sockaddr * name, int *namelen ) );
int getsockname args ( ( int s, struct sockaddr * name, int *namelen ) );
int gettimeofday args ( ( struct timeval * tp, struct timezone * tzp ) );
int listen args ( ( int s, int backlog ) );
int read args ( ( int fd, char *buf, int nbyte ) );
int select
args ( ( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
struct timeval * timeout ) );
#if defined(SYSV)
int setsockopt
args ( ( int s, int level, int optname, const char *optval, int optlen ) );
#else
int setsockopt
args ( ( int s, int level, int optname, void *optval, int optlen ) );
#endif
int socket args ( ( int domain, int type, int protocol ) );
int write args ( ( int fd, char *buf, int nbyte ) );
#endif
#if defined(ultrix)
int accept args ( ( int s, struct sockaddr * addr, int *addrlen ) );
int bind args ( ( int s, struct sockaddr * name, int namelen ) );
void bzero args ( ( char *b, int length ) );
int close args ( ( int fd ) );
int getpeername args ( ( int s, struct sockaddr * name, int *namelen ) );
int getsockname args ( ( int s, struct sockaddr * name, int *namelen ) );
int gettimeofday args ( ( struct timeval * tp, struct timezone * tzp ) );
int listen args ( ( int s, int backlog ) );
int read args ( ( int fd, char *buf, int nbyte ) );
int select
args ( ( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
struct timeval * timeout ) );
int setsockopt
args ( ( int s, int level, int optname, void *optval, int optlen ) );
int socket args ( ( int domain, int type, int protocol ) );
int write args ( ( int fd, char *buf, int nbyte ) );
#endif
/*
* Global variables.
*/
DESCRIPTOR_DATA *d_next; /* Next descriptor in loop */
bool god; /* All new chars are gods! */
char clcode[MAX_INPUT_LENGTH];
/*
* OS-dependent local functions.
*/
#if defined(macintosh) || defined(MSDOS)
void game_loop_mac_msdos args ( ( void ) );
bool read_from_descriptor args ( ( DESCRIPTOR_DATA * d ) );
bool write_to_descriptor args ( ( int desc, char *txt, int length ) );
#endif
#if defined(unix)
void game_loop_unix args ( ( int control, int wwwcontrol ) );
int init_socket args ( ( int port ) );
void init_descriptor args ( ( int control ) );
void init_descriptor_www args ( ( int wwwcontrol ) );
bool read_from_descriptor args ( ( DESCRIPTOR_DATA * d ) );
bool write_to_descriptor args ( ( int desc, char *txt, int length ) );
#endif
/* Needs to be global because of do_copyover */
int port, control, wwwport, wwwcontrol;
volatile sig_atomic_t crashed = 0;
static void sigalrm ( sig )
int sig;
{
time_t tm;
time ( &tm );
fprintf ( stderr, "TOCK!\n\r" );
if ( ( tm - current_time ) > 240 )
{
fprintf ( stderr, "Looping - Last Command: %s\r", last_command );
// this requires you to add an "if (ch)" before the send_to_char
// statements in do_copyover.
do_copyover ( NULL, "" );
exit ( 1 );
}
alarm ( 300 );
}
int main ( int argc, char **argv )
{
struct timeval now_time;
bool fCopyOver = FALSE;
struct sigaction halt_action, ignore_action, alarm_action;
halt_action.sa_handler = halt_mud;
sigemptyset ( &halt_action.sa_mask );
halt_action.sa_flags = SA_NOMASK;
ignore_action.sa_handler = SIG_IGN;
sigemptyset ( &ignore_action.sa_mask );
ignore_action.sa_flags = 0;
alarm_action.sa_handler = sigalrm;
sigemptyset ( &alarm_action.sa_mask );
alarm_action.sa_flags = SA_NOMASK;
sigaction ( SIGPIPE, &ignore_action, NULL ); /* who cares about pipes? */
sigaction ( SIGHUP, &ignore_action, NULL ); /* stay alive if user quits */
sigaction ( SIGINT, &halt_action, NULL ); /* interrupted at keyboard */
sigaction ( SIGQUIT, &halt_action, NULL ); /* quit at keyboard */
sigaction ( SIGILL, &halt_action, NULL ); /* illegal instruction */
sigaction ( SIGFPE, &halt_action, NULL ); /* floating point error */
sigaction ( SIGSEGV, &halt_action, NULL ); /* invalid memory reference */
sigaction ( SIGTERM, &halt_action, NULL ); /* terminate */
sigaction ( SIGBUS, &halt_action, NULL ); /* out of memory?? */
sigaction ( SIGALRM, &alarm_action, NULL ); /* endless loop check */
alarm ( 300 );
/*
* Memory debugging if needed.
*/
#if defined(MALLOC_DEBUG)
malloc_debug ( 2 );
#endif
/*
* Init time.
*/
gettimeofday ( &now_time, NULL );
current_time = ( time_t ) now_time.tv_sec;
strcpy ( str_boot_time, ctime ( ¤t_time ) );
/*
* Macintosh console initialization.
*/
#if defined(macintosh)
console_options.nrows = 31;
cshow ( stdout );
csetmode ( C_RAW, stdin );
cecho2file ( "log file", 1, stderr );
#endif
/*
* Reserve one channel for our use.
*/
if ( ( fpReserve = fopen ( NULL_FILE, "r" ) ) == NULL )
{
perror ( NULL_FILE );
quit ( 1 );
}
/*
* Get the port number.
*/
port = 6000;
if ( argc > 1 )
{
if ( !is_number ( argv[1] ) )
{
fprintf ( stderr, "Usage: %s [port ##] [wwwport #]\n", argv[0] );
quit ( 1 );
}
else if ( ( port = atoi ( argv[1] ) ) <= 1024 )
{
fprintf ( stderr, "Port numbers must be above 1024.\n" );
quit ( 1 );
}
}
wwwport = port + 1;
if ( argc > 2 )
{
if ( !is_number ( argv[2] ) )
{
fprintf ( stderr, "Usage: %s [port #] [wwwport ##]\n", argv[0] );
quit ( 1 );
}
else if ( ( wwwport = atoi ( argv[2] ) ) <= 1024 )
{
fprintf ( stderr, "Port numbers must be above 1024.\n" );
quit ( 1 );
}
}
if ( argc > 3 )
{
if ( !str_cmp ( argv[3], "copyover" ) && is_number ( argv[4] ) &&
is_number ( argv[5] ) )
{
fCopyOver = TRUE;
control = atoi ( argv[4] );
wwwcontrol = atoi ( argv[5] );
}
else
fCopyOver = FALSE;
}
/*
* Run the game.
*/
log_string ( "Initializing Telnet Port." );
if ( fCopyOver == FALSE )
control = init_socket ( port );
log_string ( "Initializing WWW Port." );
if ( fCopyOver == FALSE )
wwwcontrol = init_socket ( wwwport );
boot_db ( );
arena = FIGHT_OPEN;
sprintf ( log_buf, "MUD Booted: Telnet: %d, WWW: %d", port, wwwport );
log_string ( log_buf );
if ( fCopyOver == TRUE )
{
log_string ( "Initiating CopyOver Recovery" );
copyover_recover ( );
log_string ( "CopyOver Recovery Completed." );
}
game_loop_unix ( control, wwwcontrol );
close ( wwwcontrol );
close ( control );
/*
* That's all, folks.
*/
log_string ( "Normal termination of game." );
quit ( 0 );
return 0;
}
#if defined(unix)
int init_socket ( int port )
{
static struct sockaddr_in sa_zero;
struct sockaddr_in sa;
int x = 1;
int fd;
if ( ( fd = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
perror ( "Init_socket: socket" );
quit ( 1 );
}
if ( setsockopt
( fd, SOL_SOCKET, SO_REUSEADDR, ( char * ) &x, sizeof ( x ) ) < 0 )
{
perror ( "Init_socket: SO_REUSEADDR" );
close ( fd );
quit ( 1 );
}
#if defined(SO_DONTLINGER) && !defined(SYSV)
{
struct linger ld;
ld.l_onoff = 1;
ld.l_linger = 1000;
if ( setsockopt
( fd, SOL_SOCKET, SO_DONTLINGER, ( char * ) &ld,
sizeof ( ld ) ) < 0 )
{
perror ( "Init_socket: SO_DONTLINGER" );
close ( fd );
quit ( 1 );
}
}
#endif
sa = sa_zero;
sa.sin_family = AF_INET;
sa.sin_port = htons ( port );
if ( bind ( fd, ( struct sockaddr * ) &sa, sizeof ( sa ) ) < 0 )
{
perror ( "Init socket: bind" );
close ( fd );
quit ( 1 );
}
if ( listen ( fd, 3 ) < 0 )
{
perror ( "Init socket: listen" );
close ( fd );
quit ( 1 );
}
return fd;
}
#endif
#if defined(macintosh) || defined(MSDOS)
void game_loop_mac_msdos ( void )
{
struct timeval last_time;
struct timeval now_time;
static DESCRIPTOR_DATA dcon;
gettimeofday ( &last_time, NULL );
current_time = ( time_t ) last_time.tv_sec;
/*
* New_descriptor analogue.
*/
dcon.descriptor = 0;
dcon.connected = CON_GET_NAME;
dcon.host = str_dup ( "localhost" );
dcon.outsize = 2000;
dcon.outbuf = alloc_mem ( dcon.outsize );
dcon.next = descriptor_list;
dcon.showstr_head = NULL;
dcon.showstr_point = NULL;
dcon.pEdit = NULL; /* OLC */
dcon.pString = NULL; /* OLC */
dcon.editor = 0; /* OLC */
dcon.ansi = TRUE;
descriptor_list = &dcon;
/*
* Send the greeting.
*/
{
extern char *help_greetinga;
extern char *help_greetingb;
extern char *help_greetingc;
extern char *help_greetingd;
extern char *help_greetinge;
extern char *help_authors;
extern char *help_login;
switch ( number_range ( 0, 4 ) )
{
default:
if ( help_greetinga[0] == '.' )
write_to_buffer ( &dcon, help_greetinga + 1, 0 );
else
write_to_buffer ( &dcon, help_greetinga, 0 );
break;
case 0:
if ( help_greetinga[0] == '.' )
write_to_buffer ( &dcon, help_greetinga + 1, 0 );
else
write_to_buffer ( &dcon, help_greetinga, 0 );
break;
case 1:
if ( help_greetingb[0] == '.' )
write_to_buffer ( &dcon, help_greetingb + 1, 0 );
else
write_to_buffer ( &dcon, help_greetingb, 0 );
break;
case 2:
if ( help_greetingc[0] == '.' )
write_to_buffer ( &dcon, help_greetingc + 1, 0 );
else
write_to_buffer ( &dcon, help_greetingc, 0 );
break;
case 3:
if ( help_greetingd[0] == '.' )
write_to_buffer ( &dcon, help_greetingd + 1, 0 );
else
write_to_buffer ( &dcon, help_greetingd, 0 );
break;
case 4:
if ( help_greetinge[0] == '.' )
write_to_buffer ( &dcon, help_greetinge + 1, 0 );
else
write_to_buffer ( &dcon, help_greetinge, 0 );
break;
}
if ( help_authors[0] == '.' )
write_to_buffer ( &dcon, help_authors + 1, 0 );
else
write_to_buffer ( &dcon, help_authors, 0 );
if ( help_login[0] == '.' )
write_to_buffer ( &dcon, help_login + 1, 0 );
else
write_to_buffer ( &dcon, help_login, 0 );
}
/* Main loop */
while ( !merc_down )
{
DESCRIPTOR_DATA *d;
/*
* Process input.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
d->fcommand = FALSE;
#if defined(MSDOS)
if ( kbhit ( ) )
#endif
{
if ( d->character != NULL )
d->character->timer = 0;
if ( !read_from_descriptor ( d ) )
{
if ( d->character != NULL )
save_char_obj ( d->character );
d->outtop = 0;
close_socket ( d );
continue;
}
}
if ( d->character != NULL && d->character->daze > 0 )
--d->character->daze;
if ( d->character != NULL && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
read_from_buffer ( d );
if ( d->incomm[0] != '\0' )
{
d->fcommand = TRUE;
stop_idling ( d->character );
/* OLC */
if ( d->showstr_point )
show_string ( d, d->incomm );
else if ( d->pString )
string_add ( d->character, d->incomm );
else
switch ( d->connected )
{
case CON_PLAYING:
if ( !run_olc_editor ( d ) )
substitute_alias ( d, d->incomm );
break;
default:
nanny ( d, d->incomm );
break;
}
d->incomm[0] = '\0';
}
}
/*
* Autonomous game motion.
*/
update_handler ( );
/*
* Output.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( ( d->fcommand || d->outtop > 0 ) )
{
if ( !process_output ( d, TRUE ) )
{
if ( d->character != NULL && d->character->level > 1 )
save_char_obj ( d->character );
d->outtop = 0;
close_socket ( d );
}
}
}
/*
* Synchronize to a clock.
* Busy wait (blargh).
*/
now_time = last_time;
for ( ;; )
{
int delta;
#if defined(MSDOS)
if ( kbhit ( ) )
#endif
{
if ( dcon.character != NULL )
dcon.character->timer = 0;
if ( !read_from_descriptor ( &dcon ) )
{
if ( dcon.character != NULL && d->character->level > 1 )
save_char_obj ( d->character );
dcon.outtop = 0;
close_socket ( &dcon );
}
#if defined(MSDOS)
break;
#endif
}
gettimeofday ( &now_time, NULL );
delta =
( now_time.tv_sec - last_time.tv_sec ) * 1000 * 1000 +
( now_time.tv_usec - last_time.tv_usec );
if ( delta >= 1000000 / PULSE_PER_SECOND )
break;
}
last_time = now_time;
current_time = ( time_t ) last_time.tv_sec;
}
return;
}
#endif
#if defined(unix)
void game_loop_unix ( int control, int wwwcontrol )
{
static struct timeval null_time;
struct timeval last_time;
signal ( SIGPIPE, SIG_IGN );
gettimeofday ( &last_time, NULL );
current_time = ( time_t ) last_time.tv_sec;
/* Main loop */
while ( !merc_down )
{
fd_set in_set;
fd_set out_set;
fd_set exc_set;
DESCRIPTOR_DATA *d;
int maxdesc;
#if defined(MALLOC_DEBUG)
if ( malloc_verify ( ) != 1 )
abort ( );
#endif
/*
* Poll all active descriptors.
*/
FD_ZERO ( &in_set );
FD_ZERO ( &out_set );
FD_ZERO ( &exc_set );
FD_SET ( control, &in_set );
maxdesc = control;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX ( maxdesc, d->descriptor );
FD_SET ( d->descriptor, &in_set );
FD_SET ( d->descriptor, &out_set );
FD_SET ( d->descriptor, &exc_set );
}
if ( select ( maxdesc + 1, &in_set, &out_set, &exc_set, &null_time ) <
0 )
{
perror ( "Game_loop: select: poll" );
quit ( 1 );
}
/*
* New connection?
*/
if ( FD_ISSET ( control, &in_set ) )
init_descriptor ( control );
FD_ZERO ( &in_set );
FD_ZERO ( &out_set );
FD_ZERO ( &exc_set );
FD_SET ( wwwcontrol, &in_set );
maxdesc = wwwcontrol;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX ( maxdesc, d->descriptor );
FD_SET ( d->descriptor, &in_set );
FD_SET ( d->descriptor, &out_set );
FD_SET ( d->descriptor, &exc_set );
}
if ( select ( maxdesc + 1, &in_set, &out_set, &exc_set, &null_time ) <
0 )
{
perror ( "Game_loop: select: poll" );
quit ( 1 );
}
if ( FD_ISSET ( wwwcontrol, &in_set ) )
init_descriptor_www ( wwwcontrol );
/*
* Kick out the freaky folks.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( FD_ISSET ( d->descriptor, &exc_set ) )
{
FD_CLR ( d->descriptor, &in_set );
FD_CLR ( d->descriptor, &out_set );
if ( d->character && d->character->level > 1 )
save_char_obj ( d->character );
d->outtop = 0;
close_socket ( d );
}
}
/*
* Process input.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
d->fcommand = FALSE;
if ( FD_ISSET ( d->descriptor, &in_set ) )
{
if ( d->character != NULL )
d->character->timer = 0;
if ( !read_from_descriptor ( d ) )
{
FD_CLR ( d->descriptor, &out_set );
if ( d->character != NULL && d->character->level > 1 )
save_char_obj ( d->character );
d->outtop = 0;
close_socket ( d );
continue;
}
}
if ( d->character != NULL && d->character->daze > 0 )
--d->character->daze;
if ( d->character != NULL && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
read_from_buffer ( d );
if ( d->incomm[0] != '\0' )
{
d->fcommand = TRUE;
stop_idling ( d->character );
/* OLC */
if ( d->showstr_point )
show_string ( d, d->incomm );
else if ( d->pString )
string_add ( d->character, d->incomm );
else
switch ( d->connected )
{
case CON_PLAYING:
if ( !run_olc_editor ( d ) )
substitute_alias ( d, d->incomm );
break;
default:
nanny ( d, d->incomm );
break;
}
d->incomm[0] = '\0';
}
}
/*
* Autonomous game motion.
*/
update_handler ( );
/*
* Output.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( ( d->fcommand || d->outtop > 0 ) &&
FD_ISSET ( d->descriptor, &out_set ) )
{
if ( !process_output ( d, TRUE ) )
{
if ( d->character != NULL && d->character->level > 1 )
save_char_obj ( d->character );
d->outtop = 0;
close_socket ( d );
}
}
}
/*
* Synchronize to a clock.
* Sleep( last_time + 1/PULSE_PER_SECOND - now ).
* Careful here of signed versus unsigned arithmetic.
*/
{
struct timeval now_time;
long secDelta;
long usecDelta;
gettimeofday ( &now_time, NULL );
usecDelta =
( ( int ) last_time.tv_usec ) - ( ( int ) now_time.tv_usec ) +
1000000 / PULSE_PER_SECOND;
secDelta =
( ( int ) last_time.tv_sec ) - ( ( int ) now_time.tv_sec );
while ( usecDelta < 0 )
{
usecDelta += 1000000;
secDelta -= 1;
}
while ( usecDelta >= 1000000 )
{
usecDelta -= 1000000;
secDelta += 1;
}
if ( secDelta > 0 || ( secDelta == 0 && usecDelta > 0 ) )
{
struct timeval stall_time;
stall_time.tv_usec = usecDelta;
stall_time.tv_sec = secDelta;
if ( select ( 0, NULL, NULL, NULL, &stall_time ) < 0 )
{
if ( errno != EINTR )
{
perror ( "Game_loop: select: stall" );
quit ( 1 );
}
}
}
}
gettimeofday ( &last_time, NULL );
current_time = ( time_t ) last_time.tv_sec;
}
return;
}
#endif
/*void game_loop_unix( int control )
{
static struct timeval null_time;
struct timeval last_time;
signal( SIGPIPE, SIG_IGN );
gettimeofday( &last_time, NULL );
current_time = (time_t) last_time.tv_sec;
*//* Main loop *//*
while ( !merc_down )
{
fd_set in_set;
fd_set out_set;
fd_set exc_set;
DESCRIPTOR_DATA *d;
int maxdesc;
#if defined(MALLOC_DEBUG)
if ( malloc_verify( ) != 1 )
abort( );
#endif
*//*
* Poll all active descriptors.
*//*
FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( control, &in_set );
maxdesc = control;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}
if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}
*/
/*
* New connection?
*//*
if ( FD_ISSET( control, &in_set ) )
init_descriptor( control );
FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( wwwcontrol, &in_set );
maxdesc = wwwcontrol;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}
if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}
if ( FD_ISSET( wwwcontrol, &in_set ) )
init_descriptor_www( wwwcontrol );
*/
/*
* Kick out the freaky folks.
*//*
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( FD_ISSET( d->descriptor, &exc_set ) )
{
FD_CLR( d->descriptor, &in_set );
FD_CLR( d->descriptor, &out_set );
if ( d->character && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
}
}
*/
/*
* Process input.
*//*
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
d->fcommand = FALSE;
if ( FD_ISSET( d->descriptor, &in_set ) )
{
if ( d->character != NULL )
d->character->timer = 0;
if ( !read_from_descriptor( d ) )
{
FD_CLR( d->descriptor, &out_set );
if ( d->character != NULL && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
continue;
}
}
if (d->character != NULL && d->character->daze > 0)
--d->character->daze;
if ( d->character != NULL && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
read_from_buffer( d );
if ( d->incomm[0] != '\0' )
{
d->fcommand = TRUE;
stop_idling( d->character );
*//* OLC *//*
if ( d->showstr_point )
show_string( d, d->incomm );
else
if ( d->pString )
string_add( d->character, d->incomm );
else
switch ( d->connected )
{
case CON_PLAYING:
if ( !run_olc_editor( d ) )
substitute_alias( d, d->incomm );
break;
default:
nanny( d, d->incomm );
break;
}
d->incomm[0] = '\0';
}
}
*/
/*
* Autonomous game motion.
*//*
update_handler( );
*/
/*
* Output.
*//*
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( ( d->fcommand || d->outtop > 0 )
&& FD_ISSET(d->descriptor, &out_set) )
{
if ( !process_output( d, TRUE ) )
{
if ( d->character != NULL && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
}
}
}
*//*
* Synchronize to a clock.
* Sleep( last_time + 1/PULSE_PER_SECOND - now ).
* Careful here of signed versus unsigned arithmetic.
*//*
{
struct timeval now_time;
long secDelta;
long usecDelta;
gettimeofday( &now_time, NULL );
usecDelta = ((int) last_time.tv_usec) - ((int) now_time.tv_usec)
+ 1000000 / PULSE_PER_SECOND;
secDelta = ((int) last_time.tv_sec ) - ((int) now_time.tv_sec );
while ( usecDelta < 0 )
{
usecDelta += 1000000;
secDelta -= 1;
}
while ( usecDelta >= 1000000 )
{
usecDelta -= 1000000;
secDelta += 1;
}
if ( secDelta > 0 || ( secDelta == 0 && usecDelta > 0 ) )
{
struct timeval stall_time;
stall_time.tv_usec = usecDelta;
stall_time.tv_sec = secDelta;
if ( select( 0, NULL, NULL, NULL, &stall_time ) < 0 )
{
perror( "Game_loop: select: stall" );
exit( 1 );
}
}
}
gettimeofday( &last_time, NULL );
current_time = (time_t) last_time.tv_sec;
}
return;
}
#endif */
#if defined(unix)
void init_descriptor ( int control )
{
char buf[MAX_STRING_LENGTH];
DESCRIPTOR_DATA *dnew;
struct sockaddr_in sock;
struct hostent *from;
int desc;
int size;
size = sizeof ( sock );
getsockname ( control, ( struct sockaddr * ) &sock, &size );
if ( ( desc =
accept ( control, ( struct sockaddr * ) &sock, &size ) ) < 0 )
{
perror ( "New_descriptor: accept" );
return;
}
#if !defined(FNDELAY)
#define FNDELAY O_NDELAY
#endif
if ( fcntl ( desc, F_SETFL, FNDELAY ) == -1 )
{
perror ( "New_descriptor: fcntl: FNDELAY" );
return;
}
/*
* Cons a new descriptor.
*/
/*
dnew = new_descriptor();
dnew->descriptor = desc;
dnew->connected = CON_GET_NAME;
dnew->showstr_head = NULL;
dnew->showstr_point = NULL;
dnew->outsize = 2000;
dnew->outbuf = alloc_mem( dnew->outsize );
*/
dnew = new_descriptor ( ); /* new_descriptor now also allocates things */
dnew->descriptor = desc;
dnew->pEdit = NULL; /* OLC */
dnew->pString = NULL; /* OLC */
dnew->editor = 0; /* OLC */
dnew->ansi = TRUE;
size = sizeof ( sock );
if ( getpeername ( desc, ( struct sockaddr * ) &sock, &size ) < 0 )
{
perror ( "New_descriptor: getpeername" );
dnew->host = str_dup ( "(unknown)" );
}
else
{
/*
* Would be nice to use inet_ntoa here but it takes a struct arg,
* which ain't very compatible between gcc and system libraries.
*/
int addr;
addr = ntohl ( sock.sin_addr.s_addr );
sprintf ( buf, "%d.%d.%d.%d", ( addr >> 24 ) & 0xFF,
( addr >> 16 ) & 0xFF, ( addr >> 8 ) & 0xFF,
( addr ) & 0xFF );
sprintf ( log_buf, "Sock.sinaddr: %s", buf );
log_string ( log_buf );
from =
gethostbyaddr ( ( char * ) &sock.sin_addr,
sizeof ( sock.sin_addr ), AF_INET );
dnew->host = str_dup ( from ? from->h_name : buf );
}
/*
* Swiftest: I added the following to ban sites. I don't
* endorse banning of sites, but Copper has few descriptors now
* and some people from certain sites keep abusing access by
* using automated 'autodialers' and leaving connections hanging.
*
* Furey: added suffix check by request of Nickel of HiddenWorlds.
*/
if ( check_ban ( dnew->host, BAN_ALL ) )
{
write_to_descriptor ( desc,
"Your site has been banned from this mud.\n\r",
0 );
close ( desc );
free_descriptor ( dnew );
return;
}
/*
* Init descriptor data.
*/
dnew->next = descriptor_list;
descriptor_list = dnew;
/*
* Send the greeting.
*/
{
switch ( number_range ( 0, 4 ) )
{
default:
if ( help_greetinga[0] == '.' )
write_to_buffer ( dnew, help_greetinga + 1, 0 );
else
write_to_buffer ( dnew, help_greetinga, 0 );
break;
case 0:
if ( help_greetinga[0] == '.' )
write_to_buffer ( dnew, help_greetinga + 1, 0 );
else
write_to_buffer ( dnew, help_greetinga, 0 );
break;
case 1:
if ( help_greetingb[0] == '.' )
write_to_buffer ( dnew, help_greetingb + 1, 0 );
else
write_to_buffer ( dnew, help_greetingb, 0 );
break;
case 2:
if ( help_greetingc[0] == '.' )
write_to_buffer ( dnew, help_greetingc + 1, 0 );
else
write_to_buffer ( dnew, help_greetingc, 0 );
break;
case 3:
if ( help_greetingd[0] == '.' )
write_to_buffer ( dnew, help_greetingd + 1, 0 );
else
write_to_buffer ( dnew, help_greetingd, 0 );
break;
case 4:
if ( help_greetinge[0] == '.' )
write_to_buffer ( dnew, help_greetinge + 1, 0 );
else
write_to_buffer ( dnew, help_greetinge, 0 );
break;
}
if ( help_authors[0] == '.' )
write_to_buffer ( dnew, help_authors + 1, 0 );
else
write_to_buffer ( dnew, help_authors, 0 );
if ( help_login[0] == '.' )
write_to_buffer ( dnew, help_login + 1, 0 );
else
write_to_buffer ( dnew, help_login, 0 );
}
return;
}
#endif
#if defined(unix)
void init_descriptor_www ( int wwwcontrol )
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
DESCRIPTOR_DATA *dnew;
struct sockaddr_in sock;
struct hostent *from;
int desc;
int size;
char clandat[MAX_STRING_LENGTH];
BUFFER *output;
DESCRIPTOR_DATA *d;
int iClass;
int iRace;
int iClan;
int iLevelLower;
int iLevelUpper;
int nMatch;
FILE *fg;
bool rgfClass[MAX_CLASS];
bool rgfRace[MAX_PC_RACE];
bool rgfClan[MAX_CLAN];
bool fClassRestrict = FALSE;
bool fClanRestrict = FALSE;
bool fClan = FALSE;
bool fRaceRestrict = FALSE;
bool fImmortalOnly = FALSE;
size = sizeof ( sock );
getsockname ( wwwcontrol, ( struct sockaddr * ) &sock, &size );
if ( ( desc =
accept ( wwwcontrol, ( struct sockaddr * ) &sock, &size ) ) < 0 )
{
perror ( "New_descriptor: accept" );
return;
}
#if !defined(FNDELAY)
#define FNDELAY O_NDELAY
#endif
if ( fcntl ( desc, F_SETFL, FNDELAY ) == -1 )
{
perror ( "New_descriptor: fcntl: FNDELAY" );
return;
}
/*
* Cons a new descriptor.
*/
dnew = new_descriptor ( );
dnew->descriptor = desc;
dnew->connected = CON_GET_NAME;
dnew->showstr_head = NULL;
dnew->showstr_point = NULL;
dnew->outsize = 2000;
dnew->outbuf = alloc_mem ( dnew->outsize );
size = sizeof ( sock );
if ( getpeername ( desc, ( struct sockaddr * ) &sock, &size ) < 0 )
{
perror ( "New_descriptor: getpeername" );
dnew->host = str_dup ( "(unknown)" );
}
else
{
/*
* Would be nice to use inet_ntoa here but it takes a struct arg,
* which ain't very compatible between gcc and system libraries.
*/
int addr;
addr = ntohl ( sock.sin_addr.s_addr );
sprintf ( buf, "%d.%d.%d.%d", ( addr >> 24 ) & 0xFF,
( addr >> 16 ) & 0xFF, ( addr >> 8 ) & 0xFF,
( addr ) & 0xFF );
sprintf ( log_buf, "Sock.sinaddr: %s", buf );
from =
gethostbyaddr ( ( char * ) &sock.sin_addr,
sizeof ( sock.sin_addr ), AF_INET );
dnew->host = str_dup ( from ? from->h_name : buf );
}
iLevelLower = 0;
iLevelUpper = MAX_LEVEL;
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
rgfClass[iClass] = FALSE;
for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ )
rgfRace[iRace] = FALSE;
for ( iClan = 0; iClan < MAX_CLAN; iClan++ )
rgfClan[iClan] = FALSE;
nMatch = 0;
buf[0] = '\0';
output = new_buf ( );
sprintf ( buf, WWW_WHO );
if ( ( fg = file_open ( buf, "w" ) ) == NULL )
{
bug ( "WWW-Who: fopen", 0 );
perror ( buf );
}
for ( d = descriptor_list; d != NULL; d = d->next )
{
CHAR_DATA *wch;
char const *class;
buf[0] = '\0';
/*
* Check for match against restrictions.
* Don't use trust as that exposes trusted mortals.
*/
if ( d->connected != CON_PLAYING || d->character->invis_level > 1 ||
d->character->incog_level > 1 )
continue;
wch = ( d->original != NULL ) ? d->original : d->character;
if ( IS_SHIELDED ( wch, SHD_INVISIBLE ) )
continue;
if ( wch->invis_level >= 2 || wch->incog_level >= 2 )
continue;
if ( wch->in_room->vnum == ROOM_VNUM_CORNER )
continue;
if ( wch->level < iLevelLower || wch->level > iLevelUpper ||
( fImmortalOnly && wch->level < LEVEL_IMMORTAL ) ||
( fClassRestrict && !rgfClass[wch->class] ) || ( fRaceRestrict &&
!rgfRace[wch->
race] )
|| ( fClan && !is_clan ( wch ) ) || ( fClanRestrict &&
!rgfClan[wch->clan] ) )
continue;
nMatch++;
/*
* Figure out what to print for class.
*/
class = class_table[wch->class].who_name;
/*
* Format it up.
*/
if ( !is_clan ( wch ) )
{
sprintf ( clandat, "X,3,3" );
}
else
{
if ( clan_table[wch->clan].independent )
{
sprintf ( clandat, "%s,0,0", clan_table[wch->clan].who_name );
}
else if ( is_clead ( wch ) && is_pkill ( wch ) )
{
sprintf ( clandat, "%s,1,1", clan_table[wch->clan].who_name );
}
else if ( is_clead ( wch ) && !is_pkill ( wch ) )
{
sprintf ( clandat, "%s,2,1", clan_table[wch->clan].who_name );
}
else if ( is_pkill ( wch ) )
{
sprintf ( clandat, "%s,1,0", clan_table[wch->clan].who_name );
}
else
{
sprintf ( clandat, "%s,2,0", clan_table[wch->clan].who_name );
}
}
sprintf ( buf2, "%s", IS_NPC ( wch ) ? "" : wch->pcdata->title );
str_replace ( buf2, "{%", "{-" );
sprintf ( buf, "%3d,%s,%s,%s,%s%s\n\r", wch->level,
wch->race <
MAX_PC_RACE ? pc_race_table[wch->race].who_name : " ",
class, clandat, wch->name, buf2 );
fprintf ( fg, buf );
}
file_close ( fg );
close ( desc );
free_descriptor ( dnew );
return;
}
#endif
void close_socket ( DESCRIPTOR_DATA * dclose )
{
CHAR_DATA *ch;
if ( dclose->outtop > 0 )
process_output ( dclose, FALSE );
if ( dclose->snoop_by != NULL )
{
write_to_buffer ( dclose->snoop_by,
"Your victim has left the game.\n\r", 0 );
}
{
DESCRIPTOR_DATA *d;
for ( d = descriptor_list; d != NULL; d = d->next )
{
if ( d->snoop_by == dclose )
d->snoop_by = NULL;
}
}
if ( ( ch = dclose->character ) != NULL )
{
sprintf ( log_buf, "Closing link to %s.", ch->name );
log_string ( log_buf );
if ( dclose->connected == CON_PLAYING )
{
act ( "$n has lost $s link.", ch, NULL, NULL, TO_ROOM );
wiznet ( "Net death has claimed $N.", ch, NULL, WIZ_LINKS, 0, 0 );
{
char buf[MAX_STRING_LENGTH];
act ( buf, ch, NULL, NULL, TO_ALL );
}
ch->desc = NULL;
}
else
{
free_char ( dclose->original ? dclose->original : dclose->
character );
}
}
if ( d_next == dclose )
d_next = d_next->next;
if ( dclose == descriptor_list )
{
descriptor_list = descriptor_list->next;
}
/* if ( IS_SET(ch->act2,PLR2_CHALLENGER) && arena == 0 )
{
char buf[MAX_STRING_LENGTH];
REMOVE_BIT(ch->act2,PLR2_CHALLENGER);
REMOVE_BIT(ch->challenged->act2,PLR2_CHALLENGED);
ch->challenged->challenger = NULL;
ch->challenged = NULL;
arena = FIGHT_OPEN;
sprintf(buf, "[Arena] %s has lost $s link. Arena is OPEN.", ch->name);
return;
} */
else
{
DESCRIPTOR_DATA *d;
for ( d = descriptor_list; d && d->next != dclose; d = d->next )
;
if ( d != NULL )
d->next = dclose->next;
else
bug ( "Close_socket: dclose not found.", 0 );
}
close ( dclose->descriptor );
free_descriptor ( dclose );
#if defined(MSDOS) || defined(macintosh)
quit ( 1 );
#endif
return;
}
bool read_from_descriptor ( DESCRIPTOR_DATA * d )
{
int iStart;
/* Hold horses if pending command already. */
if ( d->incomm[0] != '\0' )
return TRUE;
/* Check for overflow. */
iStart = strlen ( d->inbuf );
if ( iStart >= sizeof ( d->inbuf ) - 10 )
{
sprintf ( log_buf, "%s input overflow!", d->host );
log_string ( log_buf );
write_to_descriptor ( d->descriptor,
"\n\r*** PUT A LID ON IT!!! ***\n\r", 0 );
return FALSE;
}
/* Snarf input. */
#if defined(macintosh)
for ( ;; )
{
int c;
c = getc ( stdin );
if ( c == '\0' || c == EOF )
break;
putc ( c, stdout );
if ( c == '\r' )
putc ( '\n', stdout );
d->inbuf[iStart++] = c;
if ( iStart > sizeof ( d->inbuf ) - 10 )
break;
}
#endif
#if defined(MSDOS) || defined(unix)
for ( ;; )
{
int nRead;
nRead =
read ( d->descriptor, d->inbuf + iStart,
sizeof ( d->inbuf ) - 10 - iStart );
if ( nRead > 0 )
{
iStart += nRead;
if ( d->inbuf[iStart - 1] == '\n' ||
d->inbuf[iStart - 1] == '\r' )
break;
}
else if ( nRead == 0 )
{
log_string ( "EOF encountered on read." );
return FALSE;
}
else if ( errno == EWOULDBLOCK )
break;
else
{
perror ( "Read_from_descriptor" );
return FALSE;
}
}
#endif
d->inbuf[iStart] = '\0';
return TRUE;
}
/*
* Transfer one line from input buffer to input line.
*/
void read_from_buffer ( DESCRIPTOR_DATA * d )
{
int i, j, k;
/*
* Hold horses if pending command already.
*/
if ( d->incomm[0] != '\0' )
return;
/*
* Look for at least one new line.
*/
for ( i = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++ )
{
if ( d->inbuf[i] == '\0' )
return;
}
/*
* Canonical input processing.
*/
for ( i = 0, k = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++ )
{
if ( k >= MAX_INPUT_LENGTH - 2 )
{
write_to_descriptor ( d->descriptor, "Line too long.\n\r", 0 );
/* skip the rest of the line */
for ( ; d->inbuf[i] != '\0'; i++ )
{
if ( d->inbuf[i] == '\n' || d->inbuf[i] == '\r' )
break;
}
d->inbuf[i] = '\n';
d->inbuf[i + 1] = '\0';
break;
}
if ( d->inbuf[i] == '\b' && k > 0 )
--k;
else if ( isascii ( d->inbuf[i] ) && isprint ( d->inbuf[i] ) )
d->incomm[k++] = d->inbuf[i];
}
/*
* Finish off the line.
*/
if ( k == 0 )
d->incomm[k++] = ' ';
d->incomm[k] = '\0';
/*
* Deal with bozos with #repeat 1000 ...
*/
if ( k > 1 || d->incomm[0] == '!' )
{
if ( d->incomm[0] != '!' && str_cmp ( d->incomm, d->inlast ) )
{
d->repeat = 0;
}
else
{
d->repeat++;
if ( d->repeat == 25 )
{
sprintf ( log_buf, "%s input spamming!", d->host );
log_string ( log_buf );
wiznet ( "Spam spam spam $N spam spam spam spam spam!",
d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
if ( d->incomm[0] == '!' )
wiznet ( d->inlast, d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
else
wiznet ( d->incomm, d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
}
else if ( d->repeat == 35 )
{
sprintf ( log_buf, "%s still input spamming!", d->host );
log_string ( log_buf );
wiznet ( "Spam spam spam $N spam spam spam spam spam!",
d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
if ( d->incomm[0] == '!' )
wiznet ( d->inlast, d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
else
wiznet ( d->incomm, d->character, NULL, WIZ_SPAM, 0,
get_trust ( d->character ) );
write_to_descriptor ( d->descriptor,
"\n\r*** PUT A LID ON IT!!! ***\n\r",
0 );
}
else if ( d->repeat >= 45 )
{
d->repeat = 0;
write_to_descriptor ( d->descriptor,
"\n\r*** I WARNED YOU!!! ***\n\r", 0 );
strcpy ( d->incomm, "quit" );
}
}
}
/*
* Do '!' substitution.
*/
if ( d->incomm[0] == '!' )
strcpy ( d->incomm, d->inlast );
else
strcpy ( d->inlast, d->incomm );
/*
* Shift the input buffer.
*/
while ( d->inbuf[i] == '\n' || d->inbuf[i] == '\r' )
i++;
for ( j = 0; ( d->inbuf[j] = d->inbuf[i + j] ) != '\0'; j++ )
;
return;
}
/** Function: process_ansi_output
* Descr : Sends buffered output to descriptor, converting any ANSI codes
* : along the way if character has selected ANSI.
* Returns : TRUE/FALSE based on success of output to descriptor
* Syntax : (N/A)
* Written : v1.0 5/98
* Author : Lope, updated by Gary McNickle <gary@tarmongaidon.org>
*/
bool process_ansi_output ( DESCRIPTOR_DATA * d )
{
CHAR_DATA *ch;
char *counter;
char output[MSL];
char clcode[MSL];
char *work;
bool success = TRUE;
char *i;
/*
* No sense in dealing with a null descriptor
*/
if ( d == NULL )
return FALSE;
/*
* Initialize output buffer, counter and working string
*/
memset ( output, 0, MSL );
counter = output;
work = d->outbuf;
while ( *work != '\0' && ( work - d->outbuf ) < d->outtop )
{
if ( ( int ) ( counter - output ) >= MSL - 32 )
{ /*
* have a full buffer
*/
*counter++ = '\0';
if ( !
( success =
write_to_descriptor ( d->descriptor, output,
strlen ( output ) ) ) )
break; /* problems... */
memset ( output, 0, MSL );
counter = output; /* increment counter */
}
if ( *work != '{' )
{
*counter++ = *work++;
continue;
}
/*
* Ok, we have an ansi request... process it
*/
/*
* Pass the '{' code, next should be actual color code itself
*/
work++;
clcode[0] = '\0'; /* Initialize buffer */
ch = d->character;
if ( d->ansi == TRUE )
switch ( *work )
{
default:
strcpy ( clcode, colour_clear ( ch ) );
break;
case 'x':
strcpy ( clcode, colour_clear ( ch ) );
break;
case '0':
strcpy ( clcode, colour_clear ( ch ) );
break;
case 'z':
strcpy ( clcode, BLINK );
break;
case 'b':
strcpy ( clcode, C_BLUE );
break;
case '4':
strcpy ( clcode, C_BLUE );
break;
case 'c':
strcpy ( clcode, C_CYAN );
break;
case '6':
strcpy ( clcode, C_CYAN );
break;
case 'g':
strcpy ( clcode, C_GREEN );
break;
case '2':
strcpy ( clcode, C_GREEN );
break;
case 'm':
strcpy ( clcode, C_MAGENTA );
break;
case '5':
strcpy ( clcode, C_MAGENTA );
break;
case 'r':
strcpy ( clcode, C_RED );
break;
case '1':
strcpy ( clcode, C_RED );
break;
case 'w':
strcpy ( clcode, C_WHITE );
break;
case '7':
strcpy ( clcode, C_WHITE );
break;
case 'y':
strcpy ( clcode, C_YELLOW );
break;
case '3':
strcpy ( clcode, C_YELLOW );
break;
case 'B':
strcpy ( clcode, C_B_BLUE );
break;
case '$':
strcpy ( clcode, FLASHING );
break;
case 'C':
strcpy ( clcode, C_B_CYAN );
break;
case '^':
strcpy ( clcode, C_B_CYAN );
break;
case 'G':
strcpy ( clcode, C_B_GREEN );
break;
case '@':
strcpy ( clcode, C_B_GREEN );
break;
case 'M':
strcpy ( clcode, C_B_MAGENTA );
break;
case '%':
strcpy ( clcode, C_B_MAGENTA );
break;
case 'R':
strcpy ( clcode, C_B_RED );
break;
case '!':
strcpy ( clcode, C_B_RED );
break;
case 'W':
strcpy ( clcode, C_B_WHITE );
break;
case '&':
strcpy ( clcode, C_B_WHITE );
break;
case 'Y':
strcpy ( clcode, C_B_YELLOW );
break;
case '#':
strcpy ( clcode, C_B_YELLOW );
break;
case 'D':
strcpy ( clcode, C_D_GREY );
break;
case '8':
strcpy ( clcode, C_D_GREY );
break;
case '*':
switch ( number_range ( 1, 14 ) )
{
default:
strcpy ( clcode, C_D_GREY );
break;
case 1:
strcpy ( clcode, C_RED );
break;
case 2:
strcpy ( clcode, C_B_RED );
break;
case 3:
strcpy ( clcode, C_GREEN );
break;
case 4:
strcpy ( clcode, C_B_GREEN );
break;
case 5:
strcpy ( clcode, C_YELLOW );
break;
case 6:
strcpy ( clcode, C_B_YELLOW );
break;
case 7:
strcpy ( clcode, C_BLUE );
break;
case 8:
strcpy ( clcode, C_B_BLUE );
break;
case 9:
strcpy ( clcode, C_MAGENTA );
break;
case 10:
strcpy ( clcode, C_B_MAGENTA );
break;
case 11:
strcpy ( clcode, C_CYAN );
break;
case 12:
strcpy ( clcode, C_B_CYAN );
break;
case 13:
strcpy ( clcode, C_WHITE );
break;
case 14:
strcpy ( clcode, C_B_WHITE );
break;
case 15:
strcpy ( clcode, C_D_GREY );
break;
}
break;
case 'A': /* Auction Channel */
if ( ch && ch->color_auc )
strcpy ( clcode,
colour_channel ( ch->color_auc, ch ) );
else
strcpy ( clcode, C_B_GREEN );
break;
case 'E': /* Clan Gossip Channel */
if ( ch && ch->color_cgo )
strcpy ( clcode,
colour_channel ( ch->color_cgo, ch ) );
else
strcpy ( clcode, C_B_RED );
break;
case 'F': /* Clan Talk Channel */
if ( ch && ch->color_cla )
strcpy ( clcode,
colour_channel ( ch->color_cla, ch ) );
else
strcpy ( clcode, C_B_MAGENTA );
break;
case 'H': /* Gossip Channel */
if ( ch && ch->color_gos )
strcpy ( clcode,
colour_channel ( ch->color_gos, ch ) );
else
strcpy ( clcode, C_B_BLUE );
break;
case 'J': /* Grats Channel */
if ( ch && ch->color_gra )
strcpy ( clcode,
colour_channel ( ch->color_gra, ch ) );
else
strcpy ( clcode, C_YELLOW );
break;
case 'K': /* Group Tell Channel */
if ( ch && ch->color_gte )
strcpy ( clcode,
colour_channel ( ch->color_gte, ch ) );
else
strcpy ( clcode, C_CYAN );
break;
case 'L': /* Immortal Talk Channel */
if ( ch && ch->color_imm )
strcpy ( clcode,
colour_channel ( ch->color_imm, ch ) );
else
strcpy ( clcode, C_B_WHITE );
break;
case 'N': /* Music Channel */
if ( ch && ch->color_mus )
strcpy ( clcode,
colour_channel ( ch->color_mus, ch ) );
else
strcpy ( clcode, C_B_CYAN );
break;
case 'P': /* Question+Answer Channel */
if ( ch && ch->color_que )
strcpy ( clcode,
colour_channel ( ch->color_que, ch ) );
else
strcpy ( clcode, C_B_YELLOW );
break;
case 'Q': /* Quote Channel */
if ( ch && ch->color_quo )
strcpy ( clcode,
colour_channel ( ch->color_quo, ch ) );
else
strcpy ( clcode, C_GREEN );
break;
case 'S': /* Say Channel */
if ( ch && ch->color_say )
strcpy ( clcode,
colour_channel ( ch->color_say, ch ) );
else
strcpy ( clcode, C_MAGENTA );
break;
case 'T': /* Shout+Yell Channel */
if ( ch && ch->color_sho )
strcpy ( clcode,
colour_channel ( ch->color_sho, ch ) );
else
strcpy ( clcode, C_RED );
break;
case 'U': /* Tell+Reply Channel */
if ( ch && ch->color_tel )
strcpy ( clcode,
colour_channel ( ch->color_tel, ch ) );
else
strcpy ( clcode, C_CYAN );
break;
case 'V': /* Wiznet Messages */
if ( ch && ch->color_wiz )
strcpy ( clcode,
colour_channel ( ch->color_wiz, ch ) );
else
strcpy ( clcode, C_WHITE );
break;
case 'a': /* Mobile Talk */
if ( ch && ch->color_mob )
strcpy ( clcode,
colour_channel ( ch->color_mob, ch ) );
else
strcpy ( clcode, C_MAGENTA );
break;
case 'e': /* Room Title */
if ( ch && ch->color_roo )
strcpy ( clcode,
colour_channel ( ch->color_roo, ch ) );
else
strcpy ( clcode, C_B_BLUE );
break;
case 'f': /* Opponent Condition */
if ( ch && ch->color_con )
strcpy ( clcode,
colour_channel ( ch->color_con, ch ) );
else
strcpy ( clcode, C_B_RED );
break;
case 'h': /* Fight Actions */
if ( ch && ch->color_fig )
strcpy ( clcode,
colour_channel ( ch->color_fig, ch ) );
else
strcpy ( clcode, C_B_BLUE );
break;
case 'i': /* Opponents Fight Actions */
if ( ch && ch->color_opp )
strcpy ( clcode,
colour_channel ( ch->color_opp, ch ) );
else
strcpy ( clcode, C_CYAN );
break;
case 'j': /* Disarm Messages */
if ( ch && ch->color_dis )
strcpy ( clcode,
colour_channel ( ch->color_dis, ch ) );
else
strcpy ( clcode, C_B_YELLOW );
break;
case 'k': /* Witness Messages */
if ( ch && ch->color_wit )
strcpy ( clcode,
colour_channel ( ch->color_wit, ch ) );
else
strcpy ( clcode, colour_clear ( ch ) );
break;
case 'l': /* Quest Gossip */
if ( ch && ch->color_qgo )
strcpy ( clcode,
colour_channel ( ch->color_qgo, ch ) );
else
strcpy ( clcode, C_B_CYAN );
break;
case '{':
sprintf ( clcode, "%c", '{' );
break;
}
/*
* end: switch
*/
work++; /* pass the ansi request code */
/*
* increment counters
*/
i = clcode;
while ( ( *counter = *i ) != '\0' )
++counter, ++i;
}
success = success &&
( write_to_descriptor ( d->descriptor, output, strlen ( output ) ) );
d->outtop = 0;
return success;
}
/*
* Low level output function.
*/
bool process_output ( DESCRIPTOR_DATA * d, bool fPrompt )
{
/*
* Bust a prompt.
*/
if ( !merc_down )
{
if ( d->showstr_point )
write_to_buffer ( d, "[Hit Return to continue]\n\r", 0 );
else if ( fPrompt && d->pString && d->connected == CON_PLAYING )
write_to_buffer ( d, "> ", 2 );
else if ( fPrompt && d->connected == CON_PLAYING )
{
CHAR_DATA *ch;
CHAR_DATA *victim;
ch = d->character;
/* battle prompt */
if ( ( victim = ch->fighting ) != NULL && can_see ( ch, victim ) )
{
int percent;
char meter[100];
char buf[MAX_STRING_LENGTH];
if ( victim->max_hit > 0 )
percent = victim->hit * 100 / victim->max_hit;
else
percent = -1;
if ( percent >= 100 )
sprintf ( meter, "[{C**********{x]" );
else if ( percent >= 90 )
sprintf ( meter, "[{M********* {x]" );
else if ( percent >= 80 )
sprintf ( meter, "[{Y******** {x]" );
else if ( percent >= 70 )
sprintf ( meter, "[{G******* {x]" );
else if ( percent >= 60 )
sprintf ( meter, "[{B****** {x]" );
else if ( percent >= 50 )
sprintf ( meter, "[{m***** {x]" );
else if ( percent >= 40 )
sprintf ( meter, "[{y**** {x]" );
else if ( percent >= 30 )
sprintf ( meter, "[{g*** {x]" );
else if ( percent >= 20 )
sprintf ( meter, "[{b** {x]" );
else if ( percent >= 10 )
sprintf ( meter, "[{R* {x]" );
else if ( percent >= 0 )
sprintf ( meter, "[{x {x]" );
sprintf ( buf, "%s{x: %s{x\n\r",
IS_NPC ( victim ) ? victim->short_descr : victim->
name, meter );
buf[0] = UPPER ( buf[0] );
send_to_char ( buf, ch );
if ( victim->stunned )
{
sprintf ( buf, "{f%s is stunned.{x\n\r",
IS_NPC ( victim ) ? victim->
short_descr : victim->name );
send_to_char ( buf, ch );
}
if ( victim->max_hit > 0 )
percent = ch->hit * 100 / ch->max_hit;
else
percent = -1;
if ( percent >= 100 )
sprintf ( meter, "[{C**********{x]" );
else if ( percent >= 90 )
sprintf ( meter, "[{M********* {x]" );
else if ( percent >= 80 )
sprintf ( meter, "[{Y******** {x]" );
else if ( percent >= 70 )
sprintf ( meter, "[{G******* {x]" );
else if ( percent >= 60 )
sprintf ( meter, "[{B****** {x]" );
else if ( percent >= 50 )
sprintf ( meter, "[{m***** {x]" );
else if ( percent >= 40 )
sprintf ( meter, "[{y**** {x]" );
else if ( percent >= 30 )
sprintf ( meter, "[{g*** {x]" );
else if ( percent >= 20 )
sprintf ( meter, "[{b** {x]" );
else if ( percent >= 10 )
sprintf ( meter, "[{R* {x]" );
else if ( percent >= 0 )
sprintf ( meter, "[{x {x]" );
sprintf ( buf, "You: %s\n\r", meter );
buf[0] = UPPER ( buf[0] );
send_to_char ( buf, ch );
/* write_to_buffer( d, buf, 0); */
}
ch = d->original ? d->original : d->character;
if ( !IS_SET ( ch->comm, COMM_COMPACT ) )
write_to_buffer ( d, "\n\r", 2 );
if ( IS_SET ( ch->comm, COMM_PROMPT ) )
bust_a_prompt ( d->character );
if ( IS_SET ( ch->comm, COMM_TELNET_GA ) )
write_to_buffer ( d, go_ahead_str, 0 );
}
}
/*
* Short-circuit if nothing to write.
*/
if ( d->outtop == 0 )
return TRUE;
/*
* Snoop-o-rama.
*/
if ( d->snoop_by != NULL )
{
if ( d->character != NULL )
write_to_buffer ( d->snoop_by, d->character->name, 0 );
write_to_buffer ( d->snoop_by, "> ", 2 );
write_to_buffer ( d->snoop_by, d->outbuf, d->outtop );
}
return process_ansi_output ( d );
}
/*
* Bust a prompt (player settable prompt)
* coded by Morgenes for Aldara Mud
* Completely overhauled for color by RW
*/
void bust_a_prompt ( CHAR_DATA * ch )
{
char buf[MAX_STRING_LENGTH * 100];
char buf2[MAX_STRING_LENGTH * 100];
char doors[MAX_INPUT_LENGTH];
EXIT_DATA *pexit;
bool found;
bool round;
const char *dir_name[] = { "N", "E", "S", "W", "U", "D" };
char *door_name[] = { "north", "east", "south", "west", "up", "down" };
int door, outlet;
sprintf ( buf2, "%s", ch->prompt );
if ( buf2 == NULL || buf2[0] == '\0' )
{
sprintf ( buf, "<%ldhp %ldm %ldmv> %s", ch->hit, ch->mana, ch->move,
ch->prefix );
send_to_char ( buf, ch );
return;
}
if ( IS_SET ( ch->comm, COMM_AFK ) )
{
printf_to_char ( ch, "{R<{WAFK{R>{x\n\r" );
return;
}
found = FALSE;
doors[0] = '\0';
if ( ch->position > POS_SLEEPING )
{
if ( IS_AFFECTED ( ch, AFF_BLIND ) &&
!IS_SET ( ch->act, PLR_HOLYLIGHT ) )
{
found = TRUE;
strcpy ( doors, "blinded" );
}
else
{
for ( door = 0; door < 6; door++ )
{
round = FALSE;
outlet = door;
if ( ( ch->alignment < 0 ) &&
( pexit = ch->in_room->exit[door + 6] ) != NULL )
outlet += 6;
if ( ( pexit = ch->in_room->exit[outlet] ) != NULL &&
pexit->u1.to_room != NULL &&
( can_see_room ( ch, pexit->u1.to_room ) ||
( IS_AFFECTED ( ch, AFF_INFRARED ) &&
!IS_AFFECTED ( ch, AFF_BLIND ) ) ) &&
!IS_SET ( pexit->exit_info, EX_CLOSED ) )
{
found = TRUE;
round = TRUE;
strcat ( doors, dir_name[door] );
}
if ( !round )
{
OBJ_DATA *portal;
portal =
get_obj_exit ( door_name[door],
ch->in_room->contents );
if ( ( portal != NULL ) &&
!IS_AFFECTED ( ch, AFF_BLIND ) )
{
found = TRUE;
round = TRUE;
strcat ( doors, dir_name[door] );
}
}
}
}
}
else
{
strcpy ( doors, "sleeping" );
found = TRUE;
}
if ( !found )
{
sprintf ( buf, "none" );
}
else
{
sprintf ( buf, "%s", doors );
} /*
if (ON_GQUEST(ch))
sprintf(buf2, "%d", gquest_info.timer);
else
sprintf(buf2, "%d\n\r", gquest_info.next);
i = buf2;
*/
str_replace_c ( buf2, "%e", buf );
str_replace_c ( buf2, "%c", "\n\r" );
sprintf ( buf, "%ld", ch->hit );
str_replace_c ( buf2, "%h", buf );
sprintf ( buf, "%ld", ch->max_hit );
str_replace_c ( buf2, "%H", buf );
sprintf ( buf, "%ld", ch->mana );
str_replace_c ( buf2, "%m", buf );
sprintf ( buf, "%ld", ch->max_mana );
str_replace_c ( buf2, "%M", buf );
sprintf ( buf, "%ld", ch->move );
str_replace_c ( buf2, "%v", buf );
sprintf ( buf, "%ld", ch->max_move );
str_replace_c ( buf2, "%V", buf );
sprintf ( buf, "%ld", ch->exp );
str_replace_c ( buf2, "%x", buf );
if ( !IS_NPC ( ch ) )
sprintf ( buf, "%ld",
( ch->level + 1 ) * exp_per_level ( ch,
ch->pcdata->points ) -
ch->exp );
else
sprintf ( buf, "none" );
str_replace_c ( buf2, "%X", buf );
sprintf ( buf, "%ld", ch->platinum );
str_replace_c ( buf2, "%p", buf );
sprintf ( buf, "%ld", ch->gold );
str_replace_c ( buf2, "%g", buf );
sprintf ( buf, "%ld", ch->silver );
str_replace_c ( buf2, "%s", buf );
if ( ch->level > 9 )
sprintf ( buf, "%d", ch->alignment );
else
sprintf ( buf, "%s",
IS_GOOD ( ch ) ? "good" : IS_EVIL ( ch ) ? "evil" :
"neutral" );
str_replace_c ( buf2, "%a", buf );
if ( ch->in_room != NULL )
sprintf ( buf, "%s",
( ( !IS_NPC ( ch ) && IS_SET ( ch->act, PLR_HOLYLIGHT ) ) ||
( !IS_AFFECTED ( ch, AFF_BLIND ) &&
!room_is_dark ( ch->in_room ) ) ) ? ch->in_room->
name : "darkness" );
else
sprintf ( buf, " " );
str_replace_c ( buf2, "%r", buf );
if ( IS_IMMORTAL ( ch ) ) // && ch->in_room != NULL) )
sprintf ( buf, "%ld", ch->in_room->vnum );
else
sprintf ( buf, " " );
str_replace_c ( buf2, "%o", buf );
if ( IS_IMMORTAL ( ch ) )
sprintf ( buf, "%s", olc_ed_name ( ch ) );
str_replace_c ( buf2, "%O", buf );
if ( IS_IMMORTAL ( ch ) )
sprintf ( buf, "%s", olc_ed_vnum ( ch ) );
str_replace_c ( buf2, "%R", buf );
if ( IS_IMMORTAL ( ch ) ) // && ch->in_room != NULL ))
sprintf ( buf, "%s", ch->in_room->area->name );
else
sprintf ( buf, " " );
str_replace_c ( buf2, "%z", buf );
send_to_char ( buf2, ch );
if ( ch->prefix[0] != '\0' )
write_to_buffer ( ch->desc, ch->prefix, 0 );
return;
}
/*
* Append onto an output buffer.
*/
void write_to_buffer ( DESCRIPTOR_DATA * d, const char *txt, int length )
{
/*
* Find length in case caller didn't.
*/
if ( length <= 0 )
length = strlen ( txt );
/*
* Initial \n\r if needed.
*/
if ( d->outtop == 0 && !d->fcommand )
{
d->outbuf[0] = '\n';
d->outbuf[1] = '\r';
d->outtop = 2;
}
/*
* Expand the buffer as needed.
*/
while ( d->outtop + length >= d->outsize )
{
char *outbuf;
if ( d->outsize >= 32000 )
{
bug ( "Buffer overflow. Closing.\n\r", 0 );
close_socket ( d );
return;
}
outbuf = alloc_mem ( 2 * d->outsize );
strncpy ( outbuf, d->outbuf, d->outtop );
free_mem ( d->outbuf, d->outsize );
d->outbuf = outbuf;
d->outsize *= 2;
}
/*
* Copy.
*/
strncpy ( d->outbuf + d->outtop, txt, length );
d->outtop += length;
return;
}
/*
* Lowest level output function.
* Write a block of text to the file descriptor.
* If this gives errors on very long blocks (like 'ofind all'),
* try lowering the max block size.
*/
bool write_to_descriptor ( int desc, char *txt, int length )
{
int iStart;
int nWrite;
int nBlock;
#if defined(macintosh) || defined(MSDOS)
if ( desc == 0 )
desc = 1;
#endif
if ( length <= 0 )
length = strlen ( txt );
for ( iStart = 0; iStart < length; iStart += nWrite )
{
nBlock = UMIN ( length - iStart, 2048 );
if ( ( nWrite = write ( desc, txt + iStart, nBlock ) ) < 0 )
{
perror ( "Write_to_descriptor" );
return FALSE;
}
}
return TRUE;
}
/*
* Deal with sockets that haven't logged in yet.
*/
void nanny ( DESCRIPTOR_DATA * d, char *argument )
{
DESCRIPTOR_DATA *d_old, *d_next;
char buf[MAX_STRING_LENGTH];
char newbuf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *ch;
CHAR_DATA *victim;
char *pwdnew;
char *p;
int iClass, race, i, weapon;
int pos = 0;
bool fOld;
while ( isspace ( *argument ) )
argument++;
ch = d->character;
switch ( d->connected )
{
default:
bug ( "Nanny: bad d->connected %d.", d->connected );
close_socket ( d );
return;
case CON_GET_NAME:
if ( argument[0] == '\0' )
{
close_socket ( d );
return;
}
argument[0] = UPPER ( argument[0] );
if ( !check_parse_name ( argument ) )
{
write_to_buffer ( d, "Illegal name, try another.\n\r", 0 );
write_to_buffer ( d,
"(If you've used this name here before, and are no\n\r",
0 );
write_to_buffer ( d,
" longer able to, it may be because we've added a\n\r",
0 );
write_to_buffer ( d,
" new mobile that uses the same name. Log in with\n\r",
0 );
write_to_buffer ( d,
" a new name, and let an IMM know, and we will fix it.)\n\r",
0 );
write_to_buffer ( d, "\n\rName: ", 0 );
return;
}
fOld = load_char_obj ( d, argument );
ch = d->character;
if ( IS_SET ( ch->act, PLR_DENY ) )
{
sprintf ( log_buf, "Denying access to %s@%s.", argument,
d->host );
log_string ( log_buf );
write_to_buffer ( d, "You are denied access.\n\r", 0 );
close_socket ( d );
return;
}
if ( check_ban ( d->host, BAN_PERMIT ) &&
!IS_SET ( ch->act, PLR_PERMIT ) )
{
write_to_buffer ( d,
"Your site has been banned from this mud.\n\r",
0 );
close_socket ( d );
return;
}
/*
if (check_adr(d->host,BAN_PERMIT) && (ch->level > 101) )
{
write_to_buffer(d,"Immortals are not allowed to connect from your site.\n\r",0);
close_socket(d);
return;
}
*/
if ( IS_SET ( ch->act2, PLR2_WIPED ) )
{
close_socket ( d );
return;
}
if ( check_reconnect ( d, argument, FALSE ) )
{
fOld = TRUE;
}
else
{
if ( wizlock && ( !IS_IMMORTAL ( ch ) ) )
{
write_to_buffer ( d,
"The game is currently wizlocked.\n\r",
0 );
if ( !IS_IMMORTAL ( ch ) )
{
close_socket ( d );
return;
}
}
}
if ( fOld )
{
if ( newlock && IS_IMMORTAL ( ch ) )
write_to_buffer ( d,
"The game is currently newlocked.\n\r",
0 );
/* Old player */
write_to_buffer ( d, "{D---{W===Password{W==={D---{x: ", 0 );
write_to_buffer ( d, echo_off_str, 0 );
d->connected = CON_GET_OLD_PASSWORD;
return;
}
else
{
/* New player */
if ( newlock )
{
write_to_buffer ( d, "The game is newlocked.\n\r", 0 );
close_socket ( d );
return;
}
if ( check_ban ( d->host, BAN_NEWBIES ) )
{
write_to_buffer ( d,
"New players are not allowed from your site.\n\r",
0 );
close_socket ( d );
return;
}
sprintf ( buf, "Did I get that right, %s (Y/N)? ", argument );
write_to_buffer ( d, buf, 0 );
d->connected = CON_CONFIRM_NEW_NAME;
return;
}
break;
case CON_GET_OLD_PASSWORD:
#if defined(unix)
write_to_buffer ( d, "\n\r", 2 );
#endif
if ( str_cmp
( crypt ( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
{
write_to_buffer ( d, "Wrong password.\n\r", 0 );
close_socket ( d );
return;
}
write_to_buffer ( d, echo_on_str, 0 );
if ( check_playing ( d, ch->name ) )
return;
free_string ( ch->pcdata->socket );
ch->pcdata->socket = str_dup ( d->host );
if ( check_reconnect ( d, ch->name, TRUE ) )
return;
sprintf ( log_buf, "%s@%s has connected.", ch->name, d->host );
log_string ( log_buf );
wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, get_trust ( ch ) );
free_string ( ch->pcdata->socket );
ch->pcdata->socket = str_dup ( d->host );
/* if (IS_SET(ch->act, PLR_REROLL ) )
{
sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name ) );
sprintf(newbuf, "%s", str_dup( ch->pcdata->pwd ));
sprintf( argument, "%s", capitalize( ch->name ) );
free_char( d->character );
d->character = NULL;
ch = d->character;
free_string( ch->pcdata->pwd );
ch->pcdata->pwd = str_dup( newbuf );
newbuf[0] = '\0';
ch->pcdata->tier = 1;
free_string( ch->pcdata->socket );
ch->pcdata->socket = str_dup( d->host );
write_to_buffer( d, echo_on_str, 0 );
write_to_buffer(d, "The following races are available:\n\r\n\r",0);
pos = 0;
for ( race = 1; race_table[race].name != NULL; race++ )
{
if (!race_table[race].pc_race || !IS_SET(ch->pcdata->ctier, pc_race_table[race].tier))
continue;
sprintf(newbuf, "{g%6s{g%-24s{x", " ", race_table[race].name);
write_to_buffer(d,newbuf,0);
pos++;
if (pos >= 2)
{
write_to_buffer(d,"\n\r",1);
pos = 0;
}
}
newbuf[0] = '\0';
write_to_buffer(d,"\n\r\n\r",0);
write_to_buffer(d, "What is your race (help for more information)? ",0);
d->connected = CON_GET_NEW_RACE;
break;
}
OLD REROLL DUDE! */
/*if ( IS_IMMORTAL(ch) )
{
do_help( ch, "imotd" );
d->connected = CON_READ_IMOTD;
} */
if ( IS_IMMORTAL ( ch ) )
{
write_to_buffer ( d,
"{cWould you like to login {W({BW{W){cizinvis, {W({BI{W){cncognito, or {W({BN{W){cormal?{x",
0 );
d->connected = CON_WIZ;
}
else
{
do_help ( ch, "motd" );
d->connected = CON_READ_MOTD;
}
for ( pos = 0; pos < MAX_DUPES; pos++ )
{
if ( ch->pcdata->dupes[pos] == NULL )
break;
if ( ( victim =
get_char_mortal ( ch,
ch->pcdata->dupes[pos] ) ) != NULL )
force_quit ( victim, "" );
}
break;
case CON_WIZ:
write_to_buffer ( d, "\n\r", 2 );
switch ( *argument )
{
case 'w':
case 'W':
( ch->invis_level = ch->level );
do_help ( ch, "imotd" );
d->connected = CON_READ_IMOTD;
break;
case 'i':
case 'I':
( ch->incog_level = ch->level );
do_help ( ch, "imotd" );
d->connected = CON_READ_IMOTD;
break;
case 'n':
case 'N':
( ch->incog_level = 0 );
( ch->invis_level = 0 );
do_help ( ch, "imotd" );
d->connected = CON_READ_IMOTD;
break;
default:
write_to_buffer ( d,
"{WI{wnvalid {Ychoice{w, entering in {cnormal{w mode.{x\n\r\n\r",
0 );
do_help ( ch, "imotd" );
d->connected = CON_READ_IMOTD;
break;
}
break;
/* RT code for breaking link */
case CON_BREAK_CONNECT:
switch ( *argument )
{
case 'y':
case 'Y':
for ( d_old = descriptor_list; d_old != NULL;
d_old = d_next )
{
d_next = d_old->next;
if ( d_old == d || d_old->character == NULL )
continue;
if ( str_cmp
( ch->name,
d_old->original ? d_old->original->
name : d_old->character->name ) )
continue;
close_socket ( d_old );
}
free_string ( ch->pcdata->socket );
ch->pcdata->socket = str_dup ( d->host );
if ( check_reconnect ( d, ch->name, TRUE ) )
return;
write_to_buffer ( d,
"Reconnect attempt failed.\n\rName: ",
0 );
if ( d->character != NULL )
{
free_char ( d->character );
d->character = NULL;
}
d->connected = CON_GET_NAME;
break;
case 'n':
case 'N':
write_to_buffer ( d, "Name: ", 0 );
if ( d->character != NULL )
{
free_char ( d->character );
d->character = NULL;
}
d->connected = CON_GET_NAME;
break;
default:
write_to_buffer ( d, "Please type Y or N? ", 0 );
break;
}
break;
case CON_CONFIRM_NEW_NAME:
switch ( *argument )
{
case 'y':
case 'Y':
sprintf ( buf,
"New character.\n\rGive me a password for %s: %s",
ch->name, echo_off_str );
free_string ( ch->pcdata->socket );
ch->pcdata->socket = str_dup ( d->host );
write_to_buffer ( d, buf, 0 );
d->connected = CON_GET_NEW_PASSWORD;
break;
case 'n':
case 'N':
write_to_buffer ( d, "Ok, what IS it, then? ", 0 );
free_char ( d->character );
d->character = NULL;
d->connected = CON_GET_NAME;
break;
default:
write_to_buffer ( d, "Please type Yes or No? ", 0 );
break;
}
break;
case CON_BEGIN_REROLL:
write_to_buffer ( d,
"{RNow beginning the rerolling process.{x\n\r\n\r",
0 );
write_to_buffer ( d,
"{RThe following races are available:{x\n\r ",
0 );
write_to_buffer ( d,
"{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{DDeath Rising {gRaces{r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R=\n\r{x",
0 );
pos = 0;
for ( race = 1; race_table[race].name != NULL; race++ )
{
if ( !race_table[race].pc_race ||
!IS_SET ( ch->pcdata->ctier, pc_race_table[race].tier ) )
continue;
sprintf ( newbuf, "{g%6s{g%-24s{x", " ",
race_table[race].name );
write_to_buffer ( d, newbuf, 0 );
pos++;
if ( pos >= 2 )
{
write_to_buffer ( d, "\n\r", 1 );
pos = 0;
}
}
write_to_buffer ( d, "\n\r", 0 );
write_to_buffer ( d,
"What is your race (help for more information)? ",
0 );
d->connected = CON_GET_NEW_RACE;
break;
case CON_GET_NEW_PASSWORD:
#if defined(unix)
write_to_buffer ( d, "\n\r", 2 );
#endif
if ( strlen ( argument ) < 5 )
{
write_to_buffer ( d,
"Password must be at least five characters long.\n\rPassword: ",
0 );
return;
}
pwdnew = crypt ( argument, ch->name );
for ( p = pwdnew; *p != '\0'; p++ )
{
if ( *p == '~' )
{
write_to_buffer ( d,
"New password not acceptable, try again.\n\rPassword: ",
0 );
return;
}
}
free_string ( ch->pcdata->pwd );
ch->pcdata->pwd = str_dup ( pwdnew );
write_to_buffer ( d, "Please retype password: ", 0 );
d->connected = CON_CONFIRM_NEW_PASSWORD;
break;
case CON_CONFIRM_NEW_PASSWORD:
#if defined(unix)
write_to_buffer ( d, "\n\r", 2 );
#endif
if ( str_cmp
( crypt ( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
{
write_to_buffer ( d,
"Passwords don't match.\n\rRetype password: ",
0 );
d->connected = CON_GET_NEW_PASSWORD;
return;
}
free_string ( ch->pcdata->socket );
ch->pcdata->socket = str_dup ( d->host );
write_to_buffer ( d, echo_on_str, 0 );
write_to_buffer ( d,
"{gWould you like to turn {Yoff{g ANSI Colour now? ({WY{g/{RN{g){x",
0 );
d->connected = CON_GET_ANSI;
break;
case CON_GET_ANSI:
switch ( argument[0] )
{
case 'y':
case 'Y':
d->ansi = FALSE;
SET_BIT ( ch->act, PLR_NOCOLOUR );
break;
case 'n':
case 'N':
break;
default:
write_to_buffer ( d,
"{WPlease answer {YYes{W or {RNo{W.{x\n\r",
0 );
return;
}
write_to_buffer ( d,
"{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{DDeath Rising {gRaces{r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R=\n\r{x",
0 );
pos = 0;
for ( race = 1; race_table[race].name != NULL; race++ )
{
if ( !race_table[race].pc_race ||
!IS_SET ( ch->pcdata->ctier, pc_race_table[race].tier ) )
continue;
sprintf ( newbuf, "{g%6s{g%-24s{x", " ",
race_table[race].name );
write_to_buffer ( d, newbuf, 0 );
pos++;
if ( pos >= 2 )
{
write_to_buffer ( d, "\n\r", 1 );
pos = 0;
}
}
newbuf[0] = '\0';
write_to_buffer ( d, "\n\r\n\r", 0 );
write_to_buffer ( d,
"{WWhat is your race (help for more information)?{x ",
0 );
d->connected = CON_GET_NEW_RACE;
break;
case CON_GET_NEW_RACE:
one_argument ( argument, arg );
if ( !str_cmp ( arg, "help" ) )
{
argument = one_argument ( argument, arg );
if ( argument[0] == '\0' )
do_help ( ch, "race help" );
else
do_help ( ch, argument );
write_to_buffer ( d,
"{WWhat is your race (help for more information)?{x ",
0 );
break;
}
race = race_lookup ( argument );
if ( race == 0 || !race_table[race].pc_race ||
!IS_SET ( ch->pcdata->ctier, pc_race_table[race].tier ) )
{
write_to_buffer ( d, "{RThat is not a valid race.{x\n\r", 0 );
write_to_buffer ( d,
"{RThe following races are available:\n\r{x ",
0 );
write_to_buffer ( d,
"{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{DDeath Rising {gRaces{r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R={r-{R=\n\r{x",
0 );
for ( race = 1; race_table[race].name != NULL; race++ )
{
if ( !race_table[race].pc_race ||
!IS_SET ( ch->pcdata->ctier,
pc_race_table[race].tier ) )
continue;
sprintf ( newbuf, "{g%6s{g%-24s{x", " ",
race_table[race].name );
write_to_buffer ( d, newbuf, 0 );
pos++;
if ( pos >= 2 )
{
write_to_buffer ( d, "\n\r", 2 );
pos = 0;
}
}
write_to_buffer ( d, "\n\r", 0 );
write_to_buffer ( d,
"{WWhat is your race? (help for more information){x ",
0 );
break;
}
ch->race = race;
/* initialize stats */
for ( i = 0; i < MAX_STATS; i++ )
ch->perm_stat[i] = pc_race_table[race].stats[i];
ch->act = ch->act | race_table[race].act;
ch->act2 = ch->act2 | race_table[race].act2;
ch->affected_by = ch->affected_by | race_table[race].aff;
ch->shielded_by = ch->shielded_by | race_table[race].shd;
ch->imm_flags = ch->imm_flags | race_table[race].imm;
ch->res_flags = ch->res_flags | race_table[race].res;
ch->vuln_flags = ch->vuln_flags | race_table[race].vuln;
ch->form = race_table[race].form;
ch->parts = race_table[race].parts;
/* add skills */
for ( i = 0; i < 5; i++ )
{
if ( pc_race_table[race].skills[i] == NULL )
break;
group_add ( ch, pc_race_table[race].skills[i], FALSE );
}
/* add cost */
ch->pcdata->points = pc_race_table[race].points;
ch->size = pc_race_table[race].size;
write_to_buffer ( d,
"{WThe following classes are available:{x\n\r\n\r",
0 );
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
{
if ( !IS_SET ( ch->pcdata->ctier, class_table[iClass].tier ) )
continue;
sprintf ( buf, " {%c%s{x\n\r",
IS_SET ( class_table[iClass].tier,
ch->pcdata->ctier ) ? 'R' : 'B',
class_table[iClass].name );
write_to_buffer ( d, buf, 0 );
}
write_to_buffer ( d, "\n\r\n\r", 0 );
/*
write_to_buffer(d, "{WWhat is your sex {w({BM{x/{MF{x/{RN{w){W?{x ", 0 );
d->connected = CON_GET_NEW_SEX;*/
write_to_buffer ( d, "{WWhat is your class ? {x", 0 );
d->connected = CON_GET_NEW_CLASS;
break;
case CON_GET_NEW_SEX:
switch ( argument[0] )
{
case 'm':
case 'M':
ch->sex = SEX_MALE;
ch->pcdata->true_sex = SEX_MALE;
break;
case 'f':
case 'F':
ch->sex = SEX_FEMALE;
ch->pcdata->true_sex = SEX_FEMALE;
break;
case 'n':
case 'N':
ch->sex = SEX_NEUTRAL;
ch->pcdata->true_sex = SEX_NEUTRAL;
break;
default:
write_to_buffer ( d,
"{WThat's not a sex.\n\rWhat IS your sex? {x",
0 );
return;
}
write_to_buffer ( d, echo_on_str, 0 ); /*
write_to_buffer(d, "{WThe following classes are available:{x\n\r\n\r",0);
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
{
if ( !IS_SET(ch->pcdata->ctier, class_table[iClass].tier) )
continue;
sprintf(buf, " {%c%s{x\n\r", IS_SET(class_table[iClass].tier, ch->pcdata->ctier) ? 'R' : 'B',
class_table[iClass].name);
write_to_buffer(d,buf,0);
}
write_to_buffer(d,"\n\r\n\r",0);
write_to_buffer(d, "{WWhat is your class ? {x",0);
d->connected = CON_GET_NEW_CLASS; */
write_to_buffer ( d,
"\n\r{WYou may be {Bgood{W, {Gneutral{W, or {Devil{W.{x\n\r",
0 );
write_to_buffer ( d,
"{WWhich alignment {w({BG{w/{GN{w/{DE{x){W?{x ",
0 );
d->connected = CON_GET_ALIGNMENT;
break;
case CON_GET_NEW_CLASS:
iClass = class_lookup ( argument );
if ( iClass == -1 )
{
write_to_buffer ( d,
"That's not a class.\n\rWhat IS your class? ",
0 );
return;
}
if ( !IS_SET ( ch->pcdata->ctier, class_table[iClass].tier ) )
{
write_to_buffer ( d,
"That class is not allowed to your tier.\n\rWhat IS your class? ",
0 );
return;
}
ch->class = iClass;
sprintf ( log_buf, "%s@%s new player.", ch->name, d->host );
log_string ( log_buf );
wiznet ( "Newbie alert! $N sighted.", ch, NULL, WIZ_NEWBIE, 0,
0 );
wiznet ( log_buf, NULL, NULL, WIZ_SITES, 0, get_trust ( ch ) );
write_to_buffer ( d, "\n\r", 2 ); /*
write_to_buffer(d, "{WYou may be {Bgood{W, {Gneutral{W, or {Devil{W.{x\n\r",0);
write_to_buffer(d, "{WWhich alignment {w({BG{w/{GN{w/{DE{x){W?{x ",0);
d->connected = CON_GET_ALIGNMENT; */
write_to_buffer ( d,
"{WWhat is your sex {w({BM{x/{MF{x/{RN{w){W?{x ",
0 );
d->connected = CON_GET_NEW_SEX;
break;
case CON_GET_ALIGNMENT:
switch ( argument[0] )
{
case 'g':
case 'G':
ch->alignment = 1000;
break;
case 'n':
case 'N':
ch->alignment = 0;
break;
case 'e':
case 'E':
ch->alignment = -1000;
break;
default:
write_to_buffer ( d, "That's not a valid alignment.\n\r",
0 );
write_to_buffer ( d, "Which alignment (G/N/E)? ", 0 );
return;
}
write_to_buffer ( d, "\n\r", 0 );
group_add ( ch, "rom basics", FALSE );
group_add ( ch, class_table[ch->class].base_group, FALSE );
ch->pcdata->learned[gsn_recall] = 50;
write_to_buffer ( d,
"{WDo you wish to customize this character?{x\n\r",
0 );
write_to_buffer ( d,
"{WHere at {RD{reath {RR{rising{W we advise only veteran mudders to customize.{x\n\r",
0 );
write_to_buffer ( d, "{WCustomize {w({YY{w/{RN{w){W?{x ", 0 );
d->connected = CON_DEFAULT_CHOICE;
break;
case CON_DEFAULT_CHOICE:
write_to_buffer ( d, "\n\r", 2 );
switch ( argument[0] )
{
case 'y':
case 'Y':
ch->gen_data = new_gen_data ( );
ch->gen_data->points_chosen = ch->pcdata->points;
do_help ( ch, "group header" );
list_group_costs ( ch );
write_to_buffer ( d,
"{WYou already have the following skills:{x\n\r",
0 );
do_skills ( ch, "{g" );
do_help ( ch, "menu choice" );
d->connected = CON_GEN_GROUPS;
break;
case 'n':
case 'N':
group_add ( ch, class_table[ch->class].default_group,
TRUE );
write_to_buffer ( d, "\n\r", 2 );
write_to_buffer ( d,
"{WPlease pick a weapon from the following choices:\n\r",
0 );
buf[0] = '\0';
for ( i = 0; weapon_table[i].name != NULL; i++ )
if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
{
strcat ( buf, weapon_table[i].name );
strcat ( buf, " " );
}
strcat ( buf, "\n\r{WYour choice? {x" );
write_to_buffer ( d, buf, 0 );
d->connected = CON_PICK_WEAPON;
break;
default:
write_to_buffer ( d,
"{WPlease answer {w({YY{w/{RN{w){W?{x ",
0 );
return;
}
break;
case CON_PICK_WEAPON:
write_to_buffer ( d, "{W \n\r", 2 );
weapon = weapon_lookup ( argument );
if ( weapon == -1 ||
ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0 )
{
write_to_buffer ( d,
"That's not a valid selection. Choices are:\n\r",
0 );
buf[0] = '\0';
for ( i = 0; weapon_table[i].name != NULL; i++ )
if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
{
strcat ( buf, weapon_table[i].name );
strcat ( buf, " " );
}
strcat ( buf, "\n\r{WYour choice?{x " );
write_to_buffer ( d, buf, 0 );
return;
}
ch->pcdata->learned[*weapon_table[weapon].gsn] = 40;
write_to_buffer ( d, "\n\r", 2 );
do_help ( ch, "motd" );
d->connected = CON_READ_MOTD;
break;
case CON_GEN_GROUPS:
send_to_char ( "\n\r", ch );
if ( !str_cmp ( argument, "done" ) )
{
sprintf ( buf, "{WCreation points: {b%d{x\n\r",
ch->pcdata->points );
send_to_char ( buf, ch );
sprintf ( buf, "{WExperience per level: {Y%ld{x\n\r",
( long ) exp_per_level ( ch,
ch->gen_data->
points_chosen ) );
if ( ch->pcdata->points < 40 )
ch->train = ( 40 - ch->pcdata->points + 1 ) / 2;
free_gen_data ( ch->gen_data );
ch->gen_data = NULL;
send_to_char ( buf, ch );
write_to_buffer ( d, " \n\r", 2 );
write_to_buffer ( d,
"{WPlease pick a weapon from the following choices:{x\n\r",
0 );
buf[0] = '\0';
for ( i = 0; weapon_table[i].name != NULL; i++ )
if ( ch->pcdata->learned[*weapon_table[i].gsn] > 0 )
{
strcat ( buf, weapon_table[i].name );
strcat ( buf, " " );
}
strcat ( buf, "\n\r{WYour choice?{x " );
write_to_buffer ( d, buf, 0 );
d->connected = CON_PICK_WEAPON;
break;
}
if ( !parse_gen_groups ( ch, argument ) )
send_to_char
( "{WChoices are: list,learned,premise,add,drop,info,help, and done.{x\n\r",
ch );
do_help ( ch, "menu choice" );
break;
case CON_READ_IMOTD:
write_to_buffer ( d, "\n\r", 2 );
do_help ( ch, "motd" );
d->connected = CON_READ_MOTD;
break;
case CON_READ_MOTD:
if ( IS_QUESTOR ( ch ) )
{
do_quest ( ch, "info" );
if ( ch->pcdata->questobj > 0 )
{
OBJ_INDEX_DATA *pObj = NULL;
OBJ_DATA *obj = NULL;
ROOM_INDEX_DATA *pRoom = NULL;
if ( ( pObj =
get_obj_index ( ch->pcdata->questobj ) ) == NULL )
end_quest ( ch, 0 );
else
obj = create_object ( pObj, ch->level );
if ( ( pRoom =
get_room_index ( ch->pcdata->questloc ) ) == NULL )
pRoom = get_random_room ( ch );
obj_to_room ( obj, pRoom );
}
}
if ( ch->pcdata == NULL || ch->pcdata->pwd[0] == '\0' )
{
write_to_buffer ( d, "Warning! Null password!\n\r", 0 );
write_to_buffer ( d,
"Please report old password with bug.\n\r",
0 );
write_to_buffer ( d,
"Type 'password null <new password>' to fix.\n\r",
0 );
}
write_to_buffer ( d,
"\n\rWelcome to Death Rising. Please do not feed the immortals.\n\r",
0 );
ch->next = char_list;
char_list = ch;
d->connected = CON_PLAYING;
reset_char ( ch );
sprintf ( buf,
"\n\r{WYou are currently logged on as: {x {W Name: {c%s{x {WIP/Host: {c%s{x\n\r\n\r\n\r",
ch->name, d->host );
send_to_char ( buf, ch );
if ( ch->level == 0 )
{
ch->perm_stat[class_table[ch->class].attr_prime] += 4;
/* add this while initializing all the racial stuff for new characters */
ch->level = 1;
ch->exp = exp_per_level ( ch, ch->pcdata->points );
ch->hit = ch->max_hit;
ch->mana = ch->max_mana;
ch->move = ch->max_move;
ch->train = 15;
ch->practice = 35;
ch->pcdata->plr_wager = 0; /* arena betting amount */
ch->pcdata->awins = 0; /* arena wins */
ch->pcdata->alosses = 0; /* arena losses */
sprintf ( buf, "the %s",
title_table[ch->class][ch->level][ch->sex ==
SEX_FEMALE ? 1 :
0] );
set_title ( ch, buf );
do_pack ( ch, "self" );
do_autoall ( ch, "self" );
do_prompt ( ch, "all" );
obj_to_char ( create_object
( get_obj_index ( OBJ_VNUM_MAP ), 0 ), ch );
obj_to_char ( create_object
( get_obj_index ( OBJ_VNUM_WMAP ), 0 ), ch );
obj_to_char ( create_object
( get_obj_index ( OBJ_VNUM_EMAP ), 0 ), ch );
char_to_room ( ch, get_room_index ( ROOM_VNUM_SCHOOL ) );
send_to_char ( "\n\r", ch );
/* do_help(ch,"NEWBIE INFO");*/
printf_to_char ( ch,
"{RIf{Y you are {Rnew{Y here we suggest reading help newbie{x\n\r" );
send_to_char ( "\n\r", ch );
}
else if ( ch->in_room != NULL )
{
char_to_room ( ch, ch->in_room );
}
else if ( IS_IMMORTAL ( ch ) )
{
char_to_room ( ch, get_room_index ( ROOM_VNUM_CHAT ) );
}
else
{
if ( ch->alignment < 0 )
char_to_room ( ch, get_room_index ( ROOM_VNUM_TEMPLEB ) );
else
char_to_room ( ch, get_room_index ( ROOM_VNUM_TEMPLE ) );
}
do_look ( ch, "auto" );
if ( IS_IMMORTAL ( ch ) )
{
do_announce ( ch, "is now watching over you..\n\r" );
wiznet ( "$N has entered Death Rising.", ch, NULL, WIZ_LOGINS,
WIZ_SITES, get_trust ( ch ) );
}
else
{
do_announce ( ch, "has entered Death Rising." );
wiznet ( "$N has entered Death Rising.", ch, NULL, WIZ_LOGINS,
WIZ_SITES, get_trust ( ch ) );
}
if ( ch->pet != NULL )
{
char_to_room ( ch->pet, ch->in_room );
act ( "$n has entered Death Rising.", ch->pet, NULL, NULL,
TO_ROOM );
}
do_unread ( ch, "" );
break;
}
return;
}
/*
* Parse a name for acceptability.
*/
bool check_parse_name ( char *name )
{
int e;
/*
* Reserved words.
*/
if ( is_name
( name,
"all auto immortal immortals self someone something the"
"you demise balance circle loner honor Loki unlinked {" ) )
return FALSE;
if ( str_cmp ( capitalize ( name ), "Alander" ) &&
( !str_prefix ( "Alan", name ) || !str_suffix ( "Alander", name ) ) )
return FALSE;
/*
* Cursing
*/
for ( e = 1; e < MAX_CLAN; e++ )
{
if ( !str_prefix ( clan_table[e].name, name ) )
return FALSE;
}
if ( !str_infix ( "immortal", name ) )
return FALSE;
if ( !str_infix ( " ", name ) )
return FALSE;
if ( !str_infix ( "fuck", name ) )
return FALSE;
if ( !str_infix ( "shit", name ) )
return FALSE;
if ( !str_infix ( "asshole", name ) )
return FALSE;
if ( !str_infix ( "pussy", name ) )
return FALSE;
/*
* Length restrictions.
*/
if ( strlen ( name ) < 3 )
return FALSE;
#if defined(MSDOS)
if ( strlen ( name ) > 8 )
return FALSE;
#endif
#if defined(macintosh) || defined(unix)
if ( strlen ( name ) > 12 )
return FALSE;
#endif
/*
* Alphanumerics only.
* Lock out IllIll twits.
*/
{
char *pc;
bool fIll, adjcaps = FALSE, cleancaps = FALSE;
int total_caps = 0;
fIll = TRUE;
for ( pc = name; *pc != '\0'; pc++ )
{
if ( !isalpha ( *pc ) )
return FALSE;
if ( isupper ( *pc ) ) /* ugly anti-caps hack */
{
if ( adjcaps )
cleancaps = TRUE;
total_caps++;
adjcaps = TRUE;
}
else
adjcaps = FALSE;
if ( LOWER ( *pc ) != 'i' && LOWER ( *pc ) != 'l' )
fIll = FALSE;
}
if ( fIll )
return FALSE;
if ( cleancaps ||
( total_caps > ( strlen ( name ) ) / 2 && strlen ( name ) < 3 ) )
return FALSE;
}
/*
* Prevent players from naming themselves after mobs.
*/
{
MOB_INDEX_DATA *pMobIndex;
int iHash;
for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
{
for ( pMobIndex = mob_index_hash[iHash]; pMobIndex != NULL;
pMobIndex = pMobIndex->next )
{
if ( is_name ( name, pMobIndex->player_name ) )
return FALSE;
}
}
}
/*
* Check names of people already playing, yes this is necessary for multiple newbies
* with the same name (thanks Saro).
*/
if ( descriptor_list )
{
int count = 0;
DESCRIPTOR_DATA *d, *dnext;
for ( d = descriptor_list; d != NULL; d = dnext )
{
dnext = d->next;
if ( d->connected != CON_PLAYING && d->character &&
d->character->name && d->character->name[0] &&
!str_cmp ( d->character->name, name ) )
{
count++;
close_socket ( d );
}
}
if ( count )
{
sprintf ( log_buf, "Double Newbie alert (%s)", name );
wiznet ( log_buf, NULL, NULL, WIZ_LOGINS, 0, 0 );
return FALSE;
}
}
return TRUE;
}
/*
* Look for link-dead player to reconnect.
*/
bool check_reconnect ( DESCRIPTOR_DATA * d, char *name, bool fConn )
{
CHAR_DATA *ch;
char buf[MAX_STRING_LENGTH];
for ( ch = char_list; ch != NULL; ch = ch->next )
{
if ( !IS_NPC ( ch ) && ( !fConn || ch->desc == NULL ) &&
!str_cmp ( d->character->name, ch->name ) )
{
if ( fConn == FALSE )
{
free_string ( d->character->pcdata->pwd );
d->character->pcdata->pwd = str_dup ( ch->pcdata->pwd );
}
else
{
OBJ_DATA *obj;
free_char ( d->character );
d->character = ch;
ch->desc = d;
ch->timer = 0;
if ( ch->tells )
{
sprintf ( buf,
"Reconnecting. You have {R%d{x tells waiting.\n\r",
ch->tells );
send_to_char ( buf, ch );
send_to_char ( "Type 'replay' to see tells.\n\r", ch );
}
else
{
send_to_char
( "Reconnecting. You have no tells waiting.\n\r",
ch );
}
act ( "$n has reconnected.", ch, NULL, NULL, TO_ROOM );
if ( ( obj = get_eq_char ( ch, WEAR_LIGHT ) ) != NULL &&
obj->item_type == ITEM_LIGHT && obj->value[2] != 0 )
--ch->in_room->light;
sprintf ( log_buf, "%s@%s reconnected.", ch->name, d->host );
log_string ( log_buf );
wiznet ( "$N groks the fullness of $S link.", ch, NULL,
WIZ_LINKS, 0, 0 );
d->connected = CON_PLAYING;
}
return TRUE;
}
}
return FALSE;
}
/*
* Check if already playing.
*/
bool check_playing ( DESCRIPTOR_DATA * d, char *name )
{
DESCRIPTOR_DATA *dold;
for ( dold = descriptor_list; dold; dold = dold->next )
{
if ( dold != d && dold->character != NULL &&
dold->connected != CON_GET_NAME &&
dold->connected != CON_GET_OLD_PASSWORD &&
!str_cmp ( name,
dold->original ? dold->original->name : dold->
character->name ) )
{
write_to_buffer ( d, "That character is already playing.\n\r",
0 );
write_to_buffer ( d, "Do you wish to connect anyway (Y/N)?", 0 );
d->connected = CON_BREAK_CONNECT;
return TRUE;
}
}
return FALSE;
}
void stop_idling ( CHAR_DATA * ch )
{
if ( ch == NULL || ch->desc == NULL || ch->desc->connected != CON_PLAYING
|| ch->was_in_room == NULL ||
ch->in_room != get_room_index ( ROOM_VNUM_LIMBO ) )
return;
ch->timer = 0;
char_from_room ( ch );
char_to_room ( ch, ch->was_in_room );
ch->was_in_room = NULL;
act ( "$n has returned from the void.", ch, NULL, NULL, TO_ROOM );
return;
}
void send_to_char ( const char *txt, CHAR_DATA * ch )
{
if ( txt != NULL && ch != NULL && ch->desc != NULL )
write_to_buffer ( ch->desc, txt, strlen ( txt ) );
return;
}
/*
* Send a page to one char.
*/
void page_to_char ( const char *txt, CHAR_DATA * ch )
{
if ( txt == NULL || ch == NULL || ch->desc == NULL )
return;
if ( ch->lines == 0 )
{
send_to_char ( txt, ch );
return;
}
#if defined(macintosh)
send_to_char ( txt, ch );
#else
ch->desc->showstr_head = alloc_mem ( strlen ( txt ) + 1 );
strcpy ( ch->desc->showstr_head, txt );
ch->desc->showstr_point = ch->desc->showstr_head;
show_string ( ch->desc, "" );
#endif
}
/* string pager */
void show_string ( struct descriptor_data *d, char *input )
{
char buffer[4 * MAX_STRING_LENGTH];
char buf[MAX_INPUT_LENGTH];
register char *scan, *chk;
int lines = 0, toggle = 1;
int show_lines;
one_argument ( input, buf );
if ( buf[0] != '\0' )
{
if ( d->showstr_head )
{
free_string ( d->showstr_head );
d->showstr_head = 0;
}
d->showstr_point = 0;
return;
}
if ( d->character )
show_lines = d->character->lines;
else
show_lines = 0;
for ( scan = buffer;; scan++, d->showstr_point++ )
{
if ( ( ( *scan = *d->showstr_point ) == '\n' || *scan == '\r' ) &&
( toggle = -toggle ) < 0 )
lines++;
else if ( !*scan || ( show_lines > 0 && lines >= show_lines ) )
{
*scan = '\0';
write_to_buffer ( d, buffer, strlen ( buffer ) );
for ( chk = d->showstr_point; isspace ( *chk ); chk++ );
{
if ( !*chk )
{
if ( d->showstr_head )
{
free_string ( d->showstr_head );
d->showstr_head = 0;
}
d->showstr_point = 0;
}
}
return;
}
}
return;
}
/* quick sex fixer */
void fix_sex ( CHAR_DATA * ch )
{
if ( ch->sex < 0 || ch->sex > 2 )
ch->sex = IS_NPC ( ch ) ? 0 : ch->pcdata->true_sex;
}
/*
* Extended act with optional suppression - Gregor Stipicic, 2001
*/
void xact_new ( const char *format, CHAR_DATA * ch, const void *arg1,
const void *arg2, int type, int min_pos, int verbose )
{
static char *const he_she[] = {
"it", "he", "she"
};
static char *const him_her[] = {
"it", "him", "her"
};
static char *const his_her[] = {
"its", "his", "her"
};
CHAR_DATA *to;
CHAR_DATA *vch = ( CHAR_DATA * ) arg2;
OBJ_DATA *obj1 = ( OBJ_DATA * ) arg1;
OBJ_DATA *obj2 = ( OBJ_DATA * ) arg2;
const char *str;
char *i;
char *point;
char buf[MAX_STRING_LENGTH];
char fname[MAX_INPUT_LENGTH];
int collen = -1;
if ( !format || !*format )
return;
if ( !ch || !ch->in_room )
return;
to = ch->in_room->people;
if ( type == TO_VICT )
{
if ( !vch )
{
bug ( "Act: null vch with TO_VICT.", 0 );
return;
}
if ( !vch->in_room )
return;
to = vch->in_room->people;
}
for ( ; to; to = to->next_in_room )
{
if ( ( !IS_NPC ( to ) && to->desc == NULL ) ||
( IS_NPC ( to ) && !HAS_TRIGGER ( to, TRIG_ACT ) ) ||
to->position < min_pos )
continue;
if ( type == TO_CHAR && to != ch )
continue;
if ( type == TO_VICT && ( to != vch || to == ch ) )
continue;
if ( type == TO_ROOM && to == ch )
continue;
if ( type == TO_NOTVICT && ( to == ch || to == vch ) )
continue;
point = buf;
str = format;
while ( *str )
{
if ( *str != '$' )
{
*point++ = *str++;
continue;
}
i = NULL;
switch ( *str )
{
case '$':
++str;
i = " <@@@> ";
if ( !arg2 && *str >= 'A' && *str <= 'Z' && *str != 'G' )
{
bug ( "Act: missing arg2 for code %d.", *str );
i = " <@@@> ";
}
else
{
switch ( *str )
{
default:
bug ( "Act: bad code %d.", *str );
i = " <@@@> ";
break;
case 't':
i = ( char * ) arg1;
break;
case 'T':
i = ( char * ) arg2;
break;
case 'n':
i = PERS ( ch, to );
break;
case 'N':
i = PERS ( vch, to );
break;
case 'e':
i = he_she[URANGE ( 0, ch->sex, 2 )];
break;
case 'E':
i = he_she[URANGE ( 0, vch->sex, 2 )];
break;
case 'm':
i = him_her[URANGE ( 0, ch->sex, 2 )];
break;
case 'M':
i = him_her[URANGE ( 0, vch->sex, 2 )];
break;
case 's':
i = his_her[URANGE ( 0, ch->sex, 2 )];
break;
case 'S':
i = his_her[URANGE ( 0, vch->sex, 2 )];
break;
case 'p':
i = can_see_obj ( to,
obj1 ) ? obj1->
short_descr : "something";
break;
case 'P':
i = can_see_obj ( to,
obj2 ) ? obj2->
short_descr : "something";
break;
case 'd':
if ( !arg2 || ( ( char * ) arg2 )[0] == '\0' )
{
i = "door";
}
else
{
one_argument ( ( char * ) arg2, fname );
i = fname;
}
break;
case 'G':
if ( ch->alignment < 0 )
{
i = "Muska";
}
else
{
i = "Loki";
}
break;
}
}
break;
default:
*point++ = *str++;
break;
}
++str;
while ( ( *point = *i ) != '\0' )
++point, ++i;
}
*point++ = '\n';
*point++ = '\r';
*point = '\0';
if ( collen )
buf[collen] = UPPER ( buf[collen] );
buf[0] = UPPER ( buf[0] );
if ( to->desc != NULL )
{
if ( IS_NPC ( to ) || !IS_SET ( to->pcdata->verbose, verbose ) )
write_to_buffer ( to->desc, buf, point - buf );
continue;
}
if ( MOBtrigger )
mp_act_trigger ( buf, to, ch, arg1, arg2, TRIG_ACT );
}
return;
}
char *colour ( char type, CHAR_DATA * ch )
{
if ( IS_NPC ( ch ) )
return ( "" );
switch ( type )
{
default:
sprintf ( clcode, colour_clear ( ch ) );
break;
case 'x':
sprintf ( clcode, colour_clear ( ch ) );
break;
case '0':
sprintf ( clcode, colour_clear ( ch ) );
break;
case 'z':
sprintf ( clcode, BLINK );
break;
case 'b':
sprintf ( clcode, C_BLUE );
break;
case '4':
sprintf ( clcode, C_BLUE );
break;
case 'c':
sprintf ( clcode, C_CYAN );
break;
case '6':
sprintf ( clcode, C_CYAN );
break;
case 'g':
sprintf ( clcode, C_GREEN );
break;
case '2':
sprintf ( clcode, C_GREEN );
break;
case 'm':
sprintf ( clcode, C_MAGENTA );
break;
case '5':
sprintf ( clcode, C_MAGENTA );
break;
case 'r':
sprintf ( clcode, C_RED );
break;
case '1':
sprintf ( clcode, C_RED );
break;
case 'w':
sprintf ( clcode, C_WHITE );
break;
case '7':
sprintf ( clcode, C_WHITE );
break;
case 'y':
sprintf ( clcode, C_YELLOW );
break;
case '3':
sprintf ( clcode, C_YELLOW );
break;
case 'B':
sprintf ( clcode, C_B_BLUE );
break;
case '$':
sprintf ( clcode, C_B_BLUE );
break;
case 'C':
sprintf ( clcode, C_B_CYAN );
break;
case '^':
sprintf ( clcode, C_B_CYAN );
break;
case 'G':
sprintf ( clcode, C_B_GREEN );
break;
case '@':
sprintf ( clcode, C_B_GREEN );
break;
case 'M':
sprintf ( clcode, C_B_MAGENTA );
break;
case '%':
sprintf ( clcode, C_B_MAGENTA );
break;
case 'R':
sprintf ( clcode, C_B_RED );
break;
case '!':
sprintf ( clcode, C_B_RED );
break;
case 'W':
sprintf ( clcode, C_B_WHITE );
break;
case '&':
sprintf ( clcode, C_B_WHITE );
break;
case 'Y':
sprintf ( clcode, C_B_YELLOW );
break;
case '#':
sprintf ( clcode, C_B_YELLOW );
break;
case 'D':
sprintf ( clcode, C_D_GREY );
break;
case '8':
sprintf ( clcode, C_D_GREY );
break;
case '*':
switch ( number_range ( 2, 16 ) )
{
case 2:
sprintf ( clcode, C_RED );
break;
case 3:
sprintf ( clcode, C_GREEN );
break;
case 4:
sprintf ( clcode, C_YELLOW );
break;
case 5:
sprintf ( clcode, C_BLUE );
break;
case 6:
sprintf ( clcode, C_MAGENTA );
break;
case 7:
sprintf ( clcode, C_CYAN );
break;
case 8:
sprintf ( clcode, C_WHITE );
break;
case 9:
sprintf ( clcode, C_D_GREY );
break;
case 10:
sprintf ( clcode, C_B_RED );
break;
case 11:
sprintf ( clcode, C_B_GREEN );
break;
case 12:
sprintf ( clcode, C_B_YELLOW );
break;
case 13:
sprintf ( clcode, C_B_BLUE );
break;
case 14:
sprintf ( clcode, C_B_MAGENTA );
break;
case 15:
sprintf ( clcode, C_B_CYAN );
break;
case 16:
sprintf ( clcode, C_B_WHITE );
break;
}
break;
case 'A': /* Auction Channel */
if ( ch->color_auc )
{
sprintf ( clcode, colour_channel ( ch->color_auc, ch ) );
}
else
{
sprintf ( clcode, C_B_GREEN );
}
break;
case 'E': /* Clan Gossip Channel */
if ( ch->color_cgo )
{
sprintf ( clcode, colour_channel ( ch->color_cgo, ch ) );
}
else
{
sprintf ( clcode, C_B_RED );
}
break;
case 'F': /* Clan Talk Channel */
if ( ch->color_cla )
{
sprintf ( clcode, colour_channel ( ch->color_cla, ch ) );
}
else
{
sprintf ( clcode, C_B_MAGENTA );
}
break;
case 'H': /* Gossip Channel */
if ( ch->color_gos )
{
sprintf ( clcode, colour_channel ( ch->color_gos, ch ) );
}
else
{
sprintf ( clcode, C_B_BLUE );
}
break;
case 'J': /* Grats Channel */
if ( ch->color_gra )
{
sprintf ( clcode, colour_channel ( ch->color_gra, ch ) );
}
else
{
sprintf ( clcode, C_YELLOW );
}
break;
case 'K': /* Group Tell Channel */
if ( ch->color_gte )
{
sprintf ( clcode, colour_channel ( ch->color_gte, ch ) );
}
else
{
sprintf ( clcode, C_CYAN );
}
break;
case 'L': /* Immortal Talk Channel */
if ( ch->color_imm )
{
sprintf ( clcode, colour_channel ( ch->color_imm, ch ) );
}
else
{
sprintf ( clcode, C_B_WHITE );
}
break;
case 'N': /* Music Channel */
if ( ch->color_mus )
{
sprintf ( clcode, colour_channel ( ch->color_mus, ch ) );
}
else
{
sprintf ( clcode, C_MAGENTA );
}
break;
case 'P': /* Question+Answer Channel */
if ( ch->color_que )
{
sprintf ( clcode, colour_channel ( ch->color_que, ch ) );
}
else
{
sprintf ( clcode, C_B_YELLOW );
}
break;
case 'Q': /* Quote Channel */
if ( ch->color_quo )
{
sprintf ( clcode, colour_channel ( ch->color_quo, ch ) );
}
else
{
sprintf ( clcode, C_GREEN );
}
break;
case 'S': /* Say Channel */
if ( ch->color_say )
{
sprintf ( clcode, colour_channel ( ch->color_say, ch ) );
}
else
{
sprintf ( clcode, C_MAGENTA );
}
break;
case 'T': /* Shout+Yell Channel */
if ( ch->color_sho )
{
sprintf ( clcode, colour_channel ( ch->color_sho, ch ) );
}
else
{
sprintf ( clcode, C_B_RED );
}
break;
case 'U': /* Tell+Reply Channel */
if ( ch->color_tel )
{
sprintf ( clcode, colour_channel ( ch->color_tel, ch ) );
}
else
{
sprintf ( clcode, C_CYAN );
}
break;
case 'V': /* Wiznet Messages */
if ( ch->color_wiz )
{
sprintf ( clcode, colour_channel ( ch->color_wiz, ch ) );
}
else
{
sprintf ( clcode, C_WHITE );
}
break;
case 'a': /* Mobile Talk */
if ( ch->color_mob )
{
sprintf ( clcode, colour_channel ( ch->color_mob, ch ) );
}
else
{
sprintf ( clcode, C_MAGENTA );
}
break;
case 'e': /* Room Title */
if ( ch->color_roo )
{
sprintf ( clcode, colour_channel ( ch->color_roo, ch ) );
}
else
{
sprintf ( clcode, C_B_BLUE );
}
break;
case 'f': /* Opponent Condition */
if ( ch->color_con )
{
sprintf ( clcode, colour_channel ( ch->color_con, ch ) );
}
else
{
sprintf ( clcode, C_B_RED );
}
break;
case 'h': /* Fight Actions */
if ( ch->color_fig )
{
sprintf ( clcode, colour_channel ( ch->color_fig, ch ) );
}
else
{
sprintf ( clcode, C_B_BLUE );
}
break;
case 'i': /* Opponents Fight Actions */
if ( ch->color_opp )
{
sprintf ( clcode, colour_channel ( ch->color_opp, ch ) );
}
else
{
sprintf ( clcode, C_CYAN );
}
break;
case 'j': /* Disarm Messages */
if ( ch->color_dis )
{
sprintf ( clcode, colour_channel ( ch->color_dis, ch ) );
}
else
{
sprintf ( clcode, C_B_YELLOW );
}
break;
case 'k': /* Witness Messages */
if ( ch->color_wit )
{
sprintf ( clcode, colour_channel ( ch->color_wit, ch ) );
}
else
{
sprintf ( clcode, colour_clear ( ch ) );
}
break;
case 'l': /* Quest Gossip */
if ( ch->color_qgo )
{
sprintf ( clcode, colour_channel ( ch->color_qgo, ch ) );
}
else
{
sprintf ( clcode, C_B_CYAN );
}
break;
case '{':
sprintf ( clcode, "%c", '{' );
break;
}
return clcode;
}
/*
* The colour version of the act( ) function, -Lope
*/
void act_new ( const char *format, CHAR_DATA * ch, const void *arg1,
const void *arg2, int type, int min_pos )
{
static char *const he_she[] = {
"it", "he", "she"
};
static char *const him_her[] = {
"it", "him", "her"
};
static char *const his_her[] = {
"its", "his", "her"
};
CHAR_DATA *to;
CHAR_DATA *vch = ( CHAR_DATA * ) arg2;
OBJ_DATA *obj1 = ( OBJ_DATA * ) arg1;
OBJ_DATA *obj2 = ( OBJ_DATA * ) arg2;
const char *str;
char *i;
char *point;
char buf[MAX_STRING_LENGTH];
char fname[MAX_INPUT_LENGTH];
if ( !format || !*format )
return;
if ( !ch || !ch->in_room )
return;
to = ch->in_room->people;
if ( type == TO_VICT )
{
if ( !vch )
{
bug ( "Act: null vch with TO_VICT.", 0 );
return;
}
if ( !vch->in_room )
return;
to = vch->in_room->people;
}
for ( ; to; to = to->next_in_room )
{
if ( ( !IS_NPC ( to ) && to->desc == NULL ) ||
( IS_NPC ( to ) && !HAS_TRIGGER ( to, TRIG_ACT ) ) ||
to->position < min_pos )
continue;
if ( type == TO_CHAR && to != ch )
continue;
if ( type == TO_VICT && ( to != vch || to == ch ) )
continue;
if ( type == TO_ROOM && to == ch )
continue;
if ( type == TO_NOTVICT && ( to == ch || to == vch ) )
continue;
point = buf;
str = format;
while ( *str )
{
if ( *str != '$' )
{
*point++ = *str++;
continue;
}
i = NULL;
switch ( *str )
{
case '$':
++str;
i = " <@@@> ";
if ( !arg2 && *str >= 'A' && *str <= 'Z' && *str != 'G' )
{
bug ( "Act: missing arg2 for code %d.", *str );
i = " <@@@> ";
}
else
{
switch ( *str )
{
default:
bug ( "Act: bad code %d.", *str );
i = " <@@@> ";
break;
case 't':
i = ( char * ) arg1;
break;
case 'T':
i = ( char * ) arg2;
break;
case 'n':
i = PERS ( ch, to );
break;
case 'N':
i = PERS ( vch, to );
break;
case 'e':
i = he_she[URANGE ( 0, ch->sex, 2 )];
break;
case 'E':
i = he_she[URANGE ( 0, vch->sex, 2 )];
break;
case 'm':
i = him_her[URANGE ( 0, ch->sex, 2 )];
break;
case 'M':
i = him_her[URANGE ( 0, vch->sex, 2 )];
break;
case 's':
i = his_her[URANGE ( 0, ch->sex, 2 )];
break;
case 'S':
i = his_her[URANGE ( 0, vch->sex, 2 )];
break;
case 'p':
i = can_see_obj ( to,
obj1 ) ? obj1->
short_descr : "something";
break;
case 'P':
i = can_see_obj ( to,
obj2 ) ? obj2->
short_descr : "something";
break;
case 'd':
if ( !arg2 || ( ( char * ) arg2 )[0] == '\0' )
{
i = "door";
}
else
{
one_argument ( ( char * ) arg2, fname );
i = fname;
}
break;
case 'G':
if ( ch->alignment < 0 )
{
i = "Muska";
}
else
{
i = "Loki";
}
break;
}
}
break;
default:
*point++ = *str++;
break;
}
++str;
while ( ( *point = *i ) != '\0' )
++point, ++i;
}
*point++ = '\n';
*point++ = '\r';
*point = '\0';
buf[0] = UPPER ( buf[0] );
if ( to->desc != NULL )
write_to_buffer ( to->desc, buf, point - buf );
else if ( MOBtrigger )
mp_act_trigger ( buf, to, ch, arg1, arg2, TRIG_ACT );
}
return;
}
void act ( const char *format, CHAR_DATA * ch, const void *arg1,
const void *arg2, int type )
{
/* to be compatible with older code */
xact_new ( format, ch, arg1, arg2, type, POS_RESTING, VERBOSE_STD );
}
/*
void act_new (const char *format, CHAR_DATA *ch, const void *arg1, const void *arg2,
int type, int min_pos )
{
xact_new(format,ch,arg1,arg2,type,min_pos,VERBOSE_STD);
}*/
char *colour_clear ( CHAR_DATA * ch )
{
if ( ch && ch->color )
{
if ( ch->color == 1 )
sprintf ( clcode, R_RED );
else if ( ch->color == 2 )
sprintf ( clcode, R_GREEN );
else if ( ch->color == 3 )
sprintf ( clcode, R_YELLOW );
else if ( ch->color == 4 )
sprintf ( clcode, R_BLUE );
else if ( ch->color == 5 )
sprintf ( clcode, R_MAGENTA );
else if ( ch->color == 6 )
sprintf ( clcode, R_CYAN );
else if ( ch->color == 7 )
sprintf ( clcode, R_WHITE );
else if ( ch->color == 8 )
sprintf ( clcode, R_D_GREY );
else if ( ch->color == 9 )
sprintf ( clcode, R_B_RED );
else if ( ch->color == 10 )
sprintf ( clcode, R_B_GREEN );
else if ( ch->color == 11 )
sprintf ( clcode, R_B_YELLOW );
else if ( ch->color == 12 )
sprintf ( clcode, R_B_BLUE );
else if ( ch->color == 13 )
sprintf ( clcode, R_B_MAGENTA );
else if ( ch->color == 14 )
sprintf ( clcode, R_B_CYAN );
else if ( ch->color == 15 )
sprintf ( clcode, R_B_WHITE );
else if ( ch->color == 16 )
sprintf ( clcode, R_BLACK );
else
sprintf ( clcode, CLEAR );
}
else
{
sprintf ( clcode, CLEAR );
}
return clcode;
}
char *colour_channel ( int colornum, CHAR_DATA * ch )
{
if ( colornum == 1 )
sprintf ( clcode, C_RED );
else if ( colornum == 2 )
sprintf ( clcode, C_GREEN );
else if ( colornum == 3 )
sprintf ( clcode, C_YELLOW );
else if ( colornum == 4 )
sprintf ( clcode, C_BLUE );
else if ( colornum == 5 )
sprintf ( clcode, C_MAGENTA );
else if ( colornum == 6 )
sprintf ( clcode, C_CYAN );
else if ( colornum == 7 )
sprintf ( clcode, C_WHITE );
else if ( colornum == 8 )
sprintf ( clcode, C_D_GREY );
else if ( colornum == 9 )
sprintf ( clcode, C_B_RED );
else if ( colornum == 10 )
sprintf ( clcode, C_B_GREEN );
else if ( colornum == 11 )
sprintf ( clcode, C_B_YELLOW );
else if ( colornum == 12 )
sprintf ( clcode, C_B_BLUE );
else if ( colornum == 13 )
sprintf ( clcode, C_B_MAGENTA );
else if ( colornum == 14 )
sprintf ( clcode, C_B_CYAN );
else if ( colornum == 15 )
sprintf ( clcode, C_B_WHITE );
else if ( colornum == 16 )
sprintf ( clcode, C_BLACK );
else
sprintf ( clcode, colour_clear ( ch ) );
return clcode;
}
/*
* Macintosh support functions.
*/
#if defined(macintosh)
int gettimeofday ( struct timeval *tp, void *tzp )
{
tp->tv_sec = time ( NULL );
tp->tv_usec = 0;
}
#endif
void logf ( char *fmt, ... )
{
char buf[2 * MSL];
va_list args;
va_start ( args, fmt );
vsprintf ( buf, fmt, args );
va_end ( args );
log_string ( buf );
}
/* source: EOD, by John Booth <???> */
void printf_to_char ( CHAR_DATA * ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH];
va_list args;
va_start ( args, fmt );
vsnprintf ( buf, MSL, fmt, args );
va_end ( args );
send_to_char ( buf, ch );
}
void center_to_char ( char *argument, CHAR_DATA * ch, int columns )
{
char centered[MAX_INPUT_LENGTH];
int spaces;
columns = ( columns < 2 ) ? 80 : columns;
spaces = ( columns - strlen ( argument ) ) / 2;
sprintf ( centered, "%*c%s", spaces, ' ', argument );
send_to_char ( centered, ch );
return;
}
CH_CMD ( do_font )
{
int place, size;
char buf[10];
size = strlen ( argument );
/* top border */
center_to_char ( "{b+{D-", ch, 72 - ( 2 * size ) );
for ( place = 2; place < size; place++ )
send_to_char ( "{b+{D-", ch );
send_to_char ( "{b+\n\r", ch );
/* middle */
sprintf ( buf, "{B%c", UPPER ( argument[0] ) );
center_to_char ( buf, ch, 72 - ( 2 * size ) );
for ( place = 1; place < size; place++ )
{
sprintf ( buf, " %c", UPPER ( argument[place] ) );
send_to_char ( buf, ch );
}
send_to_char ( "{x\n\r", ch );
/* bottom border */
center_to_char ( "{b+{D-", ch, 72 - ( 2 * size ) );
for ( place = 2; place < size; place++ )
send_to_char ( "{b+{D-", ch );
send_to_char ( "{b+\n\r", ch );
return;
}
void bugf ( char *fmt, ... )
{
char buf[MAX_STRING_LENGTH];
va_list args;
va_start ( args, fmt );
vsnprintf ( buf, MSL, fmt, args );
va_end ( args );
bug ( buf, 0 );
}
/*
void logf (char * fmt, ...)
{
char buf [2*MSL];
va_list args;
va_start (args, fmt);
vsnprintf (buf, 2*MSL, fmt, args);
va_end (args);
log_string (buf);
}
*/
#define CH(descriptor) ((descriptor)->original ? \
(descriptor)->original : (descriptor)->character)
/* This file holds the copyover data */
#define COPYOVER_FILE "copyover.data"
/* This is the executable file */
#define EXE_FILE "../src/rot"
/*
Palrich -- mdb99284@kestrel.tamucc.edu
telnet://areth.com:4000
*/
/* Copyover - Original idea: Fusion of MUD++
* Adapted to Diku by Erwin S. Andreasen, <erwin@pip.dknet.dk>
* http://pip.dknet.dk/~pip1773
* Changed into a ROM patch after seeing the 100th request for it :)
*/
CH_CMD ( do_copyover )
{
FILE *fp;
DESCRIPTOR_DATA *d, *d_next;
char arg0[10], arg1[10], arg2[10], arg3[10], arg4[10], arg5[10];
char buf[100];
fp = file_open ( COPYOVER_FILE, "w" );
if ( !fp )
{
if ( ch )
send_to_char ( "Copyover file not writeable, aborted.\r\n", ch );
sprintf ( buf, "Could not write to copyover file: %s",
COPYOVER_FILE );
log_string ( buf );
perror ( "do_copyover:fopen" );
return;
}
/* Consider changing all saved areas here, if you use OLC */
do_asave ( NULL, "changed" ); /* - autosave changed areas */
//save_gquest_data();
sprintf ( buf, "\r\n***Copyover in progress*** Please wait.... \r\n" );
/* For each playing descriptor, save its state */
for ( d = descriptor_list; d; d = d_next )
{
CHAR_DATA *och = CH ( d );
d_next = d->next; /* We delete from the list , so need to save this */
if ( !d->character || d->connected > CON_PLAYING ) /* drop those logging on */
{
write_to_descriptor ( d->descriptor,
"\r\nSorry, we are rebooting. Come back in a few minutes.\r\n",
0 );
close_socket ( d ); /* throw'em out */
}
else
{
fprintf ( fp, "%d %s %s\n", d->descriptor, och->name, d->host );
save_char_obj ( och );
write_to_descriptor ( d->descriptor, buf, 0 );
}
}
fprintf ( fp, "-1\n" );
file_close ( fp );
/* Close reserve and other always-open files and release other resources */
if ( fpReserve )
fclose ( fpReserve );
/* exec - descriptors are inherited */
sprintf ( arg0, "%s", "rot" );
sprintf ( arg1, "%d", port );
sprintf ( arg2, "%d", wwwport );
sprintf ( arg3, "%s", "copyover" );
sprintf ( arg4, "%d", control );
sprintf ( arg5, "%d", wwwcontrol );
execl ( EXE_FILE, arg0, arg1, arg2, arg3, arg4, arg5, ( char * ) NULL );
/* Failed - sucessful exec will not return */
perror ( "do_copyover: execl" );
if ( ch )
send_to_char ( "Copyover FAILED!\r\n", ch );
/* Here you might want to reopen fpReserve */
if ( !fpReserve )
fpReserve = fopen ( NULL_FILE, "r" );
}
/* Recover from a copyover - load players */
void copyover_recover ( )
{
DESCRIPTOR_DATA *d;
FILE *fp;
char name[100];
char host[MSL];
int desc;
bool fOld;
logf ( "Copyover recovery initiated" );
fp = file_open ( COPYOVER_FILE, "r" );
if ( !fp ) /* there are some descriptors open which will hang forever then ? */
{
perror ( "copyover_recover:fopen" );
logf ( "Copyover file not found. Exitting.\n\r" );
quit ( 1 );
}
unlink ( COPYOVER_FILE ); /* In case something crashes - doesn't prevent reading */
for ( ;; )
{
fscanf ( fp, "%d %s %s\n", &desc, name, host );
if ( desc == -1 )
break;
/* Write something, and check if it goes error-free */
if ( !write_to_descriptor
( desc, "\n\rRestoring from copyover...\n\r", 0 ) )
{
close ( desc ); /* nope */
continue;
}
d = new_descriptor ( );
d->descriptor = desc;
d->host = str_dup ( host );
d->next = descriptor_list;
descriptor_list = d;
d->connected = CON_COPYOVER_RECOVER; /* -15, so close_socket frees the char */
/* Now, find the pfile */
fOld = load_char_obj ( d, name );
if ( !fOld ) /* Player file not found?! */
{
write_to_descriptor ( desc,
"\n\rSomehow, your character was lost in the copyover. Sorry.\n\r",
0 );
close_socket ( d );
}
else /* ok! */
{
write_to_descriptor ( desc, "\n\rCopyover recovery complete.\n\r",
0 );
/* Just In Case */
if ( !d->character->in_room )
d->character->in_room = get_room_index ( ROOM_VNUM_TEMPLE );
/* Insert in the char_list */
d->character->next = char_list;
char_list = d->character;
char_to_room ( d->character, d->character->in_room );
do_look ( d->character, "auto" );
act ( "$n materializes!", d->character, NULL, NULL, TO_ROOM );
d->connected = CON_PLAYING;
if ( d->character->pet != NULL )
{
char_to_room ( d->character->pet, d->character->in_room );
act ( "$n materializes!.", d->character->pet, NULL, NULL,
TO_ROOM );
}
}
}
file_close ( fp );
}
#define CORE_EXAMINE_SCRIPT "../area/gdbscript"
void halt_mud ( int sig )
{
DESCRIPTOR_DATA *d;
CHAR_DATA *ch;
struct sigaction default_action;
int i;
pid_t forkpid;
wait ( NULL );
if ( !crashed )
{
crashed++;
fprintf ( stderr, "GAME CRASHED (SIGNAL %d).\rLast command: %s\r",
sig, last_command );
// Inform last command typer that he caused the crash
if ( strlen ( last_command2 ) )
{
write_to_descriptor ( last_descriptor,
"\n\rThe last command you typed, '", 0 );
write_to_descriptor ( last_descriptor, last_command2, 0 );
write_to_descriptor ( last_descriptor,
"', might have caused this crash.\n\r"
"Please note any unusual circumstances to IMP and avoid using that command.\n\r",
0 );
}
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
ch = CH ( d );
if ( !ch )
{
close_socket ( d );
continue;
}
if ( IS_NPC ( ch ) )
continue;
write_to_descriptor ( d->descriptor,
"\n\rThe mud has CRASHED.\007\n\r", 0 );
}
// try to save all characters - save_char_obj has sanity checking
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
ch = CH ( d );
if ( !ch )
{
close_socket ( d );
continue;
}
save_char_obj ( ch );
}
// success - proceed with fork/copyover plan. Otherwise will go to
// next section and crash with a full reboot to recover
if ( ( forkpid = fork ( ) ) > 0 )
{
// Parent process copyover and exit
waitpid ( forkpid, NULL, WNOHANG | WUNTRACED );
// this requires you to add an "if (ch)" before the send_to_char
// statements in do_copyover.
do_copyover ( NULL, "" );
exit ( 0 );
}
else if ( forkpid < 0 )
{
exit ( 1 );
}
// Child process proceed to dump
// Close all files!
for ( i = 255; i >= 0; i-- )
close ( i );
// Dup /dev/null to STD{IN,OUT,ERR}
open ( "/dev/null", O_RDWR );
dup ( 0 );
dup ( 0 );
default_action.sa_handler = SIG_DFL;
sigaction ( sig, &default_action, NULL );
// I run different scripts depending on my port
if ( !fork ( ) )
{
execl ( CORE_EXAMINE_SCRIPT, CORE_EXAMINE_SCRIPT,
( char * ) NULL );
exit ( 0 );
}
else
return;
raise ( sig );
}
if ( crashed == 1 )
{
crashed++;
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
ch = d->original ? d->original : d->character;
if ( ch == NULL )
{
close_socket ( d );
continue;
}
if ( IS_NPC ( ch ) )
continue;
write_to_descriptor ( d->descriptor,
"** Error saving character files; conducting full reboot. **\007\n\r",
0 );
close_socket ( d );
continue;
}
fprintf ( stderr, "CHARACTERS NOT SAVED.\r" );
default_action.sa_handler = SIG_DFL;
sigaction ( sig, &default_action, NULL );
if ( !fork ( ) )
{
kill ( getppid ( ), sig );
exit ( 1 );
}
else
return;
raise ( sig );
}
if ( crashed == 2 )
{
crashed++;
fprintf ( stderr, "TOTAL GAME CRASH." );
default_action.sa_handler = SIG_DFL;
sigaction ( sig, &default_action, NULL );
if ( !fork ( ) )
{
kill ( getppid ( ), sig );
exit ( 1 );
}
else
return;
raise ( sig );
}
if ( crashed == 3 )
{
default_action.sa_handler = SIG_DFL;
sigaction ( sig, &default_action, NULL );
if ( !fork ( ) )
{
kill ( getppid ( ), sig );
exit ( 1 );
}
else
return;
raise ( sig );
}
}