#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include "mud.h"
#ifdef USE_IMC
#include "imc.h"
#include "icec.h"
#endif
/* Globals */
int control;
int control2;
int conjava;
int conclient;
/* Externals */
char *help_fix args( ( char *text ) );
/*
* Copyover "do" Function -Nopey
* 6/11/01
*/
void do_copyover( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
argument = one_argument( argument, arg );
/* if there is no arg supplied */
if( arg[0] == '\0' )
{
send_to_char_color( "\n\r&YSyntax: copyover saveall\n\r", ch );
send_to_char_color( "Syntax: copyover nosave&g\n\r", ch );
return;
}
/* saves all data */
if( !str_cmp( arg, "saveall" ) )
{
log_string( "Copyover: Saving Game Data..." );
save_gamedata();
log_string( "Copyover Save: Game Data Saved. Performing Copyover..." );
copyover();
return;
}
/* saves nothing */
if( !str_cmp( arg, "nosave" ) )
{
log_string( "Copyover NoSave: Performing Copyover..." );
copyover();
return;
}
}
/*
* Actual Copyover "Beef" Function -Nopey
*/
void copyover()
{
FILE *fp;
DESCRIPTOR_DATA *d = NULL;
char buf2[100], buf3[100], buf4[100], buf5[100], buf6[100];
fp = fopen( COPYOVER_FILE, "w" );
#ifdef USE_IMC
log_string( "Copyover: Initiating IMC2 shutdown..." );
imc_shutdown();
log_string( "Copyover: IMC2 Shutdown Complete." );
#endif
for( d = first_descriptor; d; d = d->next )
{
write_to_buffer( d, "Copyover: Copyover has been initiated. Hold on.\n\r", 0 );
/* drop those logging on */
if( !d->character || d->connected != CON_PLAYING )
{
write_to_buffer( d, "Sorry the game is currently in a copyover. Please come back in a minute or so.\n\r", 0 );
close_socket( d, FALSE );
}
else
{
#ifdef I3
I3_close_char( d );
#endif
if( d->character->top_level == 1 )
{
write_to_descriptor( d->descriptor, "Since you are level one, and level ones are not saved, you gain a level!\n\r", 0 );
fprintf( fp, "%d %d %d %d %s %s %s\n", d->descriptor, d->port, ROOM_VNUM_TEMPLE, d->idle, d->character->name, d->user, d->host );
advance_level(d->character, 1);
d->character->top_level++;
} else
fprintf( fp, "%d %d %d %d %s %s %s\n", d->descriptor, d->port, d->character->in_room->vnum, d->idle, d->character->name, d->user, d->host );
}
}
fprintf (fp, "-1\n");
fclose( fp );
#ifdef I3
log_string( "Initiating Intermud-3 shutdown...." );
I3_shutdown( 0 );
log_string( "Intermud-3 shutdown completed." );
#endif
log_string( "Initiating Copyover." );
fclose( fpReserve );
fclose( fpLOG );
/* exec - descriptors are inherited */
sprintf( buf2, "%d", port );
sprintf( buf3, "%d", control );
sprintf( buf4, "%d", control2 );
sprintf( buf5, "%d", conclient );
sprintf( buf6, "%d", conjava );
/* execute the file */
execl( EXE_FILE, "smaug", buf2, "copyover", buf3, buf4, buf5, buf6, (char*)NULL );
/* 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 );
}
log_string( "Copyover FAILED!" );
perror( "Copyover: Execl" );
}
/*
* Copyover Recover
* Rewritten 6/14/01 -Nopey
*/
void copyover_recover()
{
DESCRIPTOR_DATA *d = NULL;
FILE *fp;
char name [100];
char host[MAX_STRING_LENGTH];
char user[MAX_INPUT_LENGTH]; /* 6/24/01 - User fix - Nopey */
char buf[MAX_INPUT_LENGTH];
int desc;
int dport; /* 6/24/01 - Port fix - Nopey */
int idle; /* 6/24/01 - Idle fix - Nopey */
bool fOld;
int room;
fp = fopen( COPYOVER_FILE, "r" );
/* there are some descriptors open which will hang forever then ? */
if( !fp )
{
perror("Copyver: copyover_recover:fopen");
log_string( "Copyover File not Found. Exiting.");
exit( 1 );
}
log_string( "Copyover: Recovering Character Links..." );
/* In case something crashes - doesn't prevent reading */
unlink( COPYOVER_FILE );
/* unlink( MOBSAVE_FILE );
unlink( OBJSAVE_FILE ); */
for( ; ; )
{
fscanf( fp, "%d %d %d %d %s %s %s\n", &desc, &dport, &room, &idle, name, user, host );
if( desc == -1 )
break;
/* Write something, and check if it goes error-free */
if(!write_to_descriptor(desc, "\n\rCopyover: Restoring your link.\n\r", 0))
close( desc ); /* nope */
/* boot up the descriptor! */
CREATE( d, DESCRIPTOR_DATA, 1 );
d->next = NULL;
d->descriptor = desc;
d->connected = CON_GET_NAME;
d->outsize = 2000;
d->idle = 0;
d->lines = 0;
d->scrlen = 24;
d->newstate = 0;
d->prevcolor = 0x07;
CREATE( d->outbuf, char, d->outsize );
d->user = STRALLOC( user );
d->host = STRALLOC( host );
d->port = dport;
d->idle = idle;
LINK( d, first_descriptor, last_descriptor, next, prev );
d->connected = CON_COPYOVER_RECOVER;
/* Now, find the pfile */
fOld = load_char_obj( d, name, FALSE );
/* No pfile? */
if( !fOld )
{
write_to_descriptor( desc, "Copyover: Somehow your Character was lost during the Copyover. Please contact an Immortal.\n\r", 0 );
close_socket (d, FALSE);
}
else /* ok! */
{
d->character->in_room = get_room_index( room );
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 );
num_descriptors++;
sysdata.maxplayers++;
/* send to the room */
char_to_room( d->character, d->character->in_room );
#ifdef I3
I3_char_login( d->character );
#endif
d->connected = CON_PLAYING;
do_look( d->character, "auto noprog" );
act( AT_YELLOW, "$n magically arrives in a puff of grey smoke.", d->character, NULL, NULL, TO_ROOM);
sprintf( buf, "\n\rWelcome back, %s.\n\r", d->character->name );
write_to_buffer( d, buf, 0 );
}
}
log_string( "Copyover Sucessful. Resuming Play." );
fclose( fp );
return;
}
/*
* Not sure if this is even used anymore... oh well
*/
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);
}
/*
* Decided to Clean the code up even more -Nopey
* Left here for upgrades so that the people
* don't need to get old init_descriptor.
* **NOTE** If your NOT upgrading, comment this out.
*/
void init_descriptor( DESCRIPTOR_DATA *d, int desc)
{
d->next = NULL;
d->descriptor = desc;
d->connected = CON_GET_NAME;
d->outsize = 2000;
d->idle = 0;
d->lines = 0;
d->scrlen = 24;
d->newstate = 0;
d->prevcolor = 0x07;
CREATE( d->outbuf, char, d->outsize );
}
void save_gamedata()
{
char filename[256];
FILE *fpout;
AREA_DATA *tarea;
CHAR_DATA *victim;
HELP_DATA *pHelp;
for( victim = first_char; victim; victim = victim->next )
{
/* save character */
save_char_obj( victim );
pager_printf_color( victim, "&YYou have been manually due to a copyover.\n\r" );
}
/* save area files */
for( tarea = first_build; tarea; tarea = tarea->next )
{
if( !IS_SET( tarea->status, AREA_LOADED ) )
{
continue;
}
sprintf( filename, "%s%s", BUILD_DIR, tarea->filename );
fold_area( tarea, filename, FALSE );
}
rename( "help.are", "help.are.bak" );
log_string( "Saving help.are..." );
fclose( fpReserve );
if ( ( fpout = fopen( "help.are", "w" ) ) == NULL )
{
bug( "hset save: fopen", 0 );
perror( "help.are" );
fpReserve = fopen( NULL_FILE, "r" );
return;
}
fprintf( fpout, "#HELPS\n\n" );
for ( pHelp = first_help; pHelp; pHelp = pHelp->next )
fprintf( fpout, "%d %s~\n%s~\n\n",
pHelp->level, pHelp->keyword, help_fix(pHelp->text) );
fprintf( fpout, "0 $~\n\n\n#$\n" );
fclose( fpout );
fpReserve = fopen( NULL_FILE, "r" );
save_commands();
save_socials();
save_skill_table();
save_herb_table();
return;
}