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@andreasen.org>
+ * http://www.andreasen.org
+ * 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;
}