From jgoodwin@expert.cc.purdue.edu Tue Apr 8 22:16:20 1997
Date: Sun, 2 Mar 1997 22:34:14 -0500 (EST)
From: Walter Goodwin <jgoodwin@expert.cc.purdue.edu>
To: erwin@andreasen.org
Subject: Re: Copyover Patch completed for stock 1.02
diff -u dist/src/comm.c tmp/src/comm.c
--- dist/src/comm.c Sun Mar 2 20:54:50 1997
+++ tmp/src/comm.c Sun Mar 2 20:41:34 1997
@@ -67,6 +67,7 @@
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 control2; /* Controlling descriptor #2 */
int conclient; /* MUDClient controlling desc */
@@ -111,12 +112,10 @@
void mail_count args( ( CHAR_DATA *ch ) );
-
-
int main( int argc, char **argv )
{
struct timeval now_time;
- int port;
+ bool fCopyOver = !TRUE;
/*
* Memory debugging if needed.
@@ -199,18 +198,32 @@
fprintf( stderr, "Port number must be above 1024.\n" );
exit( 1 );
}
- }
+
+ if (argv[2] && argv[2][0])
+ {
+ fCopyOver = TRUE;
+ control = atoi(argv[3]);
+ control2 = atoi(argv[4]);
+ conclient = atoi(argv[5]);
+ conjava = atoi(argv[6]);
+ }
+ else
+ fCopyOver = FALSE;
+ }
/*
* Run the game.
*/
log_string("Booting Database");
- boot_db( );
+ boot_db(fCopyOver);
log_string("Initializing socket");
- control = init_socket( port );
- control2 = init_socket( port+1 );
- conclient= init_socket( port+10);
- conjava = init_socket( port+20);
+ if (!fCopyOver) /* We have already the port if copyover'ed */
+ {
+ control = init_socket (port);
+ control2 = init_socket( port+1 );
+ conclient= init_socket( port+10);
+ conjava = init_socket( port+20);
+ }
sprintf( log_buf, "Realms of Despair ready on port %d.", port );
log_string( log_buf );
game_loop( );
@@ -481,7 +494,6 @@
continue;
}
}
-
/* IDENT authentication */
if ( ( d->auth_fd == -1 ) && ( d->atimes < 20 )
&& !str_cmp( d->user, "unknown" ) )
@@ -644,6 +656,25 @@
return;
}
+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 );
+}
+
void new_descriptor( int new_desc )
{
@@ -690,24 +721,11 @@
}
if ( check_bad_desc( new_desc ) )
return;
-
CREATE( dnew, DESCRIPTOR_DATA, 1 );
- dnew->next = NULL;
- dnew->descriptor = desc;
- dnew->connected = CON_GET_NAME;
- dnew->outsize = 2000;
- dnew->idle = 0;
- dnew->lines = 0;
- dnew->scrlen = 24;
- dnew->port = ntohs( sock.sin_port );
- 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 );
+ init_descriptor(dnew, desc );
+ dnew->port = ntohs(sock.sin_port);
+
strcpy( buf, inet_ntoa( sock.sin_addr ) );
sprintf( log_buf, "Sock.sinaddr: %s, port %hd.",
@@ -2446,7 +2464,19 @@
send_to_pager(buf, ch);
}
+/* From Erwin */
+
+void log_printf(char *fmt, ...)
+{
+ char buf[MAX_STRING_LENGTH*2];
+ va_list args;
+
+ va_start(args, fmt);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+ log_string(buf);
+}
char *obj_short( OBJ_DATA *obj )
{
@@ -3128,3 +3158,169 @@
}
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];
+
+ fp = fopen (COPYOVER_FILE, "w");
+
+ if (!fp)
+ {
+ 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;
+ }
+
+ /* 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 = 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 != 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, 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);
+ och->level++; /* Advance_level doesn't do that */
+ }
+ 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);
+ fclose (fpLOG);
+
+ /* exec - descriptors are inherited */
+
+ sprintf (buf, "%d", port);
+ sprintf (buf2, "%d", control);
+ sprintf (buf3, "%d", control2);
+ sprintf (buf4, "%d", conclient);
+ sprintf (buf5, "%d", conjava);
+
+ execl (EXE_FILE, "smaug", buf, "copyover", 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;
+ FILE *fp;
+ char name [100];
+ char host[MAX_STRING_LENGTH];
+ int desc;
+ bool fOld;
+
+ log_string ("Copyover recovery initiated");
+
+ 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\rRestoring from copyover...\n\r", 0))
+ {
+ close (desc); /* nope */
+ continue;
+ }
+
+ 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 */
+
+ /* 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\rCopyover recovery complete.\n\r",0);
+
+ /* Just In Case, Someone said this isn't necassary, but _why_
+ do we want to dump someone in limbo? */
+ if (!d->character->in_room)
+ d->character->in_room = get_room_index (ROOM_VNUM_TEMPLE);
+
+ /* Insert in the char_list */
+ LINK( d->character, first_char, last_char, next, prev );
+
+ char_to_room (d->character, d->character->in_room);
+ do_look (d->character, "auto noprog");
+ act (AT_ACTION, "$n materializes!", d->character, NULL, NULL, TO_ROOM);
+ d->connected = CON_PLAYING;
+ }
+
+ }
+ fclose (fp);
+}
+
diff -u dist/src/db.c tmp/src/db.c
--- dist/src/db.c Thu Feb 6 09:22:48 1997
+++ tmp/src/db.c Thu Feb 27 15:06:32 1997
@@ -294,7 +294,7 @@
/*
* Big mama top level function.
*/
-void boot_db( void )
+void boot_db( bool fCopyOver )
{
sh_int wear, x;
@@ -601,6 +601,11 @@
log_string( "Loading corpses" );
load_corpses( );
MOBtrigger = TRUE;
+ if (fCopyOver)
+ {
+ log_string("Running copyover_recover.");
+ copyover_recover();
+ }
}
/* init_maps ( ); */
diff -u dist/src/mud.h tmp/src/mud.h
--- dist/src/mud.h Thu Feb 6 09:22:50 1997
+++ tmp/src/mud.h Sun Mar 2 20:40:49 1997
@@ -336,15 +336,30 @@
/*
* Connected state for a channel.
*/
-typedef enum
-{
- CON_PLAYING, CON_GET_NAME, CON_GET_OLD_PASSWORD,
- CON_CONFIRM_NEW_NAME, CON_GET_NEW_PASSWORD, CON_CONFIRM_NEW_PASSWORD,
- CON_GET_NEW_SEX, CON_GET_NEW_CLASS, CON_READ_MOTD,
- CON_GET_NEW_RACE, CON_GET_EMULATION, CON_EDITING,
- CON_GET_WANT_RIPANSI, CON_TITLE, CON_PRESS_ENTER,
- CON_WAIT_1, CON_WAIT_2, CON_WAIT_3,
- CON_ACCEPTED, CON_GET_PKILL, CON_READ_IMOTD
+typedef enum {
+ CON_GET_NAME = -100,
+ CON_GET_OLD_PASSWORD,
+ CON_CONFIRM_NEW_NAME,
+ CON_GET_NEW_PASSWORD,
+ CON_CONFIRM_NEW_PASSWORD,
+ CON_GET_NEW_SEX,
+ CON_GET_NEW_CLASS,
+ CON_READ_MOTD,
+ CON_GET_NEW_RACE,
+ CON_GET_EMULATION,
+ CON_GET_WANT_RIPANSI,
+ CON_TITLE,
+ CON_PRESS_ENTER,
+ CON_WAIT_1,
+ CON_WAIT_2,
+ CON_WAIT_3,
+ CON_ACCEPTED,
+ CON_GET_PKILL,
+ CON_READ_IMOTD,
+ CON_COPYOVER_RECOVER,
+
+ CON_PLAYING = 0,
+ CON_EDITING
} connection_types;
/*
@@ -2451,6 +2466,7 @@
#define SET_BIT(var, bit) ((var) |= (bit))
#define REMOVE_BIT(var, bit) ((var) &= ~(bit))
#define TOGGLE_BIT(var, bit) ((var) ^= (bit))
+#define CH(d) ((d)->original ? (d)->original : (d)->character)
/*
* Memory allocation macros.
@@ -3014,6 +3030,7 @@
DECLARE_DO_FUN( do_compare );
DECLARE_DO_FUN( do_config );
DECLARE_DO_FUN( do_consider );
+DECLARE_DO_FUN( do_copyover );
DECLARE_DO_FUN( do_council_induct);
DECLARE_DO_FUN( do_council_outcast);
DECLARE_DO_FUN( do_councils );
@@ -3570,8 +3587,11 @@
#define USAGE_FILE SYSTEM_DIR "usage.txt" /* How many people are on
every half hour - trying to
determine best reboot time */
+#define COPYOVER_FILE SYSTEM_DIR "copyover.dat" /* for warm reboots */
+#define EXE_FILE "../src/smaug" /* executable path */
#define CLASSDIR "../classes/"
+
/*
* Our function prototypes.
* One big lump ... this is every function in Merc.
@@ -3689,8 +3709,10 @@
void set_pager_color args( ( sh_int AType, CHAR_DATA *ch ) );
void ch_printf args( ( CHAR_DATA *ch, char *fmt, ... ) );
void pager_printf args( (CHAR_DATA *ch, char *fmt, ...) );
+void log_printf args( (char *fmt, ...) );
void act args( ( sh_int AType, const char *format, CHAR_DATA *ch,
const void *arg1, const void *arg2, int type ) );
+void copyover_recover args( (void) );
/* reset.c */
RD * make_reset args( ( char letter, int extra, int arg1, int arg2, int arg3 ) );
@@ -3701,7 +3723,7 @@
/* db.c */
void show_file args( ( CHAR_DATA *ch, char *filename ) );
char * str_dup args( ( char const *str ) );
-void boot_db args( ( void ) );
+void boot_db args( ( bool fCopyOver ) );
void area_update args( ( void ) );
void add_char args( ( CHAR_DATA *ch ) );
CD * create_mobile args( ( MOB_INDEX_DATA *pMobIndex ) );
@@ -4398,3 +4420,4 @@
#define GET_ADEPT(ch,sn) ( skill_table[(sn)]->skill_adept[(ch)->class])
+
Only in dist/src: smaug
diff -u dist/src/tables.c tmp/src/tables.c
--- dist/src/tables.c Thu Feb 6 09:22:50 1997
+++ tmp/src/tables.c Thu Feb 27 15:30:48 1997
@@ -211,6 +211,7 @@
if ( !str_cmp( name, "do_council_outcast" )) return do_council_outcast;
if ( !str_cmp( name, "do_councils" )) return do_councils;
if ( !str_cmp( name, "do_counciltalk" )) return do_counciltalk;
+ if ( !str_cmp( name, "do_copyover" )) return do_copyover;
if ( !str_cmp( name, "do_credits" )) return do_credits;
if ( !str_cmp( name, "do_cset" )) return do_cset;
break;
@@ -730,6 +731,7 @@
if ( skill == do_compare ) return "do_compare";
if ( skill == do_config ) return "do_config";
if ( skill == do_consider ) return "do_consider";
+ if ( skill == do_copyover ) return "do_copyover";
if ( skill == do_council_induct ) return "do_council_induct";
if ( skill == do_council_outcast ) return "do_council_outcast";
if ( skill == do_councils ) return "do_councils";