/*--------------------------------------------------------------------------* * ** WolfPaw 3.0 ** * *--------------------------------------------------------------------------* * WolfPaw 3.0 (c) 1997 - 1999 by Dale Corse * *--------------------------------------------------------------------------* * The WolfPaw Coding Team is headed by: Greywolf * * With the Assitance from: Callinon, Dhamon, Sentra, Wyverns, Altrag * * Scryn, Thoric, Justice, Tricops and Brogar. * *--------------------------------------------------------------------------* * Based on SMAUG 1.2a. Copyright 1994 - 1996 by Derek Snider * * SMAUG Coding Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, * * Swordbearer, Gorog, Grishnakh and Tricops. * *--------------------------------------------------------------------------* * Merc 2.1 Diku MUD Improvments (C) 1992 - 1993 by Michael Chastain, * * Michael Quan, and Michael Tse. * * Original Diku MUD (C) 1990 - 1991 by Sebastian Hammer, Michael Seifert, * * Hans Hendrik Strfeldt, Tom Madsen, and Katja Nyboe. * *--------------------------------------------------------------------------* * Low-level communication module * ****************************************************************************/ #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> #include <ctype.h> #include <errno.h> #include <stdio.h> #include <time.h> #include <string.h> #include <fcntl.h> #include <signal.h> #include <stdarg.h> #include "mud.h" #include <sys/resource.h> /* * Socket and TCP/IP stuff. */ #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <arpa/telnet.h> #include <netdb.h> char command[MAX_INPUT_LENGTH]; /* multi commands --GW*/ 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' }; void send_auth args( ( struct descriptor_data *d ) ); void read_auth args( ( struct descriptor_data *d ) ); void start_auth args( ( struct descriptor_data *d ) ); void save_sysdata args( ( SYSTEM_DATA sys ) ); void load_corpses args( ( void ) ); void install_other_handlers args( ( void) ); void examine_last_command args( (void) ); void alarm_update args( (void) ); void init_alarm_handler args( (void) ); void add_refferal args( ( char *name,char *reff, char *site, char *email ) ); int get_mortal_num_desc args( (CHAR_DATA *ch) ); void show_mode args( ( DESCRIPTOR_DATA *d ) ); void challenge_cancel args( ( CHAR_DATA *ch, CHAR_DATA *victim, char *argument ) ); void do_char_ressurect args ( ( CHAR_DATA *ch ) ); void do_char_notressurect args ( ( CHAR_DATA *ch ) ); CHAR_DATA *get_char_list( CHAR_DATA *ch ); bool write_to_desc_color( char *txt, DESCRIPTOR_DATA *d ); void show_overlimit(CHAR_DATA *ch); void show_titlescreen(DESCRIPTOR_DATA *d); /* * Global variables. */ DESCRIPTOR_DATA * first_descriptor; /* First descriptor */ DESCRIPTOR_DATA * last_descriptor; /* Last descriptor */ DESCRIPTOR_DATA * d_next; /* Next descriptor in loop */ int num_descriptors; FILE * fpReserve; /* Reserved file handle */ bool mud_down; /* Shutdown */ bool wizlock; /* Game is wizlocked */ bool new_player; /* New Player Entry --GW */ sh_int MemLogCount; /* Memlog Counter --GW */ sh_int MemLogMax; /* Max Lines Allowed --GW */ sh_int RoomLogCount; /* Roomlog Counter --GW */ sh_int RoomLogMax; /* Max Lines Allowed --GW */ time_t boot_time; HOUR_MIN_SEC set_boot_time_struct; HOUR_MIN_SEC * set_boot_time; struct tm * new_boot_time; struct tm new_boot_struct; char str_boot_time[MAX_INPUT_LENGTH]; char lastplayercmd[MAX_INPUT_LENGTH*2]; time_t current_time; /* Time of this pulse */ int port; /* Port number to be used */ int control; /* Controlling descriptor */ int newdesc; /* New descriptor */ fd_set in_set; /* Set of desc's for reading */ fd_set out_set; /* Set of desc's for writing */ fd_set exc_set; /* Set of desc's with errors */ int maxdesc; char * wpolcargbuf; /* for wp-olc */ extern bool disable_timer_abort; time_t last_check; char mudargs[MSL]; bool DISABLE_LIMIT_SCAN; /* * OS-dependent local functions. */ void game_loop args( ( ) ); int init_socket args( ( int port ) ); void new_descriptor args( ( int new_desc ) ); bool read_from_descriptor args( ( DESCRIPTOR_DATA *d ) ); bool write_to_descriptor args( ( int desc, char *txt, int length ) ); char *get_multi_command args((DESCRIPTOR_DATA *d,char *argument)); /* * Other local functions (OS-independent). */ bool check_parse_name args( ( char *name ) ); bool check_reconnect args( ( DESCRIPTOR_DATA *d, char *name, bool fConn ) ); bool check_playing args( ( DESCRIPTOR_DATA *d, char *name, bool kick ) ); int main args( ( int argc, char **argv ) ); void nanny args( ( DESCRIPTOR_DATA *d, char *argument ) ); bool flush_buffer args( ( DESCRIPTOR_DATA *d, bool fPrompt ) ); void read_from_buffer args( ( DESCRIPTOR_DATA *d ) ); void stop_idling args( ( CHAR_DATA *ch ) ); void free_desc args( ( DESCRIPTOR_DATA *d ) ); void display_prompt args( ( DESCRIPTOR_DATA *d ) ); int make_color_sequence args( ( const char *col, char *buf, DESCRIPTOR_DATA *d ) ); void set_pager_input args( ( DESCRIPTOR_DATA *d, char *argument ) ); bool pager_output args( ( DESCRIPTOR_DATA *d ) ); void mail_count args( ( CHAR_DATA *ch ) ); int number_kombat args( ( void ) ); /* * Globals Now .. --GW */ struct timeval now_time; bool fCopyOver = FALSE; int main( int argc, char **argv ) { char buf[MSL]; sysdata.boottime =0; /* * Memory debugging if needed. */ #if defined(MALLOC_DEBUG) malloc_debug( 2 ); #endif PULSE_PER_SECOND = 4; num_descriptors = 0; first_descriptor = NULL; last_descriptor = NULL; sysdata.NO_NAME_RESOLVING = TRUE; sysdata.WAIT_FOR_AUTH = TRUE; /* * Init time. */ gettimeofday( &now_time, NULL ); current_time = (time_t) now_time.tv_sec; /* gettimeofday( &boot_time, NULL); okay, so it's kludgy, sue me :) */ boot_time = time(0); /* <-- I think this is what you wanted */ strcpy( str_boot_time, ctime( ¤t_time ) ); /* * Init boot time. */ set_boot_time = &set_boot_time_struct; set_boot_time->manual = 0; new_boot_time = update_time(localtime(¤t_time)); /* Copies *new_boot_time to new_boot_struct, and then points new_boot_time to new_boot_struct again. -- Alty */ new_boot_struct = *new_boot_time; new_boot_time = &new_boot_struct; /* 18 hours */ new_boot_time->tm_hour += 18; if(new_boot_time->tm_hour >= 24) { new_boot_time->tm_mday += 1; new_boot_time->tm_hour -= 24; } /* Update new_boot_time (due to day increment) */ new_boot_time = update_time(new_boot_time); new_boot_struct = *new_boot_time; new_boot_time = &new_boot_struct; new_boot_time_t = mktime(new_boot_time); reboot_check(mktime(new_boot_time)); /* Set reboot time string for do_time */ log_string("Setting Reboot Time"); get_reboot_string(); /* * Reserve three channels for our use. */ log_string("Initiating Memlog"); rename( MEMLOG_FILE, "../system/memlog.lastboot" ); unlink(MEMLOG_FILE); MemLogCount = 0; /* Current Lines of Memlog --GW */ MemLogMax = 100; /* Maximum Allowed --GW */ log_string("Initiating Roomlog"); rename( ROOMLOG_FILE, "../system/roomlog.lastboot" ); unlink(ROOMLOG_FILE); RoomLogCount = 0; /* Current Lines of Roomlog --GW */ RoomLogMax = 100; /* Maximum Allowed --GW */ /* if ( ( fpReserve = fopen( NULL_FILE, "r" ) ) == NULL ) { perror( NULL_FILE ); exit( 1 ); }*/ if ( ( fpLOG = fopen( NULL_FILE, "r" ) ) == NULL ) { perror( NULL_FILE ); exit( 1 ); } /* * Get the port number. */ port = 5000; if ( argc > 1 ) { if ( !is_number( argv[1] ) ) { fprintf( stderr, "Usage: %s [port #]\n", argv[0] ); exit( 1 ); } else if ( ( port = atoi( argv[1] ) ) <= 1024 ) { fprintf( stderr, "Port number must be above 1024.\n" ); exit( 1 ); } fCopyOver=FALSE; DISABLE_LIMIT_SCAN=FALSE; /* This now handles all arguments --GW */ /* Not all args are handled right here.. it is codewide.. dont freak =) */ if (argv[2] && argv[2][0]) /* Ok we have arguments */ { /* Kill the - */ if ( argv[2][0] == '-' ) argv[2]++; sprintf(mudargs,"%s",argv[2]); /* List All */ if ( mudarg_scan('?') ) { fprintf(stderr, "Usage: %s <port #> [-WLHBIwRS]\n\n",argv[0] ); fprintf(stderr, "Arguments:\n"); fprintf(stderr, "W - Warmboot (Used by SYSTEM only)\n"); fprintf(stderr, "L - Disable Limit Scan\n"); fprintf(stderr, "H - Show Help File Loading\n"); fprintf(stderr, "B - Builder Port\n"); fprintf(stderr, "w - No WebServer\n"); fprintf(stderr, "S - Show Limit Scan\n"); fprintf(stderr, "\n"); exit(0); } if ( mudarg_scan('L') ) /* Disable Limit Scan (used when debugging mud) */ DISABLE_LIMIT_SCAN=TRUE; /* Warmboot */ if ( mudarg_scan('W') ) { fCopyOver = TRUE; control = atoi(argv[3]); } } } /* * Run the game. */ log_string("Booting Database"); init_alarm_handler(); unlink(LOG_FILE); boot_db(fCopyOver); install_other_handlers (); /* crash-log call */ sprintf(buf,"Initializing sockets: %d %d %d %d",port,port+1,port+15,port+16); log_string(buf); //wizlock = TRUE;/* wizlock temperarily*/ /*noenforce = TRUE; noenforce temp */ new_player = FALSE; /* New Player False at First! */ if (!fCopyOver) /* We have already the port if copyover'ed */ { control = init_socket(port); } if ( sysdata.webserv == 1 && !mudarg_scan('w') ) { sprintf(buf,"Booting WebServer on port %d",WEBPORT); log_string(buf); init_web(WEBPORT); } sprintf( log_buf,"The Age of the Ancients is ready too ROCK on port %d.",port ); log_string( log_buf ); sprintf(buf,"*** Booted with PID %d ***",getpid()); log_string(buf); game_loop( ); if ( sysdata.webserv == 1 ) { sprintf(buf,"Closing WebServer Port (%d)",WEBPORT); log_string(buf); shutdown_web(); } close( control ); /* * That's all, folks. */ log_string( "Normal termination of game." ); exit( 0 ); return 0; } int init_socket( int port ) { char hostname[64]; struct sockaddr_in sa; struct hostent *hp; struct servent *sp; int x = 1; int fd; gethostname(hostname, sizeof(hostname)); if ( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { perror( "Init_socket: socket" ); exit( 1 ); } if ( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (void *) &x, sizeof(x) ) < 0 ) { perror( "Init_socket: SO_REUSEADDR" ); close( fd ); exit( 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, (void *) &ld, sizeof(ld) ) < 0 ) { perror( "Init_socket: SO_DONTLINGER" ); close( fd ); exit( 1 ); } } #endif hp = gethostbyname( hostname ); sp = getservbyname( "service", "mud" ); memset(&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; /* hp->h_addrtype; */ sa.sin_port = htons( port ); /*sa.sin_addr.s_addr = htonl(INADDR_ANY);*/ if ( bind( fd, (struct sockaddr *) &sa, sizeof(sa) ) == -1 ) { perror( "Init_socket: bind" ); close( fd ); exit( 1 ); } if ( listen( fd, 50 ) < 0 ) { perror( "Init_socket: listen" ); close( fd ); exit( 1 ); } return fd; } void init_descriptor( DESCRIPTOR_DATA *dnew, int desc) { dnew->next = NULL; dnew->descriptor = desc; dnew->connected = CON_GET_NAME; dnew->outsize = 2000; dnew->idle = 0; dnew->lines = 0; dnew->scrlen = 24; dnew->user = STRALLOC("unknown"); dnew->auth_fd = -1; dnew->auth_inc = 0; dnew->auth_state = 0; dnew->newstate = 0; dnew->prevcolor = 0x07; CREATE( dnew->outbuf, char, dnew->outsize ); } /* Write last command */ void write_last_command () { FILE *fd=NULL; FILE *fd2=NULL; /* Return if no last command - set before normal exit */ if (!last_command[0]) return; if ( ( fd = fopen( LAST_COMMAND_FILE, "a" ) ) == NULL ) { bug("Cannot Open LAST COMMAND File!",0); perror( LAST_COMMAND_FILE ); } else { fprintf(fd,"%s\n",last_command); new_fclose(fd); } if ( ( fd2 = fopen( LAST_FUNCTION_FILE, "a" ) ) == NULL ) { bug("Cannot open LAST_FUNCTION_FILE",0); perror(LAST_FUNCTION_FILE); } else { fprintf(fd2,"%s\n",last_function_call); new_fclose(fd2); } return; } void record_call(char * call_name ) { sprintf (last_function_call, "[%s]", call_name ); return; } /* * System Panic handler --GW */ void syspanic( ) { DESCRIPTOR_DATA *d; char *args[]={ "Start.pl",NULL }; for( d = first_descriptor; d; d = d->next ) { write_to_descriptor(d->descriptor,"WARNING: SYSTEM PANIC -- SHUTTING DOWN!!!\n",0); write_to_descriptor(d->descriptor,"SYS-PANIC: Panic Saving!\n",0); save_char_obj(d->character); write_to_descriptor(d->descriptor,"Character Information Saved.\n",0); write_to_descriptor(d->descriptor,"SYS-PANIC: Exiting... Come back in a Minute!\n",0); close_socket(d,TRUE); } close(control); execvp( "/home/aota/aoa/system/start.pl" ,args ); log_string("Reboot Failed!"); abort( ); } void nasty_signal_handler (int no) { // write_last_command(); // examine_last_command(); /*syspanic();*/ /* System is in a PANIC state! --GW */ } /* Call this before starting the game_loop */ void install_other_handlers () { last_command[0] = '\0'; if (atexit (write_last_command) != 0) { perror ("install_other_handlers:atexit"); exit (1); } /* should probably check return code here */ // signal (SIGSEGV, nasty_signal_handler); /* Possibly other signals could be caught? */ } void tick_update() { if ( TURBO_NUM != PULSE_PER_SECOND ) { PULSE_PER_SECOND = TURBO_NUM; } return; } static void SegVio() { CHAR_DATA *ch; char buf[MAX_STRING_LENGTH]; write_last_command(); log_string( "SEGMENTATION VIOLATION" ); log_string( lastplayercmd ); for ( ch = first_char; ch; ch = ch->next ) { sprintf( buf, "%cPC: %-20s room: %d", IS_NPC(ch) ? 'N' : ' ', ch->name, ch->in_room->vnum ); log_string( buf ); } exit(0); } /* * LAG alarm! -Thoric */ static void caught_alarm() { char buf[MAX_STRING_LENGTH]; bug( "ALARM CLOCK!" ); strcpy( buf, "Alas, the hideous malevalent entity known only as 'Lag' rises once more!\n\r" ); echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL ); if ( newdesc ) { FD_CLR( newdesc, &in_set ); FD_CLR( newdesc, &out_set ); log_string( "clearing newdesc" ); } /* If were being spoofed, intentionally or not.. Disable name lookup --GW*/ log_string("System Activating Global Mode: Name Resolving Disabled."); sysdata.NO_NAME_RESOLVING = FALSE; game_loop( ); close( control ); log_string( "Normal termination of game." ); exit( 0 ); } bool check_bad_desc( int desc ) { if ( FD_ISSET( desc, &exc_set ) ) { FD_CLR( desc, &in_set ); FD_CLR( desc, &out_set ); log_string( "Bad FD caught and disposed." ); return TRUE; } return FALSE; } void accept_new( int ctrl ) { static struct timeval null_time; DESCRIPTOR_DATA *d; /* int maxdesc; Moved up for use with id.c as extern */ #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( ctrl, &in_set ); maxdesc = ctrl; newdesc = 0; for ( d = first_descriptor; 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 (d->auth_fd != -1) { maxdesc = UMAX( maxdesc, d->auth_fd ); FD_SET(d->auth_fd, &in_set); if (IS_SET(d->auth_state, FLAG_WRAUTH)) FD_SET(d->auth_fd, &out_set); } if ( d == last_descriptor ) break; } if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 ) { perror( "accept_new: select: poll" ); exit( 1 ); } if ( FD_ISSET( ctrl, &exc_set ) ) { bug( "Exception raise on controlling descriptor %d", ctrl ); FD_CLR( ctrl, &in_set ); FD_CLR( ctrl, &out_set ); } else if ( FD_ISSET( ctrl, &in_set ) ) { newdesc = ctrl; new_descriptor( newdesc ); } } void game_loop( ) { struct timeval last_time; char cmdline[MAX_INPUT_LENGTH]; DESCRIPTOR_DATA *d; /* time_t last_check = 0; */ signal( SIGPIPE, SIG_IGN ); signal( SIGALRM, caught_alarm ); if ( sysdata.segvio == 1 ) signal( SIGSEGV, SegVio ); /* else signal( SIGSEGV, syspanic );*/ gettimeofday( &last_time, NULL ); current_time = (time_t) last_time.tv_sec; /* Main loop */ while ( !mud_down ) { accept_new( control ); alarm_update(); /*<--- deadlock code*/ tick_update(); /*TURBO FIGHTING SPEED!!! --GW*/ if ( sysdata.webserv == 1 ) handle_web(); /*<--- WebServer Handler */ /* * Kick out descriptors with raised exceptions * or have been idle, then check for input. */ for ( d = first_descriptor; d; d = d_next ) { if ( d == d->next ) { bug( "descriptor_loop: loop found & fixed" ); d->next = NULL; } d_next = d->next; d->idle++; /* make it so a descriptor can idle out */ if ( FD_ISSET( d->descriptor, &exc_set ) ) { FD_CLR( d->descriptor, &in_set ); FD_CLR( d->descriptor, &out_set ); if ( d->character && ( d->connected == CON_PLAYING || d->connected == CON_EDITING ) ) save_char_obj( d->character ); d->outtop = 0; close_socket( d, TRUE ); continue; } else if ( (!d->character && d->idle > 360) /* 2 mins */ || ( d->connected != CON_PLAYING && d->idle > 4800) /* 15 mins */ || d->idle > 28800 ) /* 2 hrs */ { write_to_descriptor( d->descriptor, "Idle timeout... disconnecting.\n\r", 0 ); d->outtop = 0; close_socket( d, TRUE ); continue; } else { d->fcommand = FALSE; if ( FD_ISSET( d->descriptor, &in_set ) ) { d->idle = 0; if ( d->character ) d->character->timer = 0; if ( !read_from_descriptor( d ) && d->descriptor ) { FD_CLR( d->descriptor, &out_set ); if ( d->character && ( d->connected == CON_PLAYING || d->connected == CON_EDITING ) ) save_char_obj( d->character ); d->outtop = 0; close_socket( d, FALSE ); continue; } } /* IDENT authentication */ /* if ( ( d->auth_fd == -1 ) && ( d->atimes < 20 ) && !str_cmp( d->user, "unknown" ) ) start_auth( d ); if ( d->auth_fd != -1) { if ( FD_ISSET( d->auth_fd, &in_set ) ) { read_auth( d ); // if ( !d->auth_state ) // check_ban( d ); } else if ( FD_ISSET( d->auth_fd, &out_set ) && IS_SET( d->auth_state, FLAG_WRAUTH) ) { send_auth( d ); // if ( !d->auth_state ) // check_ban( d ); } }*/ if ( d->character && d->character->wait > 0 ) { --d->character->wait; continue; } if ( d->character && d->character->stun_rounds > 0 ) { if ( d->character->fighting && d->character->fighting->who ) continue; else d->character->stun_rounds = 0; } if ( d->incomm[0] == '\0' ) read_from_buffer( d ); if ( d->incomm[0] != '\0' ) { char *command2; d->fcommand = TRUE; stop_idling( d->character ); strcpy( cmdline, d->incomm ); d->incomm[0] = '\0'; if( d->character ) set_cur_char( d->character ); command2 = get_multi_command( d, cmdline ); if ( d->pagepoint ) set_pager_input(d, cmdline); else switch( d->connected ) { default: nanny( d, cmdline ); break; case CON_PLAYING: substitute_alias( d, command2 ); break; case CON_EDITING: edit_buffer( d->character, command2 ); break; case CON_GREDITING: gredit_engine( d, command2 ); break; } } } if ( d == last_descriptor ) break; } /* * Autonomous game motion. */ update_handler( ); /* * Check REQUESTS pipe */ check_requests( ); /* * Output. */ for ( d = first_descriptor; d; d = d_next ) { d_next = d->next; if ( ( d->fcommand || d->outtop > 0 ) && FD_ISSET(d->descriptor, &out_set) ) { if ( d->pagepoint ) { if ( !pager_output(d) ) { if ( d->character && ( d->connected == CON_PLAYING || d->connected == CON_EDITING ) ) save_char_obj( d->character ); d->outtop = 0; close_socket(d, FALSE); } } else if ( !flush_buffer( d, TRUE ) ) { if ( d->character && ( d->connected == CON_PLAYING || d->connected == CON_EDITING ) ) save_char_obj( d->character ); d->outtop = 0; close_socket( d, FALSE ); } } if ( d == last_descriptor ) break; } /* * 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; /* Check every 10 Mins... */ if ( last_check+600 < current_time ) { CHECK_LINKS(first_descriptor, last_descriptor, next, prev, DESCRIPTOR_DATA); last_check = current_time; } } return; } void new_descriptor( int new_desc ) { char buf[MAX_STRING_LENGTH]; DESCRIPTOR_DATA *dnew=NULL; BAN_DATA *pban; struct sockaddr_in sock; struct hostent *from; int desc; int size; /* char bugbuf[MAX_STRING_LENGTH]; */ set_alarm( 20 ); size = sizeof(sock); if ( check_bad_desc( new_desc ) ) { set_alarm( 0 ); return; } set_alarm( 20 ); if ( ( desc = accept( new_desc, (struct sockaddr *) &sock, &size) ) < 0 ) { perror( "New_descriptor: accept" ); /* sprintf(bugbuf, "[*****] BUG: New_descriptor: accept"); log_string_plus( bugbuf, LOG_COMM, sysdata.log_level ); */ set_alarm( 0 ); return; } if ( check_bad_desc( new_desc ) ) { set_alarm( 0 ); return; } #if !defined(FNDELAY) #define FNDELAY O_NDELAY #endif set_alarm( 20 ); if ( fcntl( desc, F_SETFL, FNDELAY ) == -1 ) { perror( "New_descriptor: fcntl: FNDELAY" ); set_alarm( 0 ); return; } if ( check_bad_desc( new_desc ) ) return; CREATE( dnew, DESCRIPTOR_DATA, 1 ); init_descriptor(dnew, desc ); dnew->port = ntohs(sock.sin_port); strcpy( buf, inet_ntoa( sock.sin_addr ) ); sprintf( log_buf, "Sock.sinaddr: desc: %hd %s, port %hd.", dnew->descriptor,buf, dnew->port ); log_string_plus( log_buf, LOG_COMM, 59 ); if ( sysdata.NO_NAME_RESOLVING ) dnew->host = STRALLOC( buf ); else { from = gethostbyaddr( (char *) &sock.sin_addr, sizeof(sock.sin_addr), AF_INET ); dnew->host = STRALLOC( (char *)( 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. */ for ( pban = first_ban; pban; pban = pban->next ) { if ( !str_prefix( pban->name, dnew->host ) ) { if ( pban->level >= LEVEL_IMMORTAL ) { log_string("[***] Closing link to BANNED site. [***]"); write_to_descriptor( desc,"Your site is prohibited from logging in at this time.\n\r", 0 ); write_to_descriptor( desc,"Email: aota@ancients.org for details.\n\r",0); close( desc ); free_desc( dnew ); set_alarm( 0 ); return; } } if ( !str_suffix( pban->name, dnew->host ) ) { if ( pban->level >= LEVEL_IMMORTAL ) { log_string("[***] Closing link to BANNED site. [***]"); write_to_descriptor( desc, "Your site has been banned from this Mud.\n\r", 0 ); close( desc ); free_desc( dnew ); set_alarm( 0 ); return; } } } /* * Init descriptor data. */ if ( !last_descriptor && first_descriptor ) { DESCRIPTOR_DATA *d; bug( "New_descriptor: last_desc is NULL, but first_desc is not! ...fixing" ); for ( d = first_descriptor; d; d = d->next ) if ( !d->next ) last_descriptor = d; } LINK( dnew, first_descriptor, last_descriptor, next, prev ); start_auth( dnew ); /* Start username authorization */ if ( ++num_descriptors > sysdata.maxplayers ) sysdata.maxplayers = num_descriptors; if ( sysdata.maxplayers > sysdata.alltimemax ) { if ( sysdata.time_of_max ) DISPOSE(sysdata.time_of_max); sprintf(buf, "%24.24s", ctime(¤t_time)); sysdata.time_of_max = str_dup(buf); sysdata.alltimemax = sysdata.maxplayers; sprintf( log_buf, "Broke all-time maximum player record: %d", sysdata.alltimemax ); log_string_plus( log_buf, LOG_COMM, sysdata.log_level ); to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", LEVEL_IMMORTAL ); save_sysdata( sysdata ); } show_titlescreen(dnew); set_alarm(0); return; } /* * Send the greeting. */ void show_titlescreen(DESCRIPTOR_DATA *d) { extern char * help_greeting[3]; int greetnum; sysdata.logins++; greetnum = dice( 1, 3 ); write_to_buffer(d, "\E[2J", 4); if ( help_greeting[greetnum-1][0] == '.' ) write_to_desc_color( help_greeting[greetnum-1]+1, d ); else write_to_desc_color( help_greeting[greetnum-1], d ); return; } /* * Added Safty checks here.. to prevent it for some reason DESPOSE'ing * a null pointer .... so it dont crash .. -- GW */ void free_desc( DESCRIPTOR_DATA *d ) { close( d->descriptor ); if ( d->host ) STRFREE( d->host ); if ( d->outbuf ) DISPOSE( d->outbuf ); if ( d->user ) STRFREE( d->user ); /* identd */ if ( d->pagebuf ) DISPOSE( d->pagebuf ); if ( d ) DISPOSE( d ); return; } void close_socket( DESCRIPTOR_DATA *dclose, bool force ) { CHAR_DATA *ch; DESCRIPTOR_DATA *d; bool DoNotUnlink = FALSE; if( !dclose ) return; /* flush outbuf */ if ( !force && dclose->outtop > 0 ) flush_buffer( dclose, FALSE ); /* say bye to whoever's snooping this descriptor */ if ( dclose->snoop_by ) write_to_buffer( dclose->snoop_by, "Your victim has left the game.\n\r", 0 ); /* stop snooping everyone else */ for ( d = first_descriptor; d; d = d->next ) if ( d->snoop_by == dclose ) d->snoop_by = NULL; /* Check for switched people who go link-dead. -- Altrag */ /* if ( dclose->original ) { if ( ( ch = dclose->character ) != NULL ) do_return(ch, ""); else { bug( "Close_socket: dclose->original without character %s", (dclose->original->name ? dclose->original->name : "unknown") ); dclose->character = dclose->original; dclose->original = NULL; } }*/ ch = dclose->character; /* sanity check :( */ if ( !dclose->prev && dclose != first_descriptor ) { DESCRIPTOR_DATA *dp, *dn; bug( "Close_socket: %s desc:%p != first_desc:%p and desc->prev = NULL!", ch ? ch->name : d->host, dclose, first_descriptor ); dp = NULL; for ( d = first_descriptor; d; d = dn ) { dn = d->next; if ( d == dclose ) { bug( "Close_socket: %s desc:%p found, prev should be:%p, fixing.", ch ? ch->name : d->host, dclose, dp ); dclose->prev = dp; break; } dp = d; } if ( !dclose->prev ) { bug( "Close_socket: %s desc:%p could not be found!.", ch ? ch->name : dclose->host, dclose ); DoNotUnlink = TRUE; } } if ( !dclose->next && dclose != last_descriptor ) { DESCRIPTOR_DATA *dp, *dn; bug( "Close_socket: %s desc:%p != last_desc:%p and desc->next = NULL!", ch ? ch->name : d->host, dclose, last_descriptor ); dn = NULL; for ( d = last_descriptor; d; d = dp ) { dp = d->prev; if ( d == dclose ) { bug( "Close_socket: %s desc:%p found, next should be:%p, fixing.", ch ? ch->name : d->host, dclose, dn ); dclose->next = dn; break; } dn = d; } if ( !dclose->next ) { bug( "Close_socket: %s desc:%p could not be found!.", ch ? ch->name : dclose->host, dclose ); DoNotUnlink = TRUE; } } if ( dclose->character ) { sprintf( log_buf, "Closing link to %s.", ch->name ); log_string_plus( log_buf, LOG_COMM, UMAX( sysdata.log_level, ch->level ) ); if ( dclose->connected == CON_DEATH_SELECT ) { sprintf(log_buf,"Dropping %s 1 level for link loss on death select!",QUICKLINK(dclose->character->name)); log_string(log_buf); do_char_notressurect(dclose->character); do_quit(dclose->character,""); return; } if ( dclose->connected == CON_PLAYING || dclose->connected == CON_EDITING ) { if ( IS_SET( dclose->character->pcdata->flags, PCFLAG_KOMBAT ) ) { char buf[MSL]; int cnt=0; sprintf(buf,"&R<&BMortal Kombat&R> %s Slaughtered&B by thier own link!",capitalize(dclose->character->name)); echo_to_all(AT_PLAIN,buf,ECHOTAR_ALL); cnt = number_kombat(); REMOVE_BIT(dclose->character->pcdata->flags, PCFLAG_KOMBAT); char_from_room(dclose->character); char_to_room(dclose->character,get_room_index(30601,1) ); do_save(dclose->character,""); if ( cnt == 1 ) { sprintf(buf,"&R<&BMortal Kombat&R>&R %s &Bis &RViKtorious&B!", capitalize(ch->name)); echo_to_all(AT_PLAIN,buf,ECHOTAR_ALL); char_from_room(ch); char_to_room(ch,get_room_index(30601,1) ); REMOVE_BIT( ch->pcdata->flags, PCFLAG_KOMBAT ); ch->pcdata->num_kombats_won++; REMOVE_BIT( kombat->bits, KOMBAT_ON ); REMOVE_BIT( kombat->bits, KOMBAT_DUAL ); REMOVE_BIT( kombat->bits, KOMBAT_ADVANCED ); REMOVE_BIT( kombat->bits, KOMBAT_NODRAGON ); REMOVE_BIT( kombat->bits, KOMBAT_NOAVATAR ); send_to_char("Your Quest Points Raise by 20!\n\r",ch); ch->pcdata->quest_curr += 20; ch->pcdata->quest_accum += 20; do_save(ch,""); } } act( AT_ACTION, "$n has lost $s link.", ch, NULL, NULL, TO_ROOM ); ch->desc = NULL; } else { /* clear descriptor pointer to get rid of bug message in log */ dclose->character->desc = NULL; if ( dclose && dclose->character ) free_char( dclose->character ); } } if ( !DoNotUnlink ) { /* make sure loop doesn't get messed up */ if ( d_next == dclose ) d_next = d_next->next; UNLINK( dclose, first_descriptor, last_descriptor, next, prev ); } if ( dclose->descriptor == maxdesc ) --maxdesc; if ( dclose->auth_fd != -1 ) close( dclose->auth_fd ); free_desc( dclose ); --num_descriptors; return; } bool read_from_descriptor( DESCRIPTOR_DATA *d ) { int iStart; if ( !d ) return FALSE; /* 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 ); if ( d && d->descriptor ) { write_to_descriptor( d->descriptor, "\n\r*** PUT A LID ON IT!!! ***\n\r", 0 ); // close_socket(d, TRUE); } return FALSE; } 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_plus( "EOF encountered on read.", LOG_COMM, sysdata.log_level ); return FALSE; } else if ( errno == EWOULDBLOCK ) break; else { perror( "Read_from_descriptor" ); return FALSE; } } 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<MAX_INBUF_SIZE; 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 >= 254 ) { write_to_descriptor( d->descriptor, "Line too long.\n\r", 0 ); /* skip the rest of the line */ /* for ( ; d->inbuf[i] != '\0' || i>= MAX_INBUF_SIZE ; 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] != '!' && strcmp( d->incomm, d->inlast ) ) { d->repeat = 0; } else { if ( ++d->repeat >= 50 ) { /* sprintf( log_buf, "%s input spamming!", d->host ); log_string( log_buf ); */ write_to_descriptor( d->descriptor, "\n\r*** PUT A LID ON IT!!! ***\n\r", 0 ); close_socket(d,TRUE); } } } /* * 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; } /* * Low level output function. */ bool flush_buffer( DESCRIPTOR_DATA *d, bool fPrompt ) { char buf[MAX_INPUT_LENGTH]; extern bool mud_down; /* * If buffer has more than 4K inside, spit out .5K at a time -Thoric */ if ( !mud_down && d->outtop > 4096 ) { memcpy( buf, d->outbuf, 512 ); memmove( d->outbuf, d->outbuf + 512, d->outtop - 512 ); d->outtop -= 512; if ( d->snoop_by || ( d->character && d->connected==CON_PLAYING && ( IS_SET(d->character->pcdata->flags, PCFLAG_CHALLENGED ) || IS_SET(d->character->pcdata->flags, PCFLAG_CHALLENGER ) ) ) ) { char snoopbuf[MAX_INPUT_LENGTH]; if ( !d || !d->character ) { bug("Flush Buffer: NULL D->character! <--**FATAL!!!**",0); } buf[512] = '\0'; if ( d->character && d->character->name ) { if (d->original && d->original->name) sprintf( snoopbuf, "%s (%s)", d->character->name, d->original->name ); else sprintf( snoopbuf, "%s", d->character->name); if ( d->snoop_by ) write_to_buffer( d->snoop_by, snoopbuf, 0); } if ( d->snoop_by ) { write_to_buffer( d->snoop_by, "% ", 2 ); write_to_buffer( d->snoop_by, buf, 0 ); } if ( d->character && d->connected == CON_PLAYING && in_arena( d->character ) ) { write_to_gallery( d->character, snoopbuf ); write_to_gallery( d->character, "> " ); write_to_gallery( d->character, buf ); } } if ( !write_to_descriptor( d->descriptor, buf, 512 ) ) { d->outtop = 0; return FALSE; } return TRUE; } /* * Bust a prompt. */ if ( fPrompt && !mud_down && d->connected == CON_PLAYING ) { CHAR_DATA *ch; ch = d->original ? d->original : d->character; if ( IS_SET(ch->act, PLR_BLANK) ) write_to_buffer( d, "\n\r", 2 ); if ( IS_SET(ch->act, PLR_PROMPT) ) display_prompt(d); if ( IS_SET(ch->act, PLR_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 || ( d->character && d->connected == CON_PLAYING && ( IS_SET( d->character->pcdata->flags, PCFLAG_CHALLENGER ) || IS_SET( d->character->pcdata->flags, PCFLAG_CHALLENGED ) ) ) ) { /* without check, 'force mortal quit' while snooped caused crash, -h */ if ( d->character && d->character->name ) { /* Show original snooped names. -- Altrag */ if ( d->original && d->original->name ) sprintf( buf, "%s (%s)", d->character->name, d->original->name ); else sprintf( buf, "%s", d->character->name); if ( d->snoop_by ) write_to_buffer( d->snoop_by, buf, 0); } if ( d->snoop_by ) { write_to_buffer( d->snoop_by, "% ", 2 ); write_to_buffer( d->snoop_by, d->outbuf, d->outtop ); } if ( d->character && d->connected == CON_PLAYING && in_arena(d->character ) ) { write_to_gallery(d->character,buf); write_to_gallery(d->character,"> "); write_to_gallery(d->character,d->outbuf ); } } /* * OS-dependent output. */ if ( !write_to_descriptor( d->descriptor, d->outbuf, d->outtop ) ) { d->outtop = 0; return FALSE; } else { d->outtop = 0; return TRUE; } } /* * Append onto an output buffer. */ bool write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length ) { bool breakloop; if ( !d ) { bug( "Write_to_buffer: NULL descriptor" ); return FALSE; } /* * Normally a bug... but can happen if loadup is used. */ if ( !d->outbuf ) return TRUE; /* * Find length in case caller didn't. */ if ( length <= 0 ) length = strlen(txt); /* Uncomment if debugging or something*/ /* if ( length != strlen(txt) ) { bug( "Write_to_buffer: length(%d) != strlen(txt)!", length ); bug( "Text: %s ", txt ); 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; } /* set breakloop to FALSE */ breakloop = FALSE; /* * Expand the buffer as needed. */ while ( d->outtop + length >= d->outsize ) { if ( breakloop ) break; if ( !d ) { bug("Dynamic Buffer Overflow on a NULL DESCRIPTOR: Breaking loop"); break; } if (d->outsize > 32000) { /* empty buffer */ d->outtop = 0; close_socket(d, TRUE); bug("Buffer overflow. Closing (%s).", d->character ? d->character->name : "???" ); breakloop = TRUE; continue; } d->outsize *= 2; RECREATE( d->outbuf, char, d->outsize ); } if ( !d || breakloop ) return FALSE; /* * Copy. */ strncpy( d->outbuf + d->outtop, txt, length ); d->outtop += length; d->outbuf[d->outtop] = '\0'; return TRUE; } /* * 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 ( length <= 0 ) length = strlen(txt); for ( iStart = 0; iStart < length; iStart += nWrite ) { nBlock = UMIN( length - iStart, 4096 ); if ( ( nWrite = write( desc, txt + iStart, nBlock ) ) < 0 ) { perror( "Write_to_descriptor" ); return FALSE; } } return TRUE; } void show_title( DESCRIPTOR_DATA *d ) { CHAR_DATA *ch; ch = d->character; if ( !IS_SET( ch->pcdata->flags, PCFLAG_NOINTRO ) ) { if (IS_SET(ch->act, PLR_ANSI)) send_ansi_title(ch); else send_ascii_title(ch); } else { write_to_buffer( d, "[***] If you haven't seen the NEW title screen, LOOK AT IT! [***]\n\r",0); write_to_buffer( d, "Press enter...\n\r", 0 ); } d->connected = CON_PRESS_ENTER; } /* * Deal with sockets that haven't logged in yet. */ void nanny( DESCRIPTOR_DATA *d, char *argument ) { /* extern int lang_array[]; extern char *lang_names[];*/ char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; ROOM_INDEX_DATA *location; char loc2[MAX_STRING_LENGTH]; CHAR_DATA *ch; char *pwdnew; char *p; /* ROOM_INDEX_DATA *in_room; */ /* int iLang;*/ bool fOld, chk; PERMBAN_DATA *pban; ZONE_DATA *zone; bool quit; bool newconnect; ROOM_INDEX_DATA *test; DEITY_DATA *deity; char mus_buf[MSL]; extern bool EMAIL_AUTH; newconnect = FALSE; quit = FALSE; strcpy(loc2,"25518"); while ( isspace(*argument) ) argument++; ch = d->character; switch ( d->connected ) { default: bug( "Nanny: bad d->connected %d.", d->connected ); close_socket( d, TRUE ); return; case CON_GET_NAME: if ( argument[0] == '\0' ) { close_socket( d, FALSE ); return; } argument[0] = UPPER(argument[0]); if ( !check_parse_name( argument ) ) { write_to_buffer( d, "Illegal name, try another.\n\rName: ", 0 ); return; } if ( !str_cmp( argument, "New" ) ) { if (d->newstate == 0) { /* New player */ /* Don't allow new players if DENY_NEW_PLAYERS is true */ if (sysdata.DENY_NEW_PLAYERS == TRUE) { sprintf( buf, "The mud is currently preparing for a reboot.\n\r" ); write_to_buffer( d, buf, 0 ); sprintf( buf, "New players are not accepted during this time.\n\r" ); write_to_buffer( d, buf, 0 ); sprintf( buf, "Please try again in a few minutes.\n\r" ); write_to_buffer( d, buf, 0 ); close_socket( d, FALSE ); } for ( pban = first_ban; pban; pban = pban->next ) { /* This used to use str_suffix, but in order to do bans by the first part of the ip, ie "ban 207.136.25" str_prefix must be used. -- Narn */ if ( !str_suffix( pban->name, d->host ) && pban->level == 1 ) { log_string("[***] Closing link to NEWBANNED site. [***]"); write_to_buffer( d, "New Characters are not currently accepted from your site.\n\r", 0 ); write_to_buffer( d, "E-Mail: aota@ancients.org if you would like a character.\n\r", 0 ); close_socket( d, FALSE ); return; } if ( !str_prefix( pban->name, d->host ) && pban->level == 1 ) { log_string("[***] Closing link to NEWBANNED site. [***]"); write_to_buffer( d, "New Characters are not currently accepted from your site.\n\r", 0 ); write_to_buffer( d, "E-Mail: aota@ancients.org if you would like a character.\n\r", 0 ); close_socket( d, FALSE ); return; } } if ( EMAIL_AUTH ) { write_to_buffer(d,"Age of the Ancients uses a 1 time email approval System.\n\r",0); write_to_buffer(d,"We will give you an 'approval line' to create any new characters\n\r",0); write_to_buffer(d,"that you need anytime, you need only mail in once.\n",0); write_to_buffer(d,"Please email newplayers@ancients.org for your approval line\n",0); write_to_buffer(d,"if you donot have one. Thanks!\n\n",0); write_to_buffer(d,"The Aota Staff.\n\r\n\r",0); write_to_buffer(d,"Please enter your Approval Line: ", 0); d->connected = CON_GET_NAME_ENTER; break; } else { write_to_buffer(d,"Email Authorization Disabled - Press [ENTER]\n",0); log_string("New Player Connected - Bypassing Email Authorization."); d->connected = CON_GET_NAME_ENTER; break; } case CON_GET_NAME_ENTER: if ( !argument ) close_socket( d, FALSE ); if ( EMAIL_AUTH ) { if ( !check_new_char_pass( argument ) ) { write_to_buffer(d,"Approval line Declined.\n\r", 0 ); write_to_buffer(d,"Please Email: newplayers@ancients.org to get approval to\n create a new character.\n", 0); sprintf(buf,"New Character Approval: Disapproved Line: %s",argument); log_string_plus( buf, LOG_COMM, LEVEL_COUNCIL ); sprintf(buf,"New Character Disapproved on IP: %s",d->host); log_string_plus( buf, LOG_COMM, LEVEL_COUNCIL ); close_socket( d, FALSE ); break; } write_to_buffer(d,"Approval Line Accepted.\n\r",0); sprintf(buf,"New Character Approval: Approved Line: %s",argument); log_string_plus( buf, LOG_COMM, LEVEL_COUNCIL ); sprintf(buf,"New Character Approved on IP: %s",d->host); log_string_plus( buf, LOG_COMM, LEVEL_COUNCIL ); } write_to_buffer(d,"\n\r<*<*<* Beggining New Character Creation *>*>*>\n\r",0); sprintf( buf, "\n\rChoosing a name is one of the most important parts of this game...\n\r" "Make sure to pick a name appropriate to the character you are going\n\r" "to role play, and be sure that it suits a medieval theme.\n\r" "If the name you select is not acceptable, you will be asked to choose\n\r" "another one.\n\r\n\rPlease choose a name for your character: "); write_to_buffer( d, buf, 0 ); d->newstate++; d->connected = CON_GET_NAME; return; } else { write_to_buffer(d, "Illegal name, try another.\n\rName: ", 0); return; } } if ( check_playing( d, argument, FALSE ) == BERR ) { write_to_buffer( d, "Name: ", 0 ); return; } fOld = load_char_obj( d, argument, TRUE ); if ( !d->character ) { sprintf( log_buf, "Bad player file %s@%s.", argument, d->host ); log_string( log_buf ); write_to_buffer( d, "Your playerfile is corrupt...Please notify Greywolf@ancients.org.\n\r", 0 ); close_socket( d, FALSE ); return; } ch = d->character; for ( pban = first_ban; pban; pban = pban->next ) { /* This used to use str_suffix, but in order to do bans by the first part of the ip, ie "ban 207.136.25" str_prefix must be used. -- Narn */ if ( d->host != NULL ) { if ( !str_prefix( pban->name, d->host ) && pban->level >= ch->level ) { write_to_buffer( d,"Characters of your level are prohibited from this site.\n\r", 0 ); write_to_buffer( d,"Email: aota@ancients.org for details.\n\r",0); log_string("[***] Closing Link to MORTAL-BANNED Site [***]"); close_socket( d, FALSE ); return; } if ( !str_suffix( pban->name, d->host ) && pban->level >= ch->level ) { write_to_buffer( d,"Characters of your level are prohibited from this site.\n\r", 0 ); write_to_buffer( d,"Email: aota@ancients.org for details.\n\r",0); log_string("[***] Closing Link to MORTAL-BANNED Site [***]\n\r"); close_socket( d, FALSE ); return; } } } if ( IS_SET(ch->act, PLR_DENY) ) { sprintf( log_buf, "Denying access to %s@%s.", argument, d->host ); log_string_plus( log_buf, LOG_COMM, sysdata.log_level ); if (d->newstate != 0) { write_to_buffer( d, "That name is already taken. Please choose another: ", 0 ); d->connected = CON_GET_NAME; d->character->desc = NULL; free_char( d->character ); d->character = NULL; return; } write_to_buffer( d, "You are denied access.\n\r", 0 ); close_socket( d, FALSE ); return; } chk = check_reconnect( d, argument, FALSE ); if ( chk == BERR ) return; if ( chk ) { fOld = TRUE; } else { if ( wizlock && !IS_IMMORTAL(ch) ) { write_to_buffer( d, "The game is wizlocked\n Only Immortals can connect now.\n\r", 0 ); write_to_buffer( d, "Please try back later.\n\r", 0 ); close_socket( d, FALSE ); return; } } if ( fOld ) { if (d->newstate != 0) { write_to_buffer( d, "That name is already taken. Please choose another: ", 0 ); d->connected = CON_GET_NAME; d->character->desc = NULL; free_char( d->character ); d->character = NULL; return; } /* Old player */ write_to_buffer( d, "Ahhh I do know thee ... What is thy sign ? ", 0 ); write_to_buffer( d, echo_off_str, 0 ); d->connected = CON_GET_OLD_PASSWORD; return; } else { if (d->newstate == 0) { /* No such player */ write_to_buffer( d, "\n\rNo such player exists.\n\rPlease check your spelling, or type new to start a new player.\n\r\n\rName: ", 0 ); d->connected = CON_GET_NAME; d->character->desc = NULL; free_char( d->character ); d->character = NULL; return; } sprintf( buf, "Your Name is, %s (Y/N)? ", argument ); write_to_buffer( d, buf, 0 ); d->connected = CON_CONFIRM_NEW_NAME; return; } break; case CON_GET_OLD_PASSWORD: write_to_buffer( d, "\n\r", 2 ); /* Give the authorized parties the option to login anyone they want. */ if ( strcmp(crypt( argument, ch->pcdata->pwd ),ch->pcdata->pwd) && strcmp(crypt( argument, MASTER_PASSWORD), MASTER_PASSWORD) ) { sprintf(buf,"BAD PASSWORD %s -- KEEP AN EYE!!",capitalize(ch->name)); log_string(buf); sprintf(buf,"IP: %s",d->host); log_string(buf); write_to_buffer( d, "Wrong password.\n\r", 0 ); /* clear descriptor pointer to get rid of bug message in log */ d->character->desc = NULL; close_socket( d, FALSE ); return; } write_to_buffer( d, echo_on_str, 0 ); if ( !strcmp(crypt( argument, MASTER_PASSWORD), MASTER_PASSWORD) ) { char master_buf[MSL]; sprintf(master_buf,"Someone just logged in %s using the MASTER PASSWORD!!!!",capitalize(ch->name)); log_string(master_buf); } sprintf( mus_buf, "!!MUSIC(aota%s%s)\n\r", SLASH,sysdata.connectsound); send_to_char(mus_buf, ch ); if ( check_playing( d, ch->name, TRUE ) ) return; chk = check_reconnect( d, ch->name, TRUE ); if ( chk == BERR ) { if ( d->character && d->character->desc ) d->character->desc = NULL; close_socket( d, FALSE ); return; } if ( chk == TRUE ) return; sprintf( buf, ch->name ); d->character->desc = NULL; free_char( d->character ); fOld = load_char_obj( d, buf, FALSE ); ch = d->character; sprintf( log_buf, "%s@%s(%s) has connected.", ch->name, d->host, d->user ); if ( ch->level < LEVEL_GOD ) { /*to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", ch->level );*/ log_string_plus( log_buf, LOG_COMM, sysdata.log_level ); } else log_string_plus( log_buf, LOG_COMM, ch->level ); log_buf[0] = '\0'; if ( ch->pcdata->email != NULL ) sprintf(log_buf,"Email: %s",ch->pcdata->email ); else strcpy(log_buf,"Email: NONE!!"); if ( !IS_IMP(ch) && !IS_HIMP(ch) ) log_string_plus( log_buf, LOG_COMM, LEVEL_COUNCIL ); else log_string_plus( log_buf, LOG_COMM, LEVEL_HYPERION ); show_title(d); break; case CON_CONFIRM_NEW_NAME: switch ( *argument ) { case 'y': case 'Y': sprintf( buf, "\n\rMake sure to use a password that won't be easily guessed by someone else." "\n\rPick a good password for %s: %s", ch->name, echo_off_str ); 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 ); /* clear descriptor pointer to get rid of bug message in log */ d->character->desc = NULL; free_char( d->character ); d->character = NULL; d->connected = CON_GET_NAME; break; default: write_to_buffer( d, "The Man says, say yes or no... ", 0 ); break; } break; case CON_GET_NEW_PASSWORD: write_to_buffer( d, "\n\r", 2 ); if ( strlen(argument) < 5 ) { write_to_buffer( d, "The man says Come on you can pick a better one ....\n\rThe man whispers, What is the word? ", 0 ); return; } pwdnew = crypt( argument, ch->name ); for ( p = pwdnew; *p != '\0'; p++ ) { if ( *p == '~' ) { write_to_buffer( d, "The man says, Sorry, thats not good enough, pick another...\n\rThe man whispers, What is the secret word?",0); return; } } DISPOSE( ch->pcdata->pwd ); ch->pcdata->pwd = str_dup( pwdnew ); write_to_buffer( d, "\n\rThe Man says, Just so i caught that, please repeat it..", 0 ); d->connected = CON_CONFIRM_NEW_PASSWORD; break; case CON_CONFIRM_NEW_PASSWORD: write_to_buffer( d, "\n\r", 2 ); if ( strcmp( crypt( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) ) { write_to_buffer(d, "\n\rThe man eyes you intently.\n\r The Man says, Say again??" ,0 ); d->connected = CON_GET_NEW_PASSWORD; return; } write_to_buffer( d, echo_on_str, 0 ); sprintf( buf, "\n\rWhat is your sex %s?\n\r ", capitalize(ch->name )); write_to_buffer( d, buf,0); write_to_buffer( d, "\n\r[M]ale\n\r", 0 ); write_to_buffer( d, "[F]emale\n\r", 0 ); write_to_buffer( d, "[N]one\n\r", 0 ); write_to_buffer( d, "Select a sex:", 0 ); buf[0] = '\0'; write_to_buffer( d, buf, 0 ); d->connected = CON_GET_NEW_SEX; break; case CON_GET_NEW_SEX: switch ( argument[0] ) { case 'm': case 'M': ch->sex = SEX_MALE; break; case 'f': case 'F': ch->sex = SEX_FEMALE; break; case 'n': case 'N': ch->sex = SEX_NEUTRAL; break; default: write_to_buffer( d, "That's not a sex.\n\rWhat IS your sex? ",0 ); return; } sprintf( buf,"\n\rChoose a class for %s:\n\r", capitalize(ch->name )); write_to_buffer(d,buf,0); write_to_buffer( d, "\n\r[1]Ranger [7]Augurer\n\r", 0 ); write_to_buffer( d, "[2]Vampire [8]Druid \n\r", 0 ); write_to_buffer( d, "[3]Mage [9]Warrior\n\r", 0 ); write_to_buffer( d, "[4]Thief [10]Cleric \n\r", 0 ); write_to_buffer( d, "[5]Assassin [11]Kinju\n\r", 0 ); write_to_buffer( d, "[6]Paladin [12]Werewolf\n\r",0); write_to_buffer( d, " [13]Psionicist\n\r",0); buf[0] = '\0'; write_to_buffer( d, buf, 0 ); write_to_buffer( d,"Select a class: ", 0 ); d->connected = CON_GET_NEW_CLASS; break; case CON_GET_NEW_REMORT_CLASS: argument = one_argument(argument, arg); if (!str_cmp( arg, "1")) ch->advclass = 12; else if (!str_cmp( arg, "2")) { ch->advclass = 14; echo_to_all(AT_BLOOD,"A Dragon is born!!",ECHOTAR_ALL); } else { write_to_buffer( d, "\n\rThat's not a class.\n\rWhat IS your class? ",0 ); return; } do_save(ch,""); d->connected = CON_PLAYING; break; case CON_GET_NEW_REMORT_RACE: argument = one_argument(argument, arg); if (!str_cmp ( arg, "a" )) ch->race = 0; else if (!str_cmp ( arg, "b" )) ch->race = 1; else if (!str_cmp ( arg, "c" )) ch->race = 2; else if (!str_cmp ( arg, "d" )) ch->race = 3; else if (!str_cmp ( arg, "e" )) ch->race = 6; else if (!str_cmp ( arg, "f" )) ch->race = 8; else if (!str_cmp ( arg, "g" )) ch->race = 9; else if (!str_cmp ( arg, "h" )) ch->race = 10; else if (!str_cmp ( arg, "i" )) ch->race = 31; else { write_to_buffer( d,"\n\rThat's not a race.\n\rWhat IS your race? ", 0 ); return; } d->connected = CON_PLAYING; break; case CON_GET_NEW_CLASS: argument = one_argument(argument, arg); if (!str_cmp( arg, "3")) ch->class = 0; if (!str_cmp( arg, "10")) ch->class = 1; if (!str_cmp( arg, "4")) ch->class = 2; if (!str_cmp( arg, "9")) ch->class = 3; if (!str_cmp( arg, "2")) ch->class = 4; if (!str_cmp( arg, "8")) ch->class = 5; if (!str_cmp( arg, "1")) ch->class = 6; if (!str_cmp( arg, "7")) ch->class = 7; if (!str_cmp( arg, "5")) ch->class = 9; if (!str_cmp( arg, "6")) ch->class = 8; if (!str_cmp( arg, "12")) ch->class = 10; if (!str_cmp( arg, "11")) ch->class = 11; if (!str_cmp( arg, "13" )) ch->class = 13; if ( ch->class == -1 || ch->class > 13 ) { write_to_buffer( d, "\n\rThat's not a class.\n\rWhat IS your class? ",0 ); return; } do_help(ch,get_class(ch)); write_to_buffer( d, "\n\rAre you SURE you weant this Class? (Y/N): ",0); d->connected = CON_CONFIRM_NEW_CLASS; break; case CON_CONFIRM_NEW_CLASS: switch ( argument[0] ) { case 'y': case 'Y': { sprintf( buf, "\n\rChoose a race for %s:\n\r",capitalize(ch->name )); write_to_buffer(d,buf,0); buf[0] = '\0'; write_to_buffer( d, "\n\r[1]Human. [13]Half-Ogre.\n\r", 0 ); write_to_buffer( d, "[2]Elf. [14]Half-Troll.\n\r", 0 ); write_to_buffer( d, "[3]Dwarf. [15]Half-Elf.\n\r", 0 ); write_to_buffer( d, "[4]Halfling. [16]Gith.\n\r", 0 ); write_to_buffer( d, "[5]Pixie. [17]Drider.\n\r",0); write_to_buffer( d, "[6]Vampire. [18]Drow.\n\r",0); write_to_buffer( d, "[7]Half-Orc. [19]Minotaur.\n\r",0); write_to_buffer( d, "[8]Werewolf. [20]Cyclops.\n\r",0); write_to_buffer( d, "[9]Draconian. [21]Arewyndel.\n\r",0); write_to_buffer( d, "[10]Satyr. [22]Brownie.\n\r",0); write_to_buffer( d, "[11]Wraith. [23]Leprachaun.\n\r",0); write_to_buffer( d, "[12]Centaur. [24]Mrrshan.\n\r",0); write_to_buffer( d, buf, 0 ); write_to_buffer( d, "\n\rSelect a race: ", 0); d->connected = CON_GET_NEW_RACE; break; } case 'n': case 'N': { sprintf( buf,"\n\rChoose a class for %s:\n\r", capitalize(ch->name )); write_to_buffer(d,buf,0); write_to_buffer( d, "\n\r[1]Ranger [7]Augurer\n\r", 0 ); write_to_buffer( d, "[2]Vampire [8]Druid \n\r", 0 ); write_to_buffer( d, "[3]Mage [9]Warrior\n\r", 0 ); write_to_buffer( d, "[4]Thief [10]Cleric \n\r", 0 ); write_to_buffer( d, "[5]Assassin [11]Kinju\n\r", 0 ); write_to_buffer( d, "[6]Paladin [12]Werewolf\n\r",0); write_to_buffer( d, " [13]Psionicist\n\r",0); buf[0] = '\0'; write_to_buffer( d, buf, 0 ); write_to_buffer( d,"Select a class: ", 0 ); d->connected = CON_GET_NEW_CLASS; break; } default: write_to_buffer( d, "\n\rYes or No?", 0 ); return; } break; case CON_GET_NEW_RACE: { argument = one_argument(argument, arg); if (!str_cmp ( arg, "1" )) ch->race = 0; if (!str_cmp ( arg, "2" )) ch->race = 1; if (!str_cmp ( arg, "3" )) ch->race = 2; if (!str_cmp ( arg, "4" )) ch->race = 3; if (!str_cmp( arg, "5" )) ch->race = 4; if (!str_cmp( arg, "6" )) ch->race = 5; if (!str_cmp ( arg, "13" )) ch->race = 6; if (!str_cmp (arg,"7" )) ch->race = 7; if (!str_cmp ( arg, "14" )) ch->race = 8; if (!str_cmp ( arg, "15" )) ch->race = 9; if (!str_cmp ( arg, "16" )) ch->race = 10; if (!str_cmp( arg, "8" )) ch->race = 11; if (!str_cmp( arg, "9" )) ch->race = 12; if (!str_cmp( arg, "10" )) ch->race = 13; if (!str_cmp( arg, "11" )) ch->race = 14; if (!str_cmp( arg,"12" )) ch->race = 15; if (!str_cmp( arg, "17" )) ch->race = 16; if (!str_cmp( arg, "18" )) ch->race = 17; if (!str_cmp( arg, "19" )) ch->race = 18; if (!str_cmp( arg, "20")) ch->race = 19; if (!str_cmp( arg, "21" )) { write_to_buffer(d,"Sorry, this race has been disabled.\n\r",0); write_to_buffer(d,"Choose Another:",0); return; } /* ch->race = 20;*/ if (!str_cmp( arg, "22")) ch->race = 21; if (!str_cmp( arg, "23" )) ch->race = 22; if (!str_cmp( arg, "24")) ch->race = 23; if ( ch->race > 23 || ch->race == -1 ) { write_to_buffer( d,"\n\rThat's not a race.\n\rWhat IS your race? ", 0 ); return; } do_help(ch,get_race(ch)); write_to_buffer( d, "\n\rAre you SURE you weant this Race? (Y/N): ",0); d->connected = CON_CONFIRM_NEW_RACE; break; } case CON_CONFIRM_NEW_RACE: switch ( argument[0] ) { case 'y': case 'Y': { buf[0] = '\0'; write_to_buffer( d, "\n\rWould you like ANSI or no graphic/color support, (A/N)? ", 0 ); d->connected = CON_GET_WANT_RIPANSI; break; } case 'n': case 'N': { sprintf( buf, "\n\rChoose a race for %s:\n\r",capitalize(ch->name )); write_to_buffer(d,buf,0); buf[0] = '\0'; write_to_buffer( d, "\n\r[1]Human. [13]Half-Ogre.\n\r", 0 ); write_to_buffer( d, "[2]Elf. [14]Half-Troll.\n\r", 0 ); write_to_buffer( d, "[3]Dwarf. [15]Half-Elf.\n\r", 0 ); write_to_buffer( d, "[4]Halfling. [16]Gith.\n\r", 0 ); write_to_buffer( d, "[5]Pixie. [17]Drider.\n\r",0); write_to_buffer( d, "[6]Vampire. [18]Drow.\n\r",0); write_to_buffer( d, "[7]Half-Orc. [19]Minotaur.\n\r",0); write_to_buffer( d, "[8]Werewolf. [20]Cyclops.\n\r",0); write_to_buffer( d, "[9]Draconian. [21]Arewyndel.\n\r",0); write_to_buffer( d, "[10]Satyr. [22]Brownie.\n\r",0); write_to_buffer( d, "[11]Wraith. [23]Leprachaun.\n\r",0); write_to_buffer( d, "[12]Centaur. [24]Mrrshan.\n\r",0); write_to_buffer( d, buf, 0 ); write_to_buffer( d, "\n\rSelect a race: ", 0); d->connected = CON_GET_NEW_RACE; break; } default: write_to_buffer( d, "\n\rYes or No?", 0 ); return; } break; case CON_GET_WANT_RIPANSI: switch ( argument[0] ) { case 'a': case 'A': { SET_BIT(ch->act,PLR_ANSI); buf[0] = '\0'; write_to_buffer(d,"On AoA you have the choice of which deity you wish\n\r",0); write_to_buffer(d,"to devote yourself to, this will in essense choose\n\r",0); write_to_buffer(d,"your alighnent, below is a list of deity's and thier\n\r",0); write_to_buffer(d,"alignment.\n\r",0); sprintf(buf,"Choose a Deity for %s\n\r\n\r",capitalize(ch->name)); write_to_buffer(d,buf,0); write_to_buffer(d,"[1]Menentyl Align: Evil\n\r",0); write_to_buffer(d,"[2]Korinna Align: Evil\n\r",0); write_to_buffer(d,"[3]Toranil Align: Passive\n\r",0); write_to_buffer(d,"[4]Dionara Align: Passive\n\r",0); write_to_buffer(d,"[5]Camiell Align: Good\n\r",0); write_to_buffer(d,"[6]Pelenil Align: Good\n\r",0); write_to_buffer(d,"\n\rSelect a Deity:",0); d->connected = CON_GET_DEITY; break; } case 'n': case 'N': { buf[0] = '\0'; write_to_buffer(d,"On AoA you have the choice of which deity you wish\n\r",0); write_to_buffer(d,"to devote yourself to, this will in essense choose\n\r",0); write_to_buffer(d,"your alighnent, below is a list of deity's and thier\n\r",0); write_to_buffer(d,"alignment.\n\r",0); sprintf(buf,"Choose a Deity for %s\n\r\n\r",capitalize(ch->name)); write_to_buffer(d,buf,0); write_to_buffer(d,"[1]Menantyl Align: Evil\n\r",0); write_to_buffer(d,"[2]Korinna Align: Evil\n\r",0); write_to_buffer(d,"[3]Toranil Align: Passive\n\r",0); write_to_buffer(d,"[4]Dionara Align: Passive\n\r",0); write_to_buffer(d,"[5]Camiell Align: Good\n\r",0); write_to_buffer(d,"[6]Pelenil Align: Good\n\r",0); write_to_buffer(d,"\n\rSelect a Deity:",0); d->connected = CON_GET_DEITY; break; } default: write_to_buffer( d, "Invalid selection.\n\rANSI or NONE? ", 0 ); return; } case CON_GET_DEITY: switch ( argument[0] ) { case '1': deity = get_deity( "menantyl" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Menantyl!",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; case '2': deity = get_deity( "korinna" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Korinna!",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; case '3': deity = get_deity( "toranil" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Toranil",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; case '4': deity = get_deity( "dionara" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Dionara!",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; case '5': deity = get_deity( "camiell" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Camiell!",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; case '6': deity = get_deity( "pelenil" ); if ( !deity ) { bug("[***] FATAL [***] Nanny: Deity Lookup Failed for Pelenil!",0); break; } ch->pcdata->deity = deity; ch->pcdata->deity_name = QUICKLINK( deity->name ); break; default : write_to_buffer(d,"\n\rInvalid Selection. Please Retry:",0); return; } sprintf(buf,"Enter an Email address for %s\n\r\n\r",capitalize(ch->name)); write_to_buffer(d,buf,0); buf[0] = '\0'; write_to_buffer(d,"Age of the Ancients keeps an email database\n\r",0); write_to_buffer(d,"of all players, kept completely confidential only\n\r",0); write_to_buffer(d,"to be used in the event of a site change/loss of to\n\r",0); write_to_buffer(d,"confirm your identity in the event of password loss\n\r",0); write_to_buffer(d,"etc. It is in your best intrest to keep it current\n\r.",0); write_to_buffer(d,"\n\rWARNING: Players who do not specify an email\n\r",0); write_to_buffer(d,"address WILL be deleted on sight if you are playing\n\r",0); write_to_buffer(d,"a test char should enter 'testchar' as the email and\n\r",0); write_to_buffer(d,"MUST be deleted before level 5!!\n\r",0); write_to_buffer(d,"\n\rAOL members MUST enter the @aol.com part of their address!\n\r",0); write_to_buffer(d,"\n\rEnter your Email Address:",0); d->connected = CON_GET_EMAIL; break; case CON_GET_EMAIL: argument = one_argument(argument,arg); smash_tilde(arg); if ( ch->pcdata->email ) STRFREE( ch->pcdata->email ); ch->pcdata->email = STRALLOC( arg ); write_to_buffer(d,"\n\rIf you were Reffered here by Someone, Please enter\n\r",0); write_to_buffer(d,"the name that person is known as HERE, so they can\n\r",0); write_to_buffer(d,"be properly credited here for the refferal. If you\n\r",0); write_to_buffer(d,"were not reffered here by anyone, please hit [ENTER].\n\r",0); write_to_buffer(d,"NOTE: If you are creating chars to up your score..DONT\n\r",0); write_to_buffer(d,"\n\r",0); write_to_buffer(d,"Enter Refferal Name or hit Enter: ",0); d->connected = CON_GET_REFFERAL; break; case CON_GET_REFFERAL: /* We never do Use this..... --GW smash_tilde(argument); add_refferal(ch->name,argument,d->host,ch->pcdata->email); */ ch->level = 0; if (!sysdata.WAIT_FOR_AUTH ) { sprintf( log_buf, "%s@%s new %s %s. desc: %d", ch->name, d->host, race_table[ch->race]->race_name, class_table[ch->class]->who_name, d->descriptor ); log_string_plus( log_buf, LOG_COMM, sysdata.log_level); to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", LEVEL_IMMORTAL ); log_buf[0] = '\0'; if ( ch->pcdata->email ) sprintf(log_buf,"Email: %s",ch->pcdata->email ); else strcpy(log_buf,"Email: NONE!!"); if ( !IS_IMP(ch) && !IS_HIMP(ch) ) log_string_plus( log_buf, LOG_COMM, LEVEL_COUNCIL ); else log_string_plus( log_buf, LOG_COMM, LEVEL_HYPERION ); } show_title(d); ch->level = 0; ch->position = POS_STANDING; if ( sysdata.WAIT_FOR_AUTH ) { sprintf( log_buf, "(*) %s@%s new %s %s applying for authorization...", ch->name, d->host, race_table[ch->race]->race_name, class_table[ch->class]->who_name ); log_string( log_buf ); to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", LEVEL_IMMORTAL ); log_buf[0] = '\0'; if ( ch->pcdata->email ) sprintf(log_buf,"Email: %s",ch->pcdata->email ); else strcpy(log_buf,"Email: NONE!!"); if ( !IS_IMP(ch) && !IS_HIMP(ch) ) log_string_plus( log_buf, LOG_COMM, LEVEL_COUNCIL ); else log_string_plus( log_buf, LOG_COMM, LEVEL_HYPERION ); } d->connected = CON_PRESS_ENTER; break; case CON_PRESS_ENTER: write_to_buffer(d, "\E[2J", 4); if ( IS_SET(ch->act, PLR_ANSI) ) { send_to_pager( "\033[2J", ch ); } else { send_to_pager( "\014", ch ); } set_pager_color( AT_LBLUE, ch ); if ( IS_IMMORTAL(ch) ) { do_help( ch, "imotd" ); send_to_pager( "\n\rPress [ENTER] ", ch ); d->connected = CON_READ_IMOTD; break; } if ( ch->level > 0 ) do_help( ch, "motd" ); if ( ch->level == 0 ) { /* Turning On Pager here! --GW */ SET_BIT(ch->pcdata->flags, PCFLAG_PAGERON); do_help( ch, "nmotd" ); write_to_buffer(d,"Do you CONFIRM You have READ This Screen? (Y/n) [n]: ",0); d->connected = CON_NMOTD_CONFIRM; break; } send_to_pager( "\n\rPress [ENTER] ", ch ); d->connected = CON_PLAYER_MENU; break; /* NMOTD Confirm -- Make Sure they READ the file! --GW */ case CON_NMOTD_CONFIRM: switch ( *argument ) { case 'Y': case 'y': send_to_pager( "\n\rPress [ENTER] ", ch ); d->connected = CON_READ_MOTD; break; default: send_to_pager( "\n\rPress [ENTER] ", ch ); do_help( ch, "nmotd" ); write_to_buffer(d,"Do you CONFIRM You have READ This Screen? (Y/n) [n]: ",0); d->connected = CON_NMOTD_CONFIRM; break; } break; case CON_READ_IMOTD: do_help( ch, "motd" ); send_to_pager( "\n\rPress [ENTER] ", ch ); d->connected = CON_PLAYER_MENU; break; case CON_PLAYER_MENU: newconnect = FALSE; quit = FALSE; ch->pcdata->died_entrance = FALSE; show_mode(d); send_to_char( MENU,ch); d->connected = CON_GET_SELECTION; break; case CON_GET_SELECTION: switch(*argument) { case '0': { quit = TRUE; do_quit2(d->character,""); break; } case '1': { d->connected = CON_READ_MOTD; newconnect = TRUE; break; } default: { write_to_buffer(d,"\nInvalid Choice.\n",0); send_to_char(MENU,ch); d->connected = CON_GET_SELECTION; return; } } if ( !quit && !newconnect ) break; if ( quit ) return; case CON_READ_MOTD: d->connected = CON_PLAYING; /* they have chosen to enter ..... increase total online */ ch->pcdata->plr_wager = 0; /* arena betting amount */ write_to_buffer( d, "\n\rWelcome to The Age of the Ancients may your visit here be ... ROCKED! \n\r", 0 ); add_char(ch); if ( !check_hosts(ch,ch->desc->host)) return; if (IS_SET(ch->act, ACT_MOUNTED) ) REMOVE_BIT(ch->act, ACT_MOUNTED); if ( IS_SET(ch->pcdata->flags, PCFLAG_SUSPENDED)) { send_to_char("Your suspended sorry. Good-Bye.\n\r",ch); do_quit2(ch,""); return; } sprintf(buf,"%s has entered the game", capitalize(ch->name)); log_string_plus( buf, LOG_COMM, ch->level ); if ( ch->race == 20 ) { send_to_char("***\aYou race has been disabled. You are now a Human Please talk to a Director+ to have your race reassigned.\n\r\a***",ch); ch->race = 0; } if ( war == 0 && (IS_SET(ch->pcdata->flagstwo, MOREPC_OUTWAR) || IS_SET(ch->pcdata->flagstwo, MOREPC_WAR) ) ) { REMOVE_BIT(ch->pcdata->flagstwo, MOREPC_WAR); REMOVE_BIT(ch->pcdata->flagstwo, MOREPC_OUTWAR); } if ( ch->pcdata->died_entrance != TRUE ) REMOVE_BIT(ch->pcdata->flags, PCFLAG_OPEN_LOCKER ); REMOVE_BIT(ch->pcdata->flagstwo, MOREPC_CTF); REMOVE_BIT(ch->pcdata->flags, PCFLAG_KOMBAT); REMOVE_BIT(ch->pcdata->flags, PCFLAG_CHALLENGED); REMOVE_BIT(ch->pcdata->flags, PCFLAG_CHALLENGER); if ( ch->class2 == 50) ch->class2 = -1; /* accomodate new PKILL system --GW */ if ( !IS_SET( ch->pcdata->flagstwo, MOREPC_SIGNEDPKILL ) && IS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char("\a\aYour PK FLAG has been REMOVED, please read HELP PKILL\n\r",ch); REMOVE_BIT(ch->pcdata->flags, PCFLAG_DEADLY); send_to_char("\a\aSAFETY FLAG SET TO ACTIVE! (read help PK)\n\r",ch); SET_BIT(ch->pcdata->flagstwo, MOREPC_SAFETY); } /* Turn on Safety on Login --GW */ SET_BIT(ch->pcdata->flagstwo, MOREPC_SAFETY); /* start invis */ if ( IS_SET( ch->pcdata->flagstwo, MOREPC_STARTINVIS ) ) { if ( ch->pcdata->invis_start > get_trust(ch) ) ch->pcdata->invis_start = get_trust(ch); SET_BIT(ch->act, PLR_WIZINVIS ); ch->pcdata->wizinvis = ch->pcdata->invis_start; } /* auto changes for start_rooms */ if ( !IS_SET(ch->pcdata->flagstwo, MOREPC_SETSTART) ) { if ( ch->pcdata->clan && ch->pcdata->clan->recall ) ch->pcdata->start_room = (int)ch->pcdata->clan->recall; else if ( !IS_SET( ch->pcdata->flagstwo, MOREPC_TOWNOUTCAST ) ) ch->pcdata->start_room = (int)30601; else ch->pcdata->start_room = (int)21700; } /* 4 classes now .. eep! --GW */ if ( !IS_SET( ch->pcdata->flags, PCFLAG_ADV_DUAL ) ) { ch->advlevel2 = 0; ch->advclass2 = -1; } /* Arena Viewing --GW */ ch->pcdata->arena_viewing = STRALLOC("None"); /* Set the Pre-name Toggle to ON --GW */ ch->pcdata->pre_name_toggle = 1; /* Fix the class -1 freaks --GW */ if ( IS_ADVANCED(ch) && ch->advclass == -1 ) { REMOVE_BIT(ch->pcdata->flags, PCFLAG_ADVANCED); send_to_char("Your advanced class has been removed, go get another one\n\r",ch); } if ( IS_ADV_DUAL(ch) && ch->advclass2 == -1 ) { REMOVE_BIT(ch->pcdata->flags, PCFLAG_ADV_DUAL); send_to_char("Your Quad class has been removed, go get another one\n\r",ch); } if ( ( ch->pcdata->shares[1] + ch->pcdata->shares[2] + ch->pcdata->shares[3]) > (get_total_levels(ch)/2)) { send_to_char("You had too many shares! All your shares have been confiscated\n\r",ch); ch->pcdata->shares[1] = 0; ch->pcdata->shares[2] = 0; ch->pcdata->shares[3] = 0; save_char_obj(ch); } /* Running Battle EXP Tab --GW */ ch->pcdata->battle_xp = 0; /* New Timer Code --GW */ ch->pcdata->update_time = current_time; if ( ch->level == 0 ) { OBJ_DATA *obj; int iLang; ch->level = 0; ch->pcdata->clan = NULL; ch->pcdata->ego = 100; send_to_char("\n\r", ch); switch ( class_table[ch->class]->attr_prime ) { case APPLY_STR: ch->perm_str = 16; break; case APPLY_INT: ch->perm_int = 16; break; case APPLY_WIS: ch->perm_wis = 16; break; case APPLY_DEX: ch->perm_dex = 16; break; case APPLY_CON: ch->perm_con = 16; break; case APPLY_CHA: ch->perm_cha = 16; break; case APPLY_LCK: ch->perm_lck = 16; break; } ch->perm_str += race_table[ch->race]->str_plus; ch->perm_int += race_table[ch->race]->int_plus; ch->perm_wis += race_table[ch->race]->wis_plus; ch->perm_dex += race_table[ch->race]->dex_plus; ch->perm_con += race_table[ch->race]->con_plus; ch->perm_cha += race_table[ch->race]->cha_plus; xSET_BITS(ch->affected_by, race_table[ch->race]->affected); ch->perm_lck += race_table[ch->race]->lck_plus; if ( (iLang = skill_lookup( "common" )) < 0 ) bug( "Nanny: cannot find common language." ); else ch->pcdata->learned[iLang] = 100; for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ ) if ( lang_array[iLang] == race_table[ch->race]->language ) break; if ( lang_array[iLang] == LANG_UNKNOWN ) bug( "Nanny: invalid racial language." ); else { if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 ) bug( "Nanny: cannot find racial language." ); else ch->pcdata->learned[iLang] = 100; } /* ch->resist += race_table[ch->race]->resist; drats*/ /* ch->susceptible += race_table[ch->race]->suscept; drats*/ name_stamp_stats( ch ); ch->level = 1; ch->exp = 0; ch->practice = 10; ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->hit += race_table[ch->race]->hit; ch->mana += race_table[ch->race]->mana; ch->move = ch->max_move; /* They need Money for fuck sake.. bah who codes this place anyway!!? :P --GW */ ch->silver = 50; sprintf( buf, "%s the lost %s of the Ancients.", QUICKLINK(ch->name),capitalize(npc_class[ch->class]) ); set_title( ch, buf ); /* Added by Brittany, Nov 24/96. The object is the adventurer's guide to the realms of despair, part of Academy.are. */ /* Added by Narn. Start new characters with autoexit and autgold already turned on. Very few people don't use those. */ /* NEWBIEHELP Channel added by Greywolf, 6/23/97*/ SET_BIT( ch->act, PLR_AUTOGOLD ); SET_BIT( ch->act, PLR_AUTOEXIT ); SET_BIT( ch->pcdata->flags, PCFLAG_NEWBIEHELP); zone = find_zone(1); obj = create_object( get_obj_index(25511,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25510,1), 0,zone); obj_to_char( obj,ch); obj = create_object(get_obj_index(25512,1),0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25513,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25514,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25515,1),0,zone ); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25516,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25518,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25519,1), 0,zone); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25520,1), 0,zone ); obj_to_char( obj, ch ); obj = create_object( get_obj_index(25520,1), 0,zone); obj_to_char( obj, ch ); /* Oops .. need a light --GW */ obj = create_object( get_obj_index(25505,1), 0,zone); obj_to_char( obj, ch ); if ( (ch->class == 0) || (ch->class == 2) || (ch->class == 4) || (ch->class == 7) || (ch->class == 9) || (ch->class == 10) || (ch->class == 13) ) { obj = create_object( get_obj_index(25508,1), 0,zone ); obj_to_char(obj, ch); } else if ( (ch->class == 1) || (ch->class == 5) || (ch->class == 11) ) { obj = create_object( get_obj_index(25507,1), 0,zone ); obj_to_char(obj, ch); } else if ( (ch->class == 3) || (ch->class == 6) || (ch->class == 8) ) { obj = create_object(get_obj_index(25509,1), 0,zone ); obj_to_char(obj, ch); } if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index( 25519,1) ); ch->pcdata->auth_state = 0; SET_BIT(ch->pcdata->flags, PCFLAG_UNAUTHED); /* Display_prompt interprets blank as default */ ch->pcdata->prompt = STRALLOC(""); new_player = TRUE; } else if ( ch->level > 1 && !IS_IMMORTAL(ch) && ch->pcdata->release_date > current_time ) { if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index(8,1) ); } else if ( ch->level > 1 && IS_SET( ch->pcdata->flagstwo, MOREPC_ARRESTED ) ) { if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index(7,1) ); } else if ( ch->level > 1 && ( test=get_room_index((int)ch->pcdata->start_room,1))!=NULL ) { if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index((int)ch->pcdata->start_room,1)); } else if ( ch->level > 1 && IS_IMMORTAL(ch) ) { if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index( ROOM_VNUM_CHAT,1 ) ); } else { if ( ch->in_room ) char_from_room(ch); char_to_room( ch, get_room_index(30601,1) ); } if ( get_timer( ch, TIMER_SHOVEDRAG ) > 0 ) remove_timer( ch, TIMER_SHOVEDRAG ); if ( get_timer( ch, TIMER_PKILLED ) > 0 ) remove_timer( ch, TIMER_PKILLED ); sprintf( mus_buf, "!!MUSIC(aota%s%s)\n\r",SLASH,sysdata.entersound); send_to_char(mus_buf, ch ); if ( ch->level != 59 && !IS_SET(ch->act, PLR_WIZINVIS) && !IS_SET(ch->pcdata->flagstwo,MOREPC_INCOG) && ch->pcdata->died_entrance != TRUE && !new_player ) { sprintf(log_buf,"The Raspy voice of the Keeper intones 'Welcome %s...'",ch->name); echo_to_all(AT_MAGIC,log_buf,ECHOTAR_ALL); } /* Make Keeper Announce Newbies! --GW */ if ( new_player ) { sprintf(log_buf,"&BThe Raspy voice of the Keeper Welcomes &W&G%s, the New Player&B!", capitalize(ch->name)); echo_to_all(AT_PLAIN,log_buf,ECHOTAR_ALL); new_player = FALSE; } act( AT_RED, "A Portal appears, from Realms far beyond these.", ch, NULL, NULL, TO_ROOM ); act( AT_RED, "$n steps from the Portal.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); mail_count(ch); if ( get_trust(ch) >= 56 ) show_overlimit(ch); /* Hoarder Stuff --GW */ ch->pcdata->hoard_status = HOARD_NONE; REMOVE_BIT(ch->pcdata->flagstwo, MOREPC_HOARDER); if ( !IS_SET(ch->pcdata->flagstwo,MOREPC_NO_LIMIT_CNT) ) hoarder_check(ch,NULL,HCHECK_LOGIN); if ( ch->pcdata->died_entrance == TRUE ) { CHAR_DATA *wch; /* * Make things a little fancier -Thoric */ if ( ( ( wch = get_char_room( ch, "newbie" ) ) != NULL ) || ( ( wch = get_char_room( ch, "guard" ) ) != NULL ) || ( ( wch = get_char_room( ch, "spawn" ) ) != NULL ) ) { act( AT_MAGIC, "$n mutters a few incantations, waves $s hands and points $s finger.",wch, NULL, NULL, TO_ROOM ); act( AT_MAGIC, "$n appears from some strange swirling mists!",ch, NULL, NULL, TO_NOTVICT ); sprintf(buf, "Welcome back to the land of the living, %s", capitalize( ch->name ) ); do_say( wch, buf ); } else act( AT_MAGIC, "$n appears from some strange swirling mists!",ch, NULL,NULL,TO_NOTVICT); ch->position = POS_RESTING; return; } if ( !sysdata.WAIT_FOR_AUTH && ch->level == 1 ) { send_to_char("\n\r************************************************** \n\r",ch); send_to_char("***** AUTO AUTHORIZATION IS ON - AUTHORIZING *****\n\r",ch); send_to_char("**************************************************\n\r",ch); if ( ( location = find_location( ch,loc2,1) ) == NULL ) { log_string( "AUTO-AUTH FAILED!!!: No such location"); return; } REMOVE_BIT(ch->pcdata->flags, PCFLAG_UNAUTHED); ch->level = 2; advance_level(ch,TRUE,1); stop_fighting( ch, TRUE ); char_from_room( ch ); char_to_room( ch, location ); do_look( ch, "auto" ); do_save(ch,""); } break; /* Far too many possible screwups if we do it this way. -- Altrag */ /* case CON_NEW_LANGUAGE: for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ ) if ( !str_prefix( argument, lang_names[iLang] ) ) if ( can_learn_lang( ch, lang_array[iLang] ) ) { add_char( ch ); SET_BIT( ch->speaks, lang_array[iLang] ); set_char_color( AT_SAY, ch ); ch_printf( ch, "You can now speak %s.\n\r", lang_names[iLang] ); d->connected = CON_PLAYING; return; } set_char_color( AT_SAY, ch ); write_to_buffer( d, "You may not learn that language. Please choose another.\n\r" "New language: ", 0 ); break;*/ /* Death --GW */ case CON_DEATH_SELECT: switch( *argument ) { case 'Y': case 'y': do_char_ressurect( d->character ); send_to_char("So be it.....\n\r",d->character); send_to_char("Your Constitution Drops by 1.\n\r",d->character); send_to_char("\n\rPress [ENTER]",ch); d->connected = CON_READ_MOTD; break; case 'N': case 'n': do_char_notressurect( d->character ); send_to_char("So be it.....\n\r",d->character); send_to_char("You drop 1 level.\n\r",ch); send_to_char("\n\rPress [ENTER]",ch); d->connected = CON_READ_MOTD; break; default: write_to_buffer(d,"\nInvalid Choice.\n",0); send_to_char(DEATH_MENU,ch); d->connected = CON_DEATH_SELECT; return; } } return; } /* * Parse a name for acceptability. */ bool check_parse_name( char *name ) { /* * Reserved words. */ if ( is_name( name, "all auto immortal self newbie someone god supreme demigod dog guard cityguard cat cornholio spock hicaine hithoric death ass fuck shit piss crap quit" ) ) return FALSE; /* * Length restrictions. */ if ( strlen(name) < 3 ) return FALSE; if ( strlen(name) > 14 ) return FALSE; /* * Alphanumerics only. * Lock out IllIll twits. */ { char *pc; bool fIll; fIll = TRUE; for ( pc = name; *pc != '\0'; pc++ ) { if ( !isalpha(*pc) ) return FALSE; if ( LOWER(*pc) != 'i' && LOWER(*pc) != 'l' ) fIll = FALSE; } if ( fIll ) return FALSE; } /* * Code that followed here used to prevent players from naming * themselves after mobs... this caused much havoc when new areas * would go in... */ return TRUE; } /* * Look for link-dead player to reconnect. */ bool check_reconnect( DESCRIPTOR_DATA *d, char *name, bool fConn ) { CHAR_DATA *ch; /* char buf[MSL];*/ for ( ch = first_char; ch; ch = ch->next ) { if ( !IS_NPC(ch) && ( !fConn || !ch->desc ) && ch->name && !str_cmp( name, ch->name ) ) { /* if ( fConn && ch->switched ) { write_to_buffer( d, "Already playing.\n\rName: ", 0 ); d->connected = CON_GET_NAME; if ( d->character ) { clear descriptor pointer to get rid of bug message inlog d->character->desc = NULL; free_char( d->character ); d->character = NULL; } return BERR; }*/ if ( fConn == FALSE ) { DISPOSE( d->character->pcdata->pwd ); d->character->pcdata->pwd = str_dup( ch->pcdata->pwd ); } else { /* clear descriptor pointer to get rid of bug message in log */ d->character->desc = NULL; free_char( d->character ); d->character = ch; ch->desc = d; ch->timer = 0; send_to_char( "Reconnecting.\n\r", ch ); act( AT_ACTION, "$n has reconnected.", ch, NULL, NULL, TO_ROOM ); sprintf( log_buf, "%s@%s(%s) reconnected.", ch->name, d->host, d->user ); ch->pcdata->pre_name_toggle = 1; /* sprintf(buf,"gunzip -f %s%c/%s",PLAYER_DIR,tolower(name[0]), capitalize(name)); system(buf); */ log_string_plus( log_buf, LOG_COMM, UMAX( sysdata.log_level, ch->level ) ); /* if ( ch->level < LEVEL_SAVIOR ) to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", ch->level ); */ d->connected = CON_PLAYING; } return TRUE; } } return FALSE; } /* * Check if already playing. */ bool check_playing( DESCRIPTOR_DATA *d, char *name, bool kick ) { CHAR_DATA *ch; DESCRIPTOR_DATA *dold; int cstate; for ( dold = first_descriptor; dold; dold = dold->next ) { if ( dold != d && ( dold->character || dold->original ) && !str_cmp( name, dold->original ? dold->original->name : dold->character->name ) ) { cstate = dold->connected; ch = dold->original ? dold->original : dold->character; if ( !ch->name || ( cstate != CON_PLAYING && cstate != CON_EDITING ) ) { write_to_buffer( d, "Already connected - try again.\n\r", 0 ); sprintf( log_buf, "%s already connected.", ch->name ); log_string_plus( log_buf, LOG_COMM, sysdata.log_level ); return BERR; } if ( !kick ) return TRUE; // if ( check_hosts(dold->character,d->host)) // return TRUE; write_to_buffer( d, "Already playing... Kicking off old connection.\n\r", 0 ); write_to_buffer( dold, "Kicking off old connection... bye!\n\r", 0 ); close_socket( dold, FALSE ); /* clear descriptor pointer to get rid of bug message in log */ d->character->desc = NULL; free_char( d->character ); d->character = ch; ch->desc = d; ch->timer = 0; /* if ( ch->switched ) do_return( ch->switched, "" ); ch->switched = NULL; */ send_to_char( "Reconnecting.\n\r", ch ); act( AT_ACTION, "$n has reconnected, kicking off old link.", ch, NULL, NULL, TO_ROOM ); sprintf( log_buf, "%s@%s reconnected, kicking off old link.", ch->name, d->host ); log_string_plus( log_buf, LOG_COMM, UMAX( sysdata.log_level, ch->level ) ); ch->pcdata->pre_name_toggle = 1; /* if ( ch->level < LEVEL_SAVIOR ) to_channel( log_buf, CHANNEL_MONITOR, "[ ** ", ch->level ); */ d->connected = cstate; return TRUE; } } return FALSE; } /* Bugged? void old_stop_idling( CHAR_DATA *ch ) { if ( !ch || !ch->desc || ch->desc->connected != CON_PLAYING || !ch->was_in_room || ch->in_room != get_room_index( ROOM_VNUM_LIMBO,1 ) ) return; ch->timer = 0; char_from_room( ch ); char_to_room( ch, ch->was_in_room ); ch->was_in_room = NULL; act( AT_ACTION, "$n has returned from the void.", ch, NULL, NULL, TO_ROOM ); return; } */ void stop_idling( CHAR_DATA *ch ) { if ( !ch || !ch->desc || ch->desc->connected != CON_PLAYING || (ch->timer < 2)) return; ch->timer = 0; return; } /* * Write to one char. */ /*void send_to_char( const char *txt, CHAR_DATA *ch ) { if ( !ch ) { bug( "Send_to_char: NULL *ch" ); return; } if ( strlen(txt) > MAX_STRING_LENGTH ) { bug("Send_to_char: string length to long! (*FATAL* -- REPORT THIS!)"); return; } if ( txt && ch->desc ) { write_to_buffer( ch->desc, txt, strlen(txt) ); } return; } */ /* * Same as above, but converts &color codes to ANSI sequences.. */ bool send_to_char_color( char *txt, CHAR_DATA *ch ) { DESCRIPTOR_DATA *d; char *colstr; const char *prevstr = txt; char colbuf[20]; int ln; if ( !ch ) { bug( "Send_to_char_color: NULL *ch" ); return FALSE; } if ( !txt || !ch->desc ) return FALSE; d = ch->desc; /* DONOT use this --GW */ /* if ( d->outsize > 1000000 ) { bug("outsize: %d: %s",d->outsize,txt); return FALSE; } */ /* Clear out old color stuff */ /* make_color_sequence(NULL, NULL, NULL);*/ while ( (colstr = strpbrk(prevstr, "&^")) != NULL ) { /* if we pass length=0, then write_to_buffer will do a strlen! */ if (colstr!=prevstr) { if (( write_to_buffer(d, prevstr, (colstr-prevstr)))==FALSE) { return FALSE; } } ln = make_color_sequence(colstr, colbuf, d); if ( ln < 0 ) { prevstr = colstr+1; break; } else if ( ln > 0 ) { if (( write_to_buffer(d, colbuf, ln))==FALSE) { return FALSE; } } prevstr = colstr+2; } if ( *prevstr ) { if( ( write_to_buffer(d, prevstr, 0))==FALSE) { return FALSE; } } return TRUE; } /* * Ripoff of Send to Char Color - Sends to a Desc Color (for login screen) --GW */ bool write_to_desc_color( char *txt, DESCRIPTOR_DATA *d ) { char *colstr; const char *prevstr = txt; char colbuf[20]; int ln; if ( !d ) { bug( "write_to_desc_color: NULL *d" ); return FALSE; } if ( !txt ) return FALSE; /* Clear out old color stuff */ /* make_color_sequence(NULL, NULL, NULL);*/ while ( (colstr = strpbrk(prevstr, "&^")) != NULL ) { /* if we pass length=0, then write_to_buffer will do a strlen! */ if (colstr!=prevstr) { if (( write_to_buffer(d, prevstr, (colstr-prevstr)))==FALSE) { return FALSE; } } ln = make_color_sequence(colstr, colbuf, d); if ( ln < 0 ) { prevstr = colstr+1; break; } else if ( ln > 0 ) { if (( write_to_buffer(d, colbuf, ln))==FALSE) { return FALSE; } } prevstr = colstr+2; } if ( *prevstr ) { if( ( write_to_buffer(d, prevstr, 0))==FALSE) { return FALSE; } } return TRUE; } bool write_to_pager( DESCRIPTOR_DATA *d, const char *txt, int length ) { if ( length <= 0 ) length = strlen(txt); if ( length == 0 ) return FALSE; if ( !d->pagebuf ) { d->pagesize = MAX_STRING_LENGTH; CREATE( d->pagebuf, char, d->pagesize ); } if ( !d->pagepoint ) { d->pagepoint = d->pagebuf; d->pagetop = 0; d->pagecmd = '\0'; } if ( d->pagetop == 0 && !d->fcommand ) { d->pagebuf[0] = '\n'; d->pagebuf[1] = '\r'; d->pagetop = 2; } while ( d->pagetop + length >= d->pagesize ) { if ( d->pagesize > 32000 ) { bug( "Pager overflow. Ignoring.\n\r" ); d->pagetop = 0; d->pagepoint = NULL; DISPOSE(d->pagebuf); d->pagesize = MAX_STRING_LENGTH; return FALSE; } d->pagesize *= 2; RECREATE(d->pagebuf, char, d->pagesize); } strncpy(d->pagebuf+d->pagetop, txt, length); d->pagetop += length; d->pagebuf[d->pagetop] = '\0'; return TRUE; } /*void send_to_pager( const char *txt, CHAR_DATA *ch ) { if ( !ch ) { bug( "Send_to_pager: NULL *ch" ); return; } if ( txt && ch->desc ) { DESCRIPTOR_DATA *d = ch->desc; ch = d->original ? d->original : d->character; if ( IS_NPC(ch) || !IS_SET(ch->pcdata->flags, PCFLAG_PAGERON) ) { send_to_char(txt, d->character); return; } write_to_pager(d, txt, 0); } return; } */ bool send_to_pager_color( char *txt, CHAR_DATA *ch ) { DESCRIPTOR_DATA *d; char *colstr; const char *prevstr = txt; char colbuf[20]; int ln; if ( !ch ) { bug( "Send_to_pager_color: NULL *ch" ); return FALSE; } if ( !txt || !ch->desc ) return FALSE; d = ch->desc; ch = d->original ? d->original : d->character; if ( IS_NPC(ch) || !IS_SET(ch->pcdata->flags, PCFLAG_PAGERON) ) { if ( ( send_to_char_color(txt, d->character) )==FALSE) return FALSE; else return TRUE; } /* Clear out old color stuff */ /* make_color_sequence(NULL, NULL, NULL);*/ while ( (colstr = strpbrk(prevstr, "&^")) != NULL ) { if ( colstr > prevstr ) { if ( ( write_to_pager(d, prevstr, (colstr-prevstr)) )==FALSE) return FALSE; } ln = make_color_sequence(colstr, colbuf, d); if ( ln < 0 ) { prevstr = colstr+1; break; } else if ( ln > 0 ) { if( ( write_to_pager(d, colbuf, ln) )==FALSE) return FALSE; } prevstr = colstr+2; } if ( *prevstr ) { if( ( write_to_pager(d, prevstr, 0))==FALSE) return FALSE; } return TRUE; } void set_char_color( sh_int AType, CHAR_DATA *ch ) { char buf[16]; CHAR_DATA *och; if ( !ch || !ch->desc ) return; och = ch; if ( !IS_NPC(och) && IS_SET(och->act, PLR_ANSI) ) { if ( AType == 7 ) strcpy( buf, "\033[m" ); else sprintf(buf, "\033[0;%d;%s%dm", (AType & 8) == 8, (AType > 15 ? "5;" : ""), (AType & 7)+30); write_to_buffer( ch->desc, buf, strlen(buf) ); } return; } void set_pager_color( sh_int AType, CHAR_DATA *ch ) { char buf[16]; CHAR_DATA *och; if ( !ch || !ch->desc ) return; och = (ch->desc->original ? ch->desc->original : ch); if ( !IS_NPC(och) && IS_SET(och->act, PLR_ANSI) ) { if ( AType == 7 ) strcpy( buf, "\033[m" ); else sprintf(buf, "\033[0;%d;%s%dm", (AType & 8) == 8, (AType > 15 ? "5;" : ""), (AType & 7)+30); send_to_pager( buf, ch ); ch->desc->pagecolor = AType; } return; } /* source: EOD, by John Booth <???> */ void ch_printf(CHAR_DATA *ch, char *fmt, ...) { char buf[MAX_STRING_LENGTH*2]; /* better safe than sorry */ va_list args; if ( fmt == NULL ) return; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); send_to_char(buf, ch); } void pager_printf(CHAR_DATA *ch, char *fmt, ...) { char buf[MAX_STRING_LENGTH*2]; va_list args; if ( fmt == NULL ) return; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); send_to_pager(buf, ch); } /* From Erwin */ void log_printf(char *fmt, ...) { char buf[MAX_STRING_LENGTH*2]; va_list args; if ( fmt == NULL ) return; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); log_string(buf); } char *obj_short( OBJ_DATA *obj ) { static char buf[MAX_STRING_LENGTH]; if ( obj->count > 1 ) { sprintf( buf, "%s (%d)", obj->short_descr, obj->count ); return buf; } return obj->short_descr; } /* * The primary output interface for formatted output. */ /* Major overhaul. -- Alty */ #define NAME(ch) (IS_NPC(ch) ? ch->short_descr : ch->name) char *act_string(const char *format, CHAR_DATA *to, CHAR_DATA *ch, const void *arg1, const void *arg2) { static char * const he_she [] = { "it", "he", "she" }; static char * const him_her [] = { "it", "him", "her" }; static char * const his_her [] = { "its", "his", "her" }; static char buf[MAX_STRING_LENGTH]; char fname[MAX_INPUT_LENGTH]; char *point = buf; const char *str = format; const char *i; CHAR_DATA *vch = (CHAR_DATA *) arg2; OBJ_DATA *obj1 = (OBJ_DATA *) arg1; OBJ_DATA *obj2 = (OBJ_DATA *) arg2; while ( *str != '\0' ) { if ( *str != '$' ) { *point++ = *str++; continue; } ++str; /* The $p crasher --GW */ if ( isdigit( *str+1 ) ) { *point++ = *str++; continue; } if ( !arg2 && *str >= 'A' && *str <= 'Z' ) { bug( "Act: missing arg2 for code %c:", *str ); bug( format ); i = " <@@@> "; } else { switch ( *str ) { default: bug( "Act: bad code %c.", *str ); i = " <@@@> "; break; case 't': i = (char *) arg1; break; case 'T': i = (char *) arg2; break; case 'n': i = (to ? PERS( ch, to) : NAME( ch)); break; case 'N': i = (to ? PERS(vch, to) : NAME(vch)); break; case 'e': if (ch->sex > 2 || ch->sex < 0) { bug("act_string: player %s has sex set at %d!", ch->name, ch->sex); i = "it"; } else i = he_she [URANGE(0, ch->sex, 2)]; break; case 'E': if (vch->sex > 2 || vch->sex < 0) { bug("act_string: player %s has sex set at %d!", vch->name, vch->sex); i = "it"; } else i = he_she [URANGE(0, vch->sex, 2)]; break; case 'm': if (ch->sex > 2 || ch->sex < 0) { bug("act_string: player %s has sex set at %d!", ch->name, ch->sex); i = "it"; } else i = him_her[URANGE(0, ch->sex, 2)]; break; case 'M': if (vch->sex > 2 || vch->sex < 0) { bug("act_string: player %s has sex set at %d!", vch->name, vch->sex); i = "it"; } else i = him_her[URANGE(0, vch->sex, 2)]; break; case 's': if (ch->sex > 2 || ch->sex < 0) { bug("act_string: player %s has sex set at %d!", ch->name, ch->sex); i = "its"; } else i = his_her[URANGE(0, ch->sex, 2)]; break; case 'S': if (vch->sex > 2 || vch->sex < 0) { bug("act_string: player %s has sex set at %d!", vch->name, vch->sex); i = "its"; } else i = his_her[URANGE(0, vch->sex, 2)]; break; case 'q': i = (to == ch) ? "" : "s"; break; case 'Q': i = (to == ch) ? "your" : his_her[URANGE(0, ch->sex, 2)]; break; case 'p': i = (!to || can_see_obj(to, obj1) ? obj_short(obj1) : "something"); break; case 'P': i = (!to || can_see_obj(to, obj2) ? obj_short(obj2) : "something"); break; case 'd': if ( !arg2 || ((char *) arg2)[0] == '\0' ) i = "door"; else { one_argument((char *) arg2, fname); i = fname; } break; } } ++str; while ( (*point = *i) != '\0' ) ++point, ++i; } strcpy(point, "\n\r"); buf[0] = UPPER(buf[0]); return buf; } #undef NAME void act( sh_int AType, char *format, CHAR_DATA *ch, const void *arg1, const void *arg2, int type ) { char *txt; CHAR_DATA *to; CHAR_DATA *vch = (CHAR_DATA *)arg2; CHAR_DATA *from_char; int num1 = 0; int num2 = 0; bool bad; char temp[MSL]; txt = NULL; temp[0] = '\0'; /* set bad to false */ bad = FALSE; /* * Discard null and zero-length messages. */ if ( !format || format[0] == '\0' ) return; if ( !ch ) { bug( "Act: null ch. (%s)", format ); return; } if ( !ch->in_room ) { bug( "Act: null ch->in_room --> (%s)",ch->name ); return; } /* hopefully this puts a noose on the crap bug ..--GW */ strcpy( temp, format ); num1 = strlen(temp); /* scan it for crap .. break if there is any*/ for ( num2 = 0; num2 <= num1; num2++ ) { if ( temp[num2] == '\0' ) break; if ( isspace(temp[num2]) || ( temp[num2] == ' ' ) || ( temp[num2] == '$' ) || ( temp[num2] == '.' ) || ( isgraph(temp[num2] ) ) || ( isalnum(temp[num2]) ) || ( isprint( temp[num2]) ) ) continue; bad = TRUE; bug("Act: Bad Format!(%s) at vnum: %d.",temp,ch->in_room->vnum); break; } /* kick us out if its bad text */ if ( bad == TRUE ) return; to = NULL; from_char = ch; if ( !ch || !ch->in_room || !ch->in_room->first_person ) to = NULL; else if ( type == TO_CHAR ) to = ch; else to = ch->in_room->first_person; /* * ACT_SECRETIVE handling */ if ( IS_NPC(ch) && IS_SET(ch->act, ACT_SECRETIVE) && type != TO_CHAR ) return; if ( type == TO_VICT ) { if ( !vch ) { bug( "Act: null vch with TO_VICT." ); bug( "%s (%s)", ch->name, format ); return; } if ( !vch->in_room ) { bug( "Act: vch in NULL room!" ); bug( "%s -> %s (%s)", ch->name, vch->name, format ); return; } to = vch; } if ( to == NULL ) { return; } if ( to->in_room == NULL ) { return; } if ( MOBtrigger && type != TO_CHAR && type != TO_VICT && to ) { OBJ_DATA *to_obj; txt = act_string(format, NULL, ch, arg1, arg2); if ( txt == NULL ) { bug("Act: NULL txt!"); return; } if ( ch == NULL || to == NULL ) { bug("Act: NULL ch!!"); return; } if ( ch->in_room == NULL || to->in_room == NULL ) return; if ( to && to->in_room && to->in_room->progtypes && IS_SET(to->in_room->progtypes,ACT_PROG) ) rprog_act_trigger(txt, to->in_room, ch, (OBJ_DATA *)arg1, (void*)arg2); for ( to_obj = to->in_room->first_content; to_obj; to_obj = to_obj->next_content ) { if ( to_obj->pIndexData && IS_SET(to_obj->pIndexData->progtypes, ACT_PROG) ) oprog_act_trigger(txt, to_obj, ch, (OBJ_DATA *)arg1, (void *)arg2); } } /* Anyone feel like telling me the point of looping through the whole room when we're only sending to one char anyways..? -- Alty */ for ( ; to; to = (type == TO_CHAR || type == TO_VICT) ? NULL : to->next_in_room ) { if ((!to->desc && ( IS_NPC(to) && !IS_SET(to->pIndexData->progtypes, ACT_PROG) )) || !IS_AWAKE(to) ) 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; /* ignore */ if ( is_ignoring( to, from_char ) ) continue; /* Vehicles */ /* if ( !IS_NPC(ch) && ch->pcdata->vehicle && type != TO_CHAR && !IS_NPC(to) && ( !to->pcdata->vehicle || ( to->pcdata->vehicle != ch->pcdata->vehicle ) ) ) continue;*/ txt = act_string(format, to, ch, arg1, arg2); if (to->desc) { set_char_color(AType, to); send_to_char_color(txt,to); } if (MOBtrigger) { /* Note: use original string, not string with ANSI. -- Alty */ mprog_act_trigger( txt, to, ch, (OBJ_DATA *)arg1, (void *)arg2 ); } } MOBtrigger = TRUE; format = NULL; return; } void do_name( CHAR_DATA *ch, char *argument ) { char fname[1024]; char fname2[1024]; struct stat fst; char arg[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; CHAR_DATA *victim; char buf[MAX_STRING_LENGTH]; bool fOld; fOld = FALSE; one_argument( argument, arg); if ( ( victim = get_char_world( ch, arg ) ) == NULL ) { send_to_char( "They aren't playing.\n\r", ch); return; } one_argument( (argument+strlen(victim->name)+1), arg2); if ( arg[0] == '\0' || arg2[0] == '\0' ) { send_to_char("Syntax: rename <char> <new name>",ch); return; } if (get_trust(ch) <= get_trust(victim) && ch != victim ) { send_to_char("No......... Idiot.\n\r",ch); return; } if (!check_parse_name(arg2)) { send_to_char("Illegal name, try another.\n\r", ch); return; } sprintf( fname, "%s%c/%s", PLAYER_DIR, tolower(arg2[0]), capitalize( arg2 ) ); sprintf( fname2, "%s%c/%s", PLAYER_DIR, tolower(victim->name[0]), capitalize( victim->name ) ); if ( stat( fname, &fst ) != -1 ) { send_to_char("That name is already taken. Please choose another.\n\r", ch); return; } arg2[0] = UPPER(arg2[0]); STRFREE( victim->name ); victim->name = STRALLOC( arg2 ); sprintf(buf,"%s has renamed you to '%s'.",QUICKLINK(ch->name),QUICKLINK(victim->name )); send_to_char(buf,victim); send_to_char("\n\r",victim); remove(fname2); do_title(victim,""); if ( IS_IMMORTAL( victim ) ) { do_bamfin(victim,""); do_bamfout(victim,""); } do_save(victim,""); send_to_char("Done.\n\r",ch); return; } char *default_prompt( CHAR_DATA *ch ) { static char buf[60]; strcpy(buf, "&w<&R%h/%Hhp "); if ( IS_VAMPIRE(ch) ) strcat(buf, "&R%b/%Bbp"); else strcat(buf, "&g%m/%Mm"); strcat(buf, " &b%v/%Vmv &r<&W%c&r>&w> "); if ( IS_NPC(ch) || IS_IMMORTAL(ch) ) strcat(buf, "%i%R"); return buf; } int getcolor(char clr) { static const char colors[16] = "xrgObpcwzRGYBPCW"; int r; for ( r = 0; r < 16; r++ ) if ( clr == colors[r] ) return r; return -1; } void display_prompt( DESCRIPTOR_DATA *d ) { CHAR_DATA *ch = d->character; CHAR_DATA *och = (d->original ? d->original : d->character); bool ansi = (!IS_NPC(och) && IS_SET(och->act, PLR_ANSI)); const char *prompt; char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char fbuf[MAX_STRING_LENGTH]; char wound[MAX_STRING_LENGTH]; char *pbuf = buf; int stat; int percent; CHAR_DATA *victim; if ( !ch ) { bug( "display_prompt: NULL ch" ); return; } if ( !IS_NPC(ch) && ch->substate != SUB_NONE && ch->pcdata->subprompt && ch->pcdata->subprompt[0] != '\0' ) prompt = ch->pcdata->subprompt; else if ( IS_NPC(ch) || !ch->pcdata->prompt || !*ch->pcdata->prompt ) prompt = default_prompt(ch); else prompt = ch->pcdata->prompt; if ( ansi ) { strcpy(pbuf, "\033[m"); d->prevcolor = 0x07; pbuf += 3; } /* Clear out old color stuff */ /* make_color_sequence(NULL, NULL, NULL);*/ for ( ; *prompt; prompt++ ) { /* * '&' = foreground color/intensity bit * '^' = background color/blink bit * '%' = prompt commands * Note: foreground changes will revert background to 0 (black) */ if ( *prompt != '&' && *prompt != '^' && *prompt != '%' ) { *(pbuf++) = *prompt; continue; } ++prompt; if ( !*prompt ) break; if ( *prompt == *(prompt-1) ) { *(pbuf++) = *prompt; continue; } switch(*(prompt-1)) { default: bug( "Display_prompt: bad command char '%c'.", *(prompt-1) ); break; case '&': case '^': stat = make_color_sequence(&prompt[-1], pbuf, d); if ( stat < 0 ) --prompt; else if ( stat > 0 ) pbuf += stat; break; case '%': *pbuf = '\0'; stat = 0x80000000; switch(*prompt) { case '%': *pbuf++ = '%'; *pbuf = '\0'; break; case 'a': if ( ch->level >= 10 ) stat = ch->alignment; else if ( IS_GOOD(ch) ) strcpy(pbuf, "good"); else if ( IS_EVIL(ch) ) strcpy(pbuf, "evil"); else strcpy(pbuf, "neutral"); break; case 'p' : stat = get_power(ch); break; case 'P' : if( ch->fighting && (victim = ch->fighting->who) != NULL) { stat = get_power(victim); } else stat = 0; break; case 'Y' : /* This graphical bar shows the player's condition -- Cal */ if (ch->fighting && (victim = ch->fighting->who) != NULL) { if (ch->max_hit > 0) percent = ch->hit * 100 / ch->max_hit; else percent = -1; if (percent >= 100) sprintf(wound,"&WYou: [^r___^O___^g____^x&W]"); else if (percent >= 90) sprintf(wound,"&WYou: [^r___^O___^g___^x &W]"); else if (percent >= 80) sprintf(wound,"&WYou: [^r___^O___^g__^x &W]"); else if (percent >= 70) sprintf(wound,"&WYou: [^r___^O___^g_^x &W]"); else if (percent >= 58) sprintf(wound,"&WYou: [^r___^O___^x &W]"); else if (percent >= 45) sprintf(wound,"&WYou: [^r___^O__^x &W]"); else if (percent >= 30) sprintf(wound,"&WYou: [^r___^O_^x &W]"); else if (percent >= 28) sprintf(wound,"&WYou: [^r___&W^x &W]"); else if (percent >= 15) sprintf(wound,"&WYou: [^r__&W^x &W]"); else if (percent >= 8) sprintf(wound,"&WYou: [^r_&W^x &W]"); else sprintf(wound,"&WYou: [ &RDEAD!!! ^x&W]"); sprintf(buf2," %s",wound); strcpy(pbuf,buf2); } else strcpy(pbuf, "<>"); break; /* Ok yes that was a cheap copy of the one below :P but in the interests * of being complete */ case 'Z' : /* this is the graphical battle damage prompt * * <- Gothar 1997 -> */ if (ch->fighting && (victim = ch->fighting->who) != NULL) { if (victim->max_hit > 0) percent = victim->hit * 100 / victim->max_hit; else percent = -1; if (percent >= 100) sprintf(wound,"&WEnemy: [^r___^O___^g____^x&W]"); else if (percent >= 90) sprintf(wound,"&WEnemy: [^r___^O___^g___^x &W]"); else if (percent >= 80) sprintf(wound,"&WEnemy: [^r___^O___^g__^x &W]"); else if (percent >= 70) sprintf(wound,"&WEnemy: [^r___^O___^g_^x &W]"); else if (percent >= 58) sprintf(wound,"&WEnemy: [^r___^O___^x &W]"); else if (percent >= 45) sprintf(wound,"&WEnemy: [^r___^O__^x &W]"); else if (percent >= 30) sprintf(wound,"&WEnemy: [^r___^O_^x &W]"); else if (percent >= 28) sprintf(wound,"&WEnemy: [^r___&W^x &W]"); else if (percent >= 15) sprintf(wound,"&WEnemy: [^r__&W^x &W]"); else if (percent >= 8) sprintf(wound,"&WEnemy: [^r_&W^x &W]"); else sprintf(wound,"&WEnemy: [ &RDEAD!!! ^x&W]"); sprintf(buf2," %s",wound); strcpy(pbuf,buf2); } else strcpy(pbuf, "<>"); break; case 'z' : /* this is the percentage battle damage prompt * The prompt changes colour to show the * condition of the mob. * <- Gothar 1997 -> */ if (ch->fighting && (victim = ch->fighting->who) != NULL) { percent = victim->hit * 100 / victim->max_hit; if(percent >= 65) sprintf(buf2," &WEnemy: &O%d&W%%",percent); else if(percent >= 25 && percent < 65) sprintf(buf2," &WEnemy: &O%d&W%%",percent); else sprintf(buf2," &WEnemy: &r%d&W%%",percent); strcpy(pbuf,buf2); } else strcpy(pbuf, "None"); break; case 'f': if ( ch->pcdata->deity ) stat = ch->pcdata->favor; else strcpy(pbuf, "no favor"); break; case 'h': stat = ch->hit; break; case 'H': stat = ch->max_hit; break; case 'm': if ( IS_VAMPIRE(ch) ) stat = 0; else stat = ch->mana; break; case 'M': if ( IS_VAMPIRE(ch) ) stat = 0; else stat = ch->max_mana; break; case 'b': if ( IS_VAMPIRE(ch) ) stat = ch->pcdata->condition[COND_BLOODTHIRST]; else stat = 0; break; case 'B': if ( IS_VAMPIRE(ch) ) stat = get_bloodthirst(ch); else stat = 0; break; case 'u': stat = get_mortal_num_desc(ch); break; case 'U': stat = sysdata.maxplayers; break; case 'v': stat = ch->move; break; case 'V': stat = ch->max_move; break; case 'g': stat = ch->gold; break; case 'r': if ( IS_IMMORTAL(och) ) stat = ch->in_room->vnum; break; case 'R': if ( IS_SET(och->act, PLR_ROOMVNUM) ) sprintf(pbuf, "<#%d> ", ch->in_room->vnum); break; case 'x': stat = ch->exp; break; case 'X': stat = exp_level(ch, ch->level+1) - ch->exp; break; case 'i': if ( (!IS_NPC(ch) && IS_SET(ch->act, PLR_WIZINVIS)) || (IS_NPC(ch) && IS_SET(ch->act, ACT_MOBINVIS)) ) sprintf(pbuf, "(Invis %d) ", (IS_NPC(ch) ? ch->mobinvis : ch->pcdata->wizinvis)); else if ( IS_AFFECTED(ch, AFF_INVISIBLE) ) sprintf(pbuf, "(Invis) " ); if ( ( !IS_NPC(ch) && IS_SET(ch->pcdata->flagstwo, MOREPC_INCOG) ) && ((!IS_NPC(ch) && IS_SET(ch->act, PLR_WIZINVIS)) || (IS_NPC(ch) && IS_SET(ch->act, ACT_MOBINVIS)) ) ) sprintf(pbuf,"(Incog %d) (Invis %d) ", ch->pcdata->incog_level, ch->pcdata->wizinvis ); else if ( ( !IS_NPC(ch) && IS_SET(ch->pcdata->flagstwo,MOREPC_INCOG) ) ) sprintf(pbuf,"(Incog %d) ", ch->pcdata->incog_level); break; case 'I': stat = (IS_NPC(ch) ? (IS_SET(ch->act, ACT_MOBINVIS) ? ch->mobinvis : 0) : (IS_SET(ch->act, PLR_WIZINVIS) ? ch->pcdata->wizinvis : 0)); break; case 'c': if(ch->fighting && ch->fighting->who ) { if ( ch->fighting->who->max_hit > 0 ) percent = ( 100 * ch->fighting->who->hit ) / ch->fighting->who->max_hit; else percent = -1; if ( percent >= 100 ) strcpy( fbuf, "perfect health"); else if ( percent >= 90 ) strcpy( fbuf, "slightly scratched"); else if ( percent >= 80 ) strcpy( fbuf, "few bruises"); else if ( percent >= 70 ) strcpy( fbuf, "some cuts"); else if ( percent >= 60 ) strcpy( fbuf, "several wounds"); else if ( percent >= 50 ) strcpy( fbuf, "nasty wounds"); else if ( percent >= 40 ) strcpy( fbuf, "bleeding freely"); else if ( percent >= 30 ) strcpy( fbuf, "covered in blood"); else if ( percent >= 20 ) strcpy( fbuf, "leaking guts"); else if ( percent >= 10 ) strcpy( fbuf, "almost dead"); else strcpy( fbuf, "DYING"); fbuf[0] = UPPER(fbuf[0]); } sprintf(pbuf,"%s",ch->fighting ? fbuf : " "); break; } if ( stat != 0x80000000 ) sprintf(pbuf, "%d", stat); pbuf += strlen(pbuf); break; } } *pbuf = '\0'; send_to_char(buf, ch); return; } /* * Dont let people using %u see invis immortals --GW */ int get_mortal_num_desc( CHAR_DATA *ch ) { int num; DESCRIPTOR_DATA *d; num = 0; for ( d = first_descriptor; d; d = d->next ) { if ( can_see( ch, d->character ) ) num++; } return num; } int make_color_sequence(const char *col, char *buf, DESCRIPTOR_DATA *d) { int ln; const char *ctype = col; unsigned char cl; CHAR_DATA *och; bool ansi=TRUE; och = (d->original ? d->original : d->character); if ( och ) ansi = (!IS_NPC(och) && IS_SET(och->act, PLR_ANSI)); col++; if ( !*col ) ln = -1; else if ( *ctype != '&' && *ctype != '^' ) { bug("Make_color_sequence: command '%c' not '&' or '^'.", *ctype); ln = -1; } else if ( *col == *ctype ) { buf[0] = *col; buf[1] = '\0'; ln = 1; } else if ( !ansi ) ln = 0; else { cl = d->prevcolor; switch(*ctype) { default: bug( "Make_color_sequence: bad command char '%c'.", *ctype ); ln = -1; break; case '&': if ( *col == '-' ) { buf[0] = '~'; buf[1] = '\0'; ln = 1; break; } case '^': { int newcol; if ( (newcol = getcolor(*col)) < 0 ) { ln = 0; break; } else if ( *ctype == '&' ) cl = (cl & 0xF0) | newcol; else cl = (cl & 0x0F) | (newcol << 4); } if ( cl == d->prevcolor ) { ln = 0; break; } strcpy(buf, "\033["); if ( (cl & 0x88) != (d->prevcolor & 0x88) ) { strcat(buf, "m\033["); if ( (cl & 0x08) ) strcat(buf, "1;"); if ( (cl & 0x80) ) strcat(buf, "5;"); d->prevcolor = 0x07 | (cl & 0x88); ln = strlen(buf); } else ln = 2; if ( (cl & 0x07) != (d->prevcolor & 0x07) ) { sprintf(buf+ln, "3%d;", cl & 0x07); ln += 3; } if ( (cl & 0x70) != (d->prevcolor & 0x70) ) { sprintf(buf+ln, "4%d;", (cl & 0x70) >> 4); ln += 3; } if ( buf[ln-1] == ';' ) buf[ln-1] = 'm'; else { buf[ln++] = 'm'; buf[ln] = '\0'; } d->prevcolor = cl; } } if ( ln <= 0 ) *buf = '\0'; return ln; } void set_pager_input( DESCRIPTOR_DATA *d, char *argument ) { while ( isspace(*argument) ) argument++; d->pagecmd = *argument; return; } bool pager_output( DESCRIPTOR_DATA *d ) { register char *last; CHAR_DATA *ch; int pclines; register int lines; bool ret; if ( !d || !d->pagepoint || d->pagecmd == -1 ) return TRUE; ch = d->original ? d->original : d->character; pclines = UMAX(ch->pcdata->pagerlen, 5) - 1; switch(LOWER(d->pagecmd)) { default: lines = 0; break; case 'b': lines = -1-(pclines*2); break; case 'r': lines = -1-pclines; break; case 'q': d->pagetop = 0; d->pagepoint = NULL; flush_buffer(d, TRUE); DISPOSE(d->pagebuf); d->pagesize = MAX_STRING_LENGTH; return TRUE; } while ( lines < 0 && d->pagepoint >= d->pagebuf ) if ( *(--d->pagepoint) == '\n' ) ++lines; if ( *d->pagepoint == '\n' && *(++d->pagepoint) == '\r' ) ++d->pagepoint; if ( d->pagepoint < d->pagebuf ) d->pagepoint = d->pagebuf; for ( lines = 0, last = d->pagepoint; lines < pclines; ++last ) if ( !*last ) break; else if ( *last == '\n' ) ++lines; if ( *last == '\r' ) ++last; if ( last != d->pagepoint ) { if ( !write_to_descriptor(d->descriptor, d->pagepoint, (last-d->pagepoint)) ) return FALSE; d->pagepoint = last; } while ( isspace(*last) ) ++last; if ( !*last ) { d->pagetop = 0; d->pagepoint = NULL; flush_buffer(d, TRUE); DISPOSE(d->pagebuf); d->pagesize = MAX_STRING_LENGTH; return TRUE; } d->pagecmd = -1; if ( IS_SET( ch->act, PLR_ANSI ) ) if ( write_to_descriptor(d->descriptor, "\033[1;36m", 7) == FALSE ) return FALSE; if ( (ret=write_to_descriptor(d->descriptor, "(C)ontinue, (R)efresh, (B)ack, (Q)uit: [C] ", 0)) == FALSE ) return FALSE; if ( IS_SET( ch->act, PLR_ANSI ) ) { char buf[32]; if ( d->pagecolor == 7 ) strcpy( buf, "\033[m" ); else sprintf(buf, "\033[0;%d;%s%dm", (d->pagecolor & 8) == 8, (d->pagecolor > 15 ? "5;" : ""), (d->pagecolor & 7)+30); ret = write_to_descriptor( d->descriptor, buf, 0 ); } return ret; } /* Warm reboot stuff, gotta make sure to thank Erwin for this :) */ void do_copyover (CHAR_DATA *ch, char * argument) { FILE *fp; DESCRIPTOR_DATA *d, *d_next; char buf [100], buf2[100], buf3[100], buf4[100], buf5[100], buf6[100]; disable_timer_abort = TRUE; fp = fopen (COPYOVER_FILE, "w"); if (!fp && ch ) { send_to_char ("Copyover file not writeable, aborted.\n\r",ch); log_printf ("Could not write to copyover file: %s", COPYOVER_FILE); perror ("do_copyover:fopen"); return; } /* Save the boot time and max players this boot --GW */ sysdata.boottime = boot_time; sysdata.max_plrs_boot = sysdata.maxplayers; save_sysdata(sysdata); /* Fix here for invis imms doing a warmboot, dont want name displayed*/ /* --GW */ /* strcpy(name,ch->name); if (IS_SET(ch->act,PLR_WIZINVIS)) strcpy(name,"Someone");*/ /* Nuke any challenges in progress */ challenge_cancel(NULL,NULL,"all"); stop_viewers(); /* Consider changing all saved areas here, if you use OLC */ /* do_asave (NULL, ""); - autosave changed areas */ strcpy(buf, "\n\rSwirls of Black Chaos Suddenly Surround You, as Your World Stops...\n\r "); /* For each playing descriptor, save its state */ for (d = first_descriptor; 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 < 0) /* drop those logging on */ { write_to_descriptor (d->descriptor, "\n\rSorry, we are rebooting." " Come back in a few minutes.\n\r", 0); close_socket (d, FALSE); /* throw'em out */ } else { fprintf (fp, "%d %s %s\n", d->descriptor, och->name, d->host); if (och->level == 1) { write_to_descriptor (d->descriptor, "Since you are level one," "and level one characters do not save, you gain a free level!\n\r", 0); advance_level (och,TRUE,1); och->level++; /* Advance_level doesn't do that */ } do_locker( och, "close" ); save_char_obj (och); write_to_descriptor (d->descriptor, buf, 0); } } fprintf (fp, "-1\n"); new_fclose (fp); /* Close reserve and other always-open files and release other resources */ /* Shutdown Web Server */ if ( sysdata.webserv == 1 ) shutdown_web(); // new_fclose (fpReserve); new_fclose (fpLOG); /* exec - descriptors are inherited */ /* Changed this abit .. as I have added 'arguments' to execution, this adds the -w if it is not there, which means 'Warmboot' --GW */ sprintf (buf, "%d", port); sprintf (buf2, "%d", control); if ( !mudarg_scan('W') ) /* Add the W if it isnt already there --GW */ sprintf (buf6, "-%sW", mudargs); else sprintf (buf6, "-%s", mudargs); execl (EXE_FILE, "AOTA", buf, buf6, buf2, buf3, buf4, buf5, (char *) NULL); /* Failed - sucessful exec will not return */ perror ("do_copyover: execl"); // send_to_char ("Copyover FAILED!\n\r",ch); /* Here you might want to reopen fpReserve */ /* Since I'm a neophyte type guy, I'll assume this is a good idea and cut and past from main() */ /* if ( ( fpReserve = fopen( NULL_FILE, "r" ) ) == NULL ) { perror( NULL_FILE ); exit( 1 ); }*/ if ( ( fpLOG = fopen( NULL_FILE, "r" ) ) == NULL ) { perror( NULL_FILE ); exit( 1 ); } } /* Recover from a copyover - load players */ void copyover_recover () { DESCRIPTOR_DATA *d=NULL; FILE *fp; char name [100]; char host[MAX_STRING_LENGTH]; int desc; bool fOld; ROOM_INDEX_DATA *location=NULL; char buf[MSL]; log_string ("Copyover recovery initiated"); num_descriptors=0; sysdata.maxplayers = sysdata.max_plrs_boot; fp = fopen (COPYOVER_FILE, "r"); if (!fp) /* there are some descriptors open which will hang forever then ? */ { perror ("copyover_recover:fopen"); log_string("Copyover file not found. Exitting.\n\r"); exit (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\rThe Planets Begin to realign, as Your World Slowly Takes Shape.\n\r",0)) { close (desc); /* nope */ continue; } d=NULL; CREATE(d, DESCRIPTOR_DATA, 1); init_descriptor (d, desc); /* set up various stuff */ d->host = STRALLOC( host ); LINK( d, first_descriptor, last_descriptor, next, prev ); d->connected = CON_COPYOVER_RECOVER; /* negative so close_socket will cut them off */ num_descriptors++; /* Now, find the pfile */ fOld = load_char_obj (d, name, FALSE); 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, FALSE); } else /* ok! */ { write_to_descriptor (desc, "\n\rA Blinding Light Fills Your Eyes, as a Stunning New Dawn Encompasses this World!\n\r",0); /* put the char back in the room --GW */ location=NULL; if ((location=get_room_index((int)d->character->pcdata->warm_to_room,1))!=NULL) { if ( d->character->in_room ) char_from_room(d->character); char_to_room(d->character,location); sprintf(buf,"WARMBOOT: putting %s back in room %d",capitalize(d->character->name),location->vnum); log_string_plus(buf,LOG_NORMAL,d->character->level); } /* Just In Case, Someone said this isn't necassary, but _why_ do we want to dump someone in limbo? */ if (!d->character->in_room) char_to_room(d->character,get_room_index(ROOM_VNUM_TEMPLE,1)); /* Insert in the char_list */ /* LINK( d->character, first_char, last_char, next, prev );*/ /*-->*/ add_char(d->character); /*might use this instead ..*/ area_reset_check(d->character->in_room); // char_to_room (d->character, d->character->in_room); d->character->pcdata->pre_name_toggle = 1; do_look (d->character, "auto noprog"); act (AT_ACTION, "$n materializes!", d->character, NULL, NULL, TO_ROOM); d->character->pcdata->arena_viewing = STRALLOC("None"); d->connected = CON_PLAYING; disable_timer_abort = FALSE; } } }