void post_server_shutdown(int status) { switch (status) { case 0: topiclist_unload(); realmlist_destroy(); teamlist_unload(); clanlist_unload(); tournament_destroy(); anongame_infos_unload(); trans_unload(); aliasfile_unload(); command_groups_unload(); tracker_set_servers(NULL); characterlist_destroy(); ladder_destroyxptable(); case STATUS_WAR3XPTABLES_FAILURE: case STATUS_LADDERLIST_FAILURE: ladder_update_all_accounts(); ladders_destroy(); output_dispose_filename(); accountlist_destroy(); attrlayer_cleanup(); watchlist_destroy(); news_unload(); versioncheck_unload(); autoupdate_unload(); adbannerlist_destroy(); ipbanlist_save(prefs_get_ipbanfile()); ipbanlist_destroy(); helpfile_unload(); channellist_destroy(); server_clear_hostname(); timerlist_destroy(); gamelist_destroy(); connlist_destroy(); fdwatch_close(); case STATUS_FDWATCH_FAILURE: anongame_matchlists_destroy(); case STATUS_MATCHLISTS_FAILURE: anongame_maplists_destroy(); case STATUS_MAPLISTS_FAILURE: case STATUS_SUPPORT_FAILURE: if (psock_deinit()) eventlog(eventlog_level_error, __FUNCTION__, "got error from psock_deinit()"); case STATUS_PSOCK_FAILURE: storage_close(); case STATUS_STORAGE_FAILURE: oom_free(); case STATUS_OOM_FAILURE: case -1: break; default: eventlog(eventlog_level_error,__FUNCTION__,"got bad status \"%d\" during shutdown",status); } return; }
extern int ladder_createxptable(const char *xplevelfile, const char *xpcalcfile) { std::FILE *fd1, *fd2; char buffer[256]; char *p; t_xpcalc_entry * newxpcalc; int len,i ,j; int level, startxp, neededxp, mingames; float lossfactor; int minlevel, leveldiff, higher_xpgained, higher_xplost, lower_xpgained, lower_xplost = 10; if (xplevelfile == NULL || xpcalcfile == NULL) { eventlog(eventlog_level_error, "ladder_createxptable", "got NULL filename(s)"); return -1; } /* first lets open files */ if ((fd1 = std::fopen(xplevelfile, "rt")) == NULL) { eventlog(eventlog_level_error, "ladder_createxptable", "could not open XP level file : \"%s\"", xplevelfile); return -1; } if ((fd2 = std::fopen(xpcalcfile, "rt")) == NULL) { eventlog(eventlog_level_error, "ladder_createxptable", "could not open XP calc file : \"%s\"", xpcalcfile); std::fclose(fd1); return -1; } /* then lets allocate mem for all the arrays */ xpcalc = (t_xpcalc_entry*)xmalloc(sizeof(t_xpcalc_entry) * W3_XPCALC_MAXLEVEL); //presume the maximal leveldiff is level number w3_xpcalc_maxleveldiff = -1; std::memset(xpcalc, 0, sizeof(t_xpcalc_entry) * W3_XPCALC_MAXLEVEL); xplevels = (t_xplevel_entry*)xmalloc(sizeof(t_xplevel_entry) * W3_XPCALC_MAXLEVEL); std::memset(xplevels, 0, sizeof(t_xplevel_entry) * W3_XPCALC_MAXLEVEL); /* finally, lets read from the files */ while(std::fgets(buffer, 256, fd1)) { len = std::strlen(buffer); if (len < 2) continue; if (buffer[len - 1] == '\n') buffer[len - 1] = '\0'; /* support comments */ for(p=buffer; *p && *p != '#'; p++); if (*p == '#') *p = '\0'; if (std::sscanf(buffer, "%d %d %d %f %d", &level, &startxp, &neededxp, &lossfactor, &mingames) != 5) continue; if (level < 1 || level > W3_XPCALC_MAXLEVEL) { /* invalid level */ eventlog(eventlog_level_error, "ladder_createxptable", "read INVALID player level : %d", level); continue; } level--; /* the index in a C array starts from 0 */ xplevels[level].startxp = startxp; xplevels[level].neededxp = neededxp; xplevels[level].lossfactor = (int)(lossfactor * 100); /* we store the loss factor as % */ xplevels[level].mingames = mingames; eventlog(eventlog_level_trace, "ladder_createxptable", "inserting level XP info (level: %d, startxp: %d neededxp: %d lossfactor: %d mingames: %d)", level+1, xplevels[level].startxp, xplevels[level].neededxp, xplevels[level].lossfactor, xplevels[level].mingames); } std::fclose(fd1); while(std::fgets(buffer, 256, fd2)) { len = std::strlen(buffer); if (len < 2) continue; if (buffer[len - 1] == '\n') buffer[len - 1] = '\0'; /* support comments */ for(p=buffer; *p && *p != '#'; p++); if (*p == '#') *p = '\0'; if (std::sscanf(buffer, " %d %d %d %d %d %d ", &minlevel, &leveldiff, &higher_xpgained, &higher_xplost, &lower_xpgained, &lower_xplost) != 6) continue; eventlog(eventlog_level_trace, "ladder_createxptable", "parsed xpcalc leveldiff : %d", leveldiff); if (leveldiff <0) { eventlog(eventlog_level_error, "ladder_createxptable", "got invalid level diff : %d", leveldiff); continue; } if (leveldiff> (w3_xpcalc_maxleveldiff+1)) { eventlog(eventlog_level_error, __FUNCTION__,"expected entry for leveldiff=%u but found %u",w3_xpcalc_maxleveldiff+1,leveldiff); continue; } w3_xpcalc_maxleveldiff = leveldiff; xpcalc[leveldiff].higher_winxp = higher_xpgained; xpcalc[leveldiff].higher_lossxp = higher_xplost; xpcalc[leveldiff].lower_winxp = lower_xpgained; xpcalc[leveldiff].lower_lossxp = lower_xplost; } std::fclose(fd2); newxpcalc = (t_xpcalc_entry*)xrealloc(xpcalc, sizeof(t_xpcalc_entry) * (w3_xpcalc_maxleveldiff+1)); xpcalc=newxpcalc; /* OK, now we need to test couse if the user forgot to put some values * lots of profiles could get screwed up */ if (w3_xpcalc_maxleveldiff<0) { eventlog(eventlog_level_error,__FUNCTION__,"found no valid entries for WAR3 xp calculation"); ladder_destroyxptable(); return -1; } eventlog(eventlog_level_info,__FUNCTION__,"set war3 xpcalc maxleveldiff to %u",w3_xpcalc_maxleveldiff); for(j=0;j<=w3_xpcalc_maxleveldiff;j++) if (xpcalc[j].higher_winxp == 0 || xpcalc[j].higher_lossxp == 0 || xpcalc[j].lower_winxp == 0 || xpcalc[j].lower_lossxp == 0) { eventlog(eventlog_level_error, __FUNCTION__, "I found 0 for a win/loss XP, please check your config file"); ladder_destroyxptable(); return -1; } for (i=0; i<W3_XPCALC_MAXLEVEL; i++) if ((i > 0 && xplevels[i].neededxp == 0) || xplevels[i].lossfactor == 0 || (i > 0 && (xplevels[i].startxp <= xplevels[i-1].startxp || xplevels[i].neededxp < xplevels[i-1].neededxp))) { eventlog(eventlog_level_error, __FUNCTION__, "I found 0 for a level XP, please check your config file (level: %d neededxp: %d lossfactor: %d)", i+1, xplevels[i].neededxp , xplevels[i].lossfactor); ladder_destroyxptable(); return -1; } return 0; }