/*Copyright by Erwin Andreasen, 2000*/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "db.h" #include "recycle.h" #include "unistd.h" DECLARE_DO_FUN(do_look); void do_copyove (CHAR_DATA *ch, char *argument) { send_to_char("If you want to COPYOVER, spell it out.\n\r",ch); return; } void do_copyover (CHAR_DATA *ch, char * argument) { FILE *fp; DESCRIPTOR_DATA *d, *d_next; char buf [100], buf2[100],buf3[100]; fp = fopen (COPYOVER_FILE, "w"); if (!fp) { send_to_char ("Copyover file not writeable, aborted.\n\r",ch); bug ("Could not write to copyover file",0); perror ("do_copyover:fopen"); return; } /* Consider changing all saved areas here, if you use OLC */ do_asave (NULL, "");/* - autosave changed areas */ save_sockets(); save_ranks(); 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 (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); /* exec - descriptors are inherited */ sprintf (buf, "%d", port); sprintf (buf2, "%d", control); sprintf (buf3, "%d", wwwcontrol); execl (EXE_FILE, "rot","copyover", buf2, buf3, (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[MAX_STRING_LENGTH]; int desc; bool fOld; bug ("Copyover recovery initiated",0); fp = fopen (COPYOVER_FILE, "r"); if (!fp) /* there are some descriptors open which will hang forever then ? */ { perror ("copyover_recover:fopen"); bug ("Copyover file not found. Exitting.\n\r",0); 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 = alloc_perm (sizeof(DESCRIPTOR_DATA)); init_descriptor2 (d,desc); /* set up various stuff */ d->host = str_dup (host); d->next = descriptor_list; descriptor_list = d; d->connected = /*CON_COPYOVER_RECOVER*/ -15; /* -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; d->character->pcdata->socket=str_dup(host); d->ip=str_dup(host); conn_so_far++; char_to_room (d->character, d->character->in_room); if(d->character->pet) char_to_room(d->character->pet,d->character->in_room); do_look (d->character, ""); act ("$n materializes!", d->character, NULL, NULL, TO_ROOM); if(d->character->pet) act("$n materializes!", d->character->pet,NULL,NULL,TO_ROOM); d->connected = CON_PLAYING; reset_char(d->character); } } fclose (fp); }