Boot_db Fix v1 for EmberMUD Fix Sheet by Rindar (Ron Cole) Code by Raven (Laurie Zenner) and Rindar The Bug: This is more of a snippet than a bug fix, but since not using this code can crash the game.. well, bugfix just seems to apply a bit better. Basicly, Ember, ROM, MERC, and most other DIKU variants load their areas completely and one at a time. Because of this, if area X loads before area Y and one of its RESETs is an item from area Y, the game will crash. Simply speaking, because the item has not been loaded into memory yet, any attempt to call the item results in a game crash. The Check: The easiest way to check for this is to set an object from the last area your MUD loads as a reset in the FIRST area it loads (not including the help files and socials). Usually, the area is LIMBO (to check, open the file area.lst in the area folder and see which area loads first). After the reset has been set and the area saved, HOTBOOT the MUD. If the game crashes, you have the bug. The Bugfix: Fixing this bug requires getting the areas to load resets, shops, and other "load sensitive" things last, after all items and MOBs from every area have been loaded into the game. This fix does that, though probably not in the best way possible (this is a quick fix, not the boot code for an entirely new codebase after all). To install the code, do the following: 1) Open db.c 2) Find the function "void boot_db" 3) Delete the entire function. 4) Paste in the new boot_db function at the bottom of this page, along with the "skip_section" function. 5) You must now declare the new function skip_section. Find the following lines: /* * Local booting procedures. */ void init_mm args( ( void ) ); /* void load_clans args( ( FILE *fp ) ); */ Add in the skip_section function. It should now look like this: void init_mm args( ( void ) ); void skip_section args( ( FILE *fp, char *section ) ); /* void load_clans args( ( FILE *fp ) ); */ 10) Save and recompile. You should be done. All done! If you find other bugs in the boot function or have some other improvements, please feel free to send them along to me. My e-mail address is below. -= Rindar clogar@concentric.net ** Note: This function is provided "as is" and may be used so long as 1) The author's name is kept at the top of the function (if requested) and 2) all other previous licensing aggreements are abided by. The author assumes no responsibility for problems that occur through use or install- ation, including lost wages, bugs, deletions, downtimes, etc... Use at your own risk. All new code is copyrighted by its author. Boot and skip_section code (in db.c): void boot_db( ) { #if defined(unix) /* open file fix */ maxfilelimit(); #endif /* * Init some data space stuff. */ { if ( ( string_space = calloc( 1, MAX_STRING ) ) == NULL ) { bug( "Boot_db: can't alloc %d string space.", MAX_STRING ); exit( 1 ); } top_string = string_space; fBootDb = TRUE; } /* * Init random number generator. */ { init_mm( ); } /* * Set time and weather. */ { long lhour, lday, lmonth; lhour = (current_time - 650336715) / (PULSE_TICK / PULSE_PER_SECOND); time_info.hour = lhour % 24; lday = lhour / 24; time_info.day = lday % 35; lmonth = lday / 35; time_info.month = lmonth % 17; time_info.year = lmonth / 17; if ( time_info.hour < 5 ) weather_info.sunlight = SUN_DARK; else if ( time_info.hour < 6 ) weather_info.sunlight = SUN_RISE; else if ( time_info.hour < 19 ) weather_info.sunlight = SUN_LIGHT; else if ( time_info.hour < 20 ) weather_info.sunlight = SUN_SET; else weather_info.sunlight = SUN_DARK; weather_info.change = 0; weather_info.mmhg = 960; if ( time_info.month >= 7 && time_info.month <=12 ) weather_info.mmhg += number_range( 1, 50 ); else weather_info.mmhg += number_range( 1, 80 ); if ( weather_info.mmhg <= 980 ) weather_info.sky = SKY_LIGHTNING; else if ( weather_info.mmhg <= 1000 ) weather_info.sky = SKY_RAINING; else if ( weather_info.mmhg <= 1020 ) weather_info.sky = SKY_CLOUDY; else weather_info.sky = SKY_CLOUDLESS; } /* * Assign gsn's for skills which have them. */ { int sn; for ( sn = 0; sn < MAX_SKILL; sn++ ) { if ( skill_table[sn].pgsn != NULL ) *skill_table[sn].pgsn = sn; } } /* * Read in all the area files. */ { FILE *fpList; if ( ( fpList = fopen( AREA_LIST, "r" ) ) == NULL ) { perror( AREA_LIST ); exit( 1 ); } for ( ; ; ) { strcpy( strArea, fread_word( fpList ) ); if ( strArea[0] == '$' ) break; if ( strArea[0] == '-' ) { fpArea = stdin; } else { if ( ( fpArea = fopen( strArea, "r" ) ) == NULL ) { perror( strArea ); exit( 1 ); } } for ( ; ; ) { char *word; if ( fread_letter( fpArea ) != '#' ) { bug( "Boot_db: # not found.", 0 ); exit( 1 ); } word = fread_word( fpArea ); if ( word[0] == '$' ) break; /* OLC */ else if ( !str_cmp( word, "AREADATA" ) ) load_area (fpArea); /* else if ( !str_cmp( word, "CLANS" ) ) load_clans (fpArea); */ else if ( !str_cmp( word, "HELPS" ) ) load_helps (fpArea); else if ( !str_cmp( word, "MOBILES" ) ) load_mobiles (fpArea); else if ( !str_cmp( word, "MOBPROGS" ) ) load_mobprogs(fpArea); else if ( !str_cmp( word, "OBJECTS" ) ) load_objects (fpArea); else if ( !str_cmp( word, "RESETS" ) ) skip_section (fpArea,word); else if ( !str_cmp( word, "ROOMS" ) ) load_rooms (fpArea); else if ( !str_cmp( word, "RAFFECTS" ) ) load_raffects(fpArea); else if ( !str_cmp( word, "SHOPS" ) ) skip_section (fpArea,word); else if ( !str_cmp( word, "SOCIALS" ) ) load_socials (fpArea); else if ( !str_cmp( word, "SPECIALS" ) ) load_specials(fpArea); else { bug( "Boot_db: bad section name.", 0 ); exit( 1 ); } } if ( fpArea != stdin ) fclose( fpArea ); fpArea = NULL; } fclose( fpList ); /* Load resets and shops only after everything else is loaded in */ if ( ( fpList = fopen( AREA_LIST, "r" ) ) == NULL ) { perror( AREA_LIST ); exit( 1 ); } for ( ; ; ) { strcpy( strArea, fread_word( fpList ) ); if ( strArea[0] == '$' ) break; if ( strArea[0] == '-' ) { fpArea = stdin; } else { if ( ( fpArea = fopen( strArea, "r" ) ) == NULL ) { perror( strArea ); exit( 1 ); } } for ( ; ; ) { char *word; if ( fread_letter( fpArea ) != '#' ) { bug( "Boot_db: # not found.", 0 ); exit( 1 ); } word = fread_word( fpArea ); if ( word[0] == '$' ) break; /* OLC */ else if ( !str_cmp( word, "AREADATA" ) ) skip_section (fpArea,word); /*load_area (fpArea)*/ /* else if ( !str_cmp( word, "CLANS" ) ) load_clans (fpArea); */ else if ( !str_cmp( word, "HELPS" ) ) skip_section (fpArea,word); /*load_helps (fpArea)*/ else if ( !str_cmp( word, "MOBILES" ) ) skip_section (fpArea,word); /*load_mobiles (fpArea)*/ else if ( !str_cmp( word, "MOBPROGS" ) ) skip_section (fpArea,word); /*load_mobprogs(fpArea)*/ else if ( !str_cmp( word, "OBJECTS" ) ) skip_section (fpArea,word); /*load_objects (fpArea)*/ else if ( !str_cmp( word, "RESETS" ) ) load_resets (fpArea); else if ( !str_cmp( word, "ROOMS" ) ) skip_section (fpArea,word); /*load_rooms (fpArea)*/ else if ( !str_cmp( word, "RAFFECTS" ) ) skip_section (fpArea,word); /*load_raffects(fpArea)*/ else if ( !str_cmp( word, "SHOPS" ) ) load_shops (fpArea); else if ( !str_cmp( word, "SOCIALS" ) ) skip_section (fpArea,word); /*load_socials (fpArea)*/ else if ( !str_cmp( word, "SPECIALS" ) ) skip_section (fpArea,word); /*load_specials(fpArea)*/ else { bug( "Boot_db: bad section name.", 0 ); exit( 1 ); } } if ( fpArea != stdin ) fclose( fpArea ); fpArea = NULL; } fclose( fpList ); } /* * Fix up exits. * Declare db booting over. * Reset all areas once. * Load up the notes file. */ { fix_exits( ); fBootDb = FALSE; area_update( ); load_boards(); /* Load all boards */ save_notes(); MOBtrigger = TRUE; } if ( !help_greeting ) /* Hugin */ { bug( "boot_db: No help_greeting read.", 0 ); help_greeting = "By what name do you wish to be known ? "; } if (fCopyOver) copyover_recover(); return; } /***************************************************************************/ /* * Skip a section. */ void skip_section( FILE *fp, char *section ) { int number; char *word; char letter; if (!str_cmp( section, "AREADATA" )) { for ( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); if ( !str_cmp( word, "End" ) ) return; fread_to_eol( fp ); } } if (!str_cmp( section, "HELPS" )) { for ( ; ; ) { number = fread_number( fp ); word = fread_string( fp ); if ( word[0] == '$' ) return; fread_string( fp ); } } if (!str_cmp( section, "MOBILES" ) || !str_cmp( section, "OBJECTS" ) || !str_cmp( section, "ROOMS" ) || !str_cmp( section, "RAFFECTS" )) { for ( ; ; ) { word = feof( fp ) ? "#0" : fread_string_eol( fp ); if ( word[0] == '#' && word[1] == '0' ) return; } } if (!str_cmp( section, "MOBPROGS" ) || !str_cmp( section, "RESETS" ) || !str_cmp( section, "SPECIALS" )) { for ( ; ; ) { switch( letter = fread_letter( fp ) ) { case 'S': if ( !str_cmp( section, "RESETS" ) || !str_cmp( section, "SPECIALS" )) return; case 's': fread_to_eol( fp ); return; } fread_to_eol( fp ); } } if (!str_cmp( section, "SHOPS" )) { for ( ; ; ) { number = fread_number( fp ); if ( number == 0 ) return; fread_to_eol( fp ); } } if (!str_cmp( section, "SOCIALS" )) { for ( ; ; ) { word = fread_word( fp ); if ( !strcmp( word, "#0" ) ) return; fread_to_eol( fp ); } } bug( "skip_section: Invalid section name.", 0 ); exit( 1 ); } ============================================================================= / ______ _______ ____ _____ ___ __ _ ______ ____ ____ _____ / \ | ____|__ __| _ \ / ____\ / _ \| \ / | ____| / __ \| _ \ / ____\ \ / | |__ | | | |_| | | | |_| | |\/| | |___ | | | | |_| | | / / | ___| | | | ___/| | __| _ | | | | ____| | | | | __/| | ___ \ \ | | | | | | | |___| | | | | | | | |____ | |__| | |\ \| |___| | / / |_| |_| |_| o \_____/|_| |_|_| |_|______|o \____/|_| \_|\_____/ \ \ / ============================================================================ ------------------------------------------------------------------------------ ftp://ftp.game.org/pub/mud FTP.GAME.ORG http://www.game.org/ftpsite/ ------------------------------------------------------------------------------ This file came from FTP.GAME.ORG, the ultimate source for MUD resources. ------------------------------------------------------------------------------