#include <unistd.h> #include <stdlib.h> #include "kernel.h" #include "objsys.h" #include "mobile.h" #include "update.h" #include "pflags.h" #include "log.h" #include "fight.h" void write_zones(void); void run_update (void) { UPDATE_IDX_REC update_idx; char fn[25]; FILE *fp; sprintf (fn, "%s/update.data.%d", TEMP_DIR, getpid ()); if ((fp = FOPEN (fn, "wb")) == NULL) { return; } update_idx.qdone = qdone; update_idx.mudzones = num_const_zon; update_idx.mudlocs = num_const_locs; update_idx.mudobjs = num_const_obs; update_idx.mudchars = num_const_chars - max_players; update_idx.mobnum = save_mobiles (); update_idx.objnum = save_objects (); fwrite (&update_idx, sizeof (update_idx), 1, fp); FCLOSE (fp); write_zones (); } void update_world (int num) { UPDATE_IDX_REC update_idx; char fn[25]; int i; FILE *fp; sprintf (fn, "%s/update.data.%d", TEMP_DIR, num); if ((fp = FOPEN (fn, "rb")) == NULL) { mudlog ("UPDATE: Error: Cannot read file %s", fn); return; } fread (&update_idx, sizeof (update_idx), 1, fp); FCLOSE (fp); check_update (num); qdone = update_idx.qdone; read_mobiles (update_idx.mobnum, num); read_objects (update_idx.objnum, num); for (i = 0 ; i < numchars ; i++) if (is_in_game(i)) reset_armor(True, i); unlink (fn); } /* Checks to see if the world has changed any. It checks for new zones, * new locations, new mobiles, and new objects. It then logs a warning * that data has been changed. This is to let people know that something * could go wrong with the update since data has been changed. */ int check_update (int num) { UPDATE_IDX_REC data; Boolean error = False; char fn[25]; FILE *fp; sprintf (fn, "%s/update.data.%d", TEMP_DIR, num); if ((fp = FOPEN (fn, "rb")) == NULL) { mudlog ("UPDATE: Error: Cannot read file %s", fn); return -1; } fread (&data, sizeof (data), 1, fp); FCLOSE (fp); if (num_const_zon != data.mudzones) { mudlog ("UPDATE: Warning: Number of zones has been changed"); error = True; } if (num_const_locs != data.mudlocs) { mudlog ("UPDATE: Warning: Number of locations has been changed"); error = True; } if (num_const_chars - max_players != data.mudchars) { mudlog ("UPDATE: Warning: Number of characters has been changed"); error = True; } if (num_const_obs != data.mudobjs) { mudlog ("UPDATE: Warning: Number of objects has been changed"); error = True; } if (error) mudlog ("UPDATE: This could cause problems with updated data"); return error; } /* Save the mobiles and return the number saved. */ int save_mobiles (void) { UPDATE_MOBILE_REC data; int mob, idx = 0; char fn[25]; FILE *fp; sprintf (fn, "%s/mobiles.update.%d", TEMP_DIR, getpid ()); if ((fp = FOPEN (fn, "wb")) == NULL) { mudlog ("UPDATE: Error: Cannot create file %s", fn); return -1; } for (mob = max_players; mob < numchars; mob++) { if (ploc (mob) != ploc_reset (mob) || pstr (mob) != pstr_reset (mob)) { ++idx; data.num = mob; data.str = pstr (mob); data.loc = ploc (mob); data.score = pscore (mob); fwrite (&data, sizeof (data), 1, fp); } } FCLOSE (fp); return idx; } /* Save the objects and return the number saved. */ int save_objects (void) { UPDATE_OBJECT_REC data; int obj, idx = 0; char fn[25]; FILE *fp; sprintf (fn, "%s/objects.update.%d", TEMP_DIR, getpid ()); if ((fp = FOPEN (fn, "wb")) == NULL) { mudlog ("UPDATE: Error: Cannot create file %s", fn); return -1; } for (obj = 0; obj < numobs; obj++) { if (oloc (obj) != oloc_reset (obj) || ocarrf (obj) != ocarrf_reset (obj) || !eqbits(obits(obj), obits_reset(obj)) || state (obj) != state_reset (obj)) { ++idx; data.num = onum (obj); data.loc = oloc (obj); data.state = state (obj); data.carrflg = ocarrf (obj); data.flags_h = objects[obj].oflags.h; data.flags_l = objects[obj].oflags.l; fwrite (&data, sizeof (data), 1, fp); } } FCLOSE (fp); return idx; } /* Reads in the mobiles data file. */ void read_mobiles (int mob, int fnum) { UPDATE_MOBILE_REC data; int idx; char fn[25]; FILE *fp; sprintf (fn, "%s/mobiles.update.%d", TEMP_DIR, fnum); if ((fp = FOPEN (fn, "rb")) == NULL) { mudlog ("UPDATE: Error: Cannot read file %s", fn); return; } for (idx = 0; idx < mob; idx++) { fread (&data, sizeof (data), 1, fp); setploc (data.num, data.loc); setpstr (data.num, data.str); setpscore (data.num, data.score); } FCLOSE (fp); unlink (fn); } void read_objects (int obj, int fnum) { UPDATE_OBJECT_REC data; int idx; char fn[25]; FILE *fp; sprintf (fn, "%s/objects.update.%d", TEMP_DIR, fnum); if ((fp = FOPEN (fn, "rb")) == NULL) { mudlog ("UPDATE: Error: Cannot read file %s", fn); return; } for (idx = 0; idx < obj; idx++) { fread (&data, sizeof (data), 1, fp); setoloc (data.num, data.loc, data.carrflg); setobjstate (data.num, data.state); objects[data.num].oflags.h = data.flags_h; objects[data.num].oflags.l = data.flags_l; } FCLOSE (fp); unlink (fn); } void write_zones() { int i; FILE *fp; char filename[40]; /* save cloned rooms */ for (i = 0 ; i < max_players ; i++) if (is_in_game(i) && ptstflg(i, PFL_CLONE)) storecom(pname(i), True); /* store list of cloned zones to load */ sprintf (filename, "%s/update.zones.%d", TEMP_DIR, getpid()); if ((fp = FOPEN(filename, "w")) != NULL) { for (i = num_const_zon ; i < numzon ; i++) fprintf(fp, "%s\n", zname(i)); } FCLOSE(fp); }