diff --exclude-from=dont-diff -u src/act_wiz.c src.copyover/act_wiz.c --- src/act_wiz.c Tue Jun 4 16:33:07 1996 +++ src.copyover/act_wiz.c Wed Jan 29 00:43:56 1997 @@ -4394,3 +4394,187 @@ ch->prefix = str_dup(argument); } + +#define CH(descriptor) ((descriptor)->original ? \ +(descriptor)->original : (descriptor)->character) + +/* This file holds the copyover data */ +#define COPYOVER_FILE "copyover.data" + +/* This is the executable file */ +#define EXE_FILE "../src/rom" + + +/* Copyover - Original idea: Fusion of MUD++ + * Adapted to Diku by Erwin S. Andreasen, <erwin@pip.dknet.dk> + * http://pip.dknet.dk/~pip1773 + * Changed into a ROM patch after seeing the 100th request for it :) + */ +void do_copyover (CHAR_DATA *ch, char * argument) +{ + FILE *fp; + DESCRIPTOR_DATA *d, *d_next; + char buf [100], buf2[100]; + extern int port,control; /* db.c */ + + fp = fopen (COPYOVER_FILE, "w"); + + if (!fp) + { + send_to_char ("Copyover file not writeable, aborted.\n\r",ch); + logf ("Could not write to copyover file: %s", COPYOVER_FILE); + perror ("do_copyover:fopen"); + return; + } + + /* Consider changing all saved areas here, if you use OLC */ + + /* do_asave (NULL, ""); - autosave changed areas */ + + + sprintf (buf, "\n\r *** COPYOVER by %s - please remain seated!\n\r", ch->name); + + /* For each playing descriptor, save its state */ + for (d = descriptor_list; d ; d = d_next) + { + CHAR_DATA * och = CH (d); + d_next = d->next; /* We delete from the list , so need to save this */ + + if (!d->character || d->connected > CON_PLAYING) /* drop those logging on */ + { + write_to_descriptor (d->descriptor, "\n\rSorry, we are rebooting. Come back in a few minutes.\n\r", 0); + close_socket (d); /* throw'em out */ + } + else + { + fprintf (fp, "%d %s %s\n", d->descriptor, och->name, d->host); + +#if 0 /* This is not necessary for ROM */ + 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); + och->level++; /* Advance_level doesn't do that */ + } +#endif + save_char_obj (och); + + write_to_descriptor (d->descriptor, buf, 0); + } + } + + fprintf (fp, "-1\n"); + fclose (fp); + + /* Close reserve and other always-open files and release other resources */ + + fclose (fpReserve); + + /* exec - descriptors are inherited */ + + sprintf (buf, "%d", port); + sprintf (buf2, "%d", control); + execl (EXE_FILE, "rom", buf, "copyover", buf2, (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 */ + fpReserve = fopen (NULL_FILE, "r"); +} + +/* Recover from a copyover - load players */ +void copyover_recover () +{ + DESCRIPTOR_DATA *d; + FILE *fp; + char name [100]; + char host[MSL]; + int desc; + bool fOld; + + logf ("Copyover recovery initiated"); + + fp = fopen (COPYOVER_FILE, "r"); + + if (!fp) /* there are some descriptors open which will hang forever then ? */ + { + perror ("copyover_recover:fopen"); + logf ("Copyover file not found. Exitting.\n\r"); + 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\rRestoring from copyover...\n\r",0)) + { + close (desc); /* nope */ + continue; + } + + d = new_descriptor(); + d->descriptor = desc; + + d->host = str_dup (host); + d->next = descriptor_list; + descriptor_list = d; + d->connected = CON_COPYOVER_RECOVER; /* -15, so close_socket frees the char */ + + + /* Now, find the pfile */ + + fOld = load_char_obj (d, name); + + if (!fOld) /* Player file not found?! */ + { + write_to_descriptor (desc, "\n\rSomehow, your character was lost in the copyover. Sorry.\n\r", 0); + close_socket (d); + } + else /* ok! */ + { + write_to_descriptor (desc, "\n\rCopyover recovery complete.\n\r",0); + + /* Just In Case */ + if (!d->character->in_room) + d->character->in_room = get_room_index (ROOM_VNUM_TEMPLE); + + /* Insert in the char_list */ + d->character->next = char_list; + char_list = d->character; + + char_to_room (d->character, d->character->in_room); + do_look (d->character, "auto"); + act ("$n materializes!", d->character, NULL, NULL, TO_ROOM); + d->connected = CON_PLAYING; + + if (d->character->pet != NULL) + { + char_to_room(d->character->pet,d->character->in_room); + act("$n materializes!.",d->character->pet,NULL,NULL,TO_ROOM); + } + } + + } + fclose (fp); + + +} + + + + + + + + + + + diff --exclude-from=dont-diff -u src/comm.c src.copyover/comm.c --- src/comm.c Tue Jun 4 16:33:07 1996 +++ src.copyover/comm.c Tue Jan 28 23:33:04 1997 @@ -56,6 +56,7 @@ #include <string.h> #include <stdlib.h> #include <time.h> +#include <stdarg.h> #include "merc.h" #include "recycle.h" @@ -165,8 +166,6 @@ #endif #if defined(linux) -int accept args( ( int s, struct sockaddr *addr, int *addrlen ) ); -int bind args( ( int s, struct sockaddr *name, int namelen ) ); int close args( ( int fd ) ); int getpeername args( ( int s, struct sockaddr *name, int *namelen ) ); int getsockname args( ( int s, struct sockaddr *name, int *namelen ) ); @@ -337,15 +336,13 @@ void stop_idling args( ( CHAR_DATA *ch ) ); void bust_a_prompt args( ( CHAR_DATA *ch ) ); +/* Needs to be global because of do_copyover */ +int port, control; int main( int argc, char **argv ) { struct timeval now_time; - int port; - -#if defined(unix) - int control; -#endif + bool fCopyOver = FALSE; /* * Memory debugging if needed. @@ -396,22 +393,39 @@ fprintf( stderr, "Port number must be above 1024.\n" ); exit( 1 ); } + + /* Are we recovering from a copyover? */ + if (argv[2] && argv[2][0]) + { + fCopyOver = TRUE; + control = atoi(argv[3]); + } + else + fCopyOver = FALSE; + } /* * Run the game. */ #if defined(macintosh) || defined(MSDOS) - boot_db( ); + boot_db(); log_string( "Merc is ready to rock." ); game_loop_mac_msdos( ); #endif #if defined(unix) - control = init_socket( port ); - boot_db( ); + + if (!fCopyOver) + control = init_socket( port ); + + boot_db(); sprintf( log_buf, "ROM is ready to rock on port %d.", port ); log_string( log_buf ); + + if (fCopyOver) + copyover_recover(); + game_loop_unix( control ); close (control); #endif @@ -850,6 +864,7 @@ #if defined(unix) + void init_descriptor( int control ) { char buf[MAX_STRING_LENGTH]; @@ -880,14 +895,8 @@ /* * Cons a new descriptor. */ - dnew = new_descriptor(); - - dnew->descriptor = desc; - dnew->connected = CON_GET_NAME; - dnew->showstr_head = NULL; - dnew->showstr_point = NULL; - dnew->outsize = 2000; - dnew->outbuf = alloc_mem( dnew->outsize ); + dnew = new_descriptor(); /* new_descriptor now also allocates things */ + dnew->descriptor = desc; size = sizeof(sock); if ( getpeername( desc, (struct sockaddr *) &sock, &size ) < 0 ) @@ -2552,3 +2561,15 @@ tp->tv_usec = 0; } #endif + +void logf (char * fmt, ...) +{ + char buf [2*MSL]; + va_list args; + va_start (args, fmt); + vsprintf (buf, fmt, args); + va_end (args); + + log_string (buf); +} + diff --exclude-from=dont-diff -u src/db.c src.copyover/db.c --- src/db.c Tue Jun 4 16:33:07 1996 +++ src.copyover/db.c Tue Jan 28 23:23:54 1997 @@ -232,7 +232,7 @@ /* * Big mama top level function. */ -void boot_db( void ) +void boot_db() { /* @@ -388,7 +388,7 @@ load_bans(); load_songs(); } - + return; } diff --exclude-from=dont-diff -u src/interp.c src.copyover/interp.c --- src/interp.c Tue Jun 4 16:33:08 1996 +++ src.copyover/interp.c Tue Jan 28 23:16:41 1997 @@ -289,6 +289,7 @@ * Immortal commands. */ { "advance", do_advance, POS_DEAD, ML, LOG_ALWAYS, 1 }, + { "copyover", do_copyover,POS_DEAD, ML, LOG_ALWAYS, 1 }, { "dump", do_dump, POS_DEAD, ML, LOG_ALWAYS, 0 }, { "trust", do_trust, POS_DEAD, ML, LOG_ALWAYS, 1 }, { "violate", do_violate, POS_DEAD, ML, LOG_ALWAYS, 1 }, diff --exclude-from=dont-diff -u src/interp.h src.copyover/interp.h --- src/interp.h Tue Jun 4 16:33:08 1996 +++ src.copyover/interp.h Tue Jan 28 23:15:15 1997 @@ -101,6 +101,7 @@ DECLARE_DO_FUN( do_compact ); DECLARE_DO_FUN( do_compare ); DECLARE_DO_FUN( do_consider ); +DECLARE_DO_FUN( do_copyover ); DECLARE_DO_FUN( do_count ); DECLARE_DO_FUN( do_credits ); DECLARE_DO_FUN( do_deaf ); diff --exclude-from=dont-diff -u src/merc.h src.copyover/merc.h --- src/merc.h Tue Jun 4 16:33:09 1996 +++ src.copyover/merc.h Tue Jan 28 23:25:47 1997 @@ -121,6 +121,10 @@ #define MAX_INPUT_LENGTH 256 #define PAGELEN 22 +/* I am lazy :) */ +#define MSL MAX_STRING_LENGTH +#define MIL MAX_INPUT_LENGTH + /* @@ -241,7 +245,7 @@ #define CON_READ_IMOTD 13 #define CON_READ_MOTD 14 #define CON_BREAK_CONNECT 15 - +#define CON_COPYOVER_RECOVER 16 /* @@ -2123,6 +2127,8 @@ void nuke_pets args( ( CHAR_DATA *ch ) ); void die_follower args( ( CHAR_DATA *ch ) ); bool is_same_group args( ( CHAR_DATA *ach, CHAR_DATA *bch ) ); +void logf args((char * fmt, ...)); + /* act_enter.c */ RID *get_random_room args ( (CHAR_DATA *ch) ); @@ -2142,6 +2148,8 @@ /* act_wiz.c */ void wiznet args( (char *string, CHAR_DATA *ch, OBJ_DATA *obj, long flag, long flag_skip, int min_level ) ); +void copyover_recover args((void)); + /* alias.c */ void substitute_alias args( (DESCRIPTOR_DATA *d, char *input) ); Only in src.copyover: mob_cmds.c Only in src.copyover: mob_cmds.h Only in src.copyover: mob_prog.c diff --exclude-from=dont-diff -u src/recycle.c src.copyover/recycle.c --- src/recycle.c Mon Oct 23 18:52:29 1995 +++ src.copyover/recycle.c Tue Jan 28 23:30:16 1997 @@ -125,6 +125,13 @@ *d = d_zero; VALIDATE(d); + + d->connected = CON_GET_NAME; + d->showstr_head = NULL; + d->showstr_point = NULL; + d->outsize = 2000; + d->outbuf = alloc_mem( d->outsize ); + return d; }