00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <global.h>
00035 #ifndef __CEXTRACT__
00036 #include <sproto.h>
00037 #endif
00038 #include <object.h>
00039
00046 static void write_map_log(void) {
00047 FILE *fp;
00048 mapstruct *map;
00049 char buf[MAX_BUF];
00050 long current_time = time(NULL);
00051
00052 snprintf(buf, sizeof(buf), "%s/temp.maps", settings.localdir);
00053 if (!(fp = fopen(buf, "w"))) {
00054 LOG(llevError, "Could not open %s for writing\n", buf);
00055 return;
00056 }
00057 for (map = first_map; map != NULL; map = map->next) {
00058
00059
00060
00061 if (map->in_memory != MAP_IN_MEMORY
00062 && (map->tmpname != NULL)
00063 && (strncmp(map->path, "/random", 7))) {
00064
00065
00066
00067
00068
00069 fprintf(fp, "%s:%s:%ld:0:0:%d:0:%d\n", map->path, map->tmpname,
00070 (map->reset_time == -1 ? -1 : map->reset_time-current_time),
00071 map->difficulty,
00072 map->darkness);
00073 }
00074 }
00075 fclose(fp);
00076 }
00077
00083 void read_map_log(void) {
00084 FILE *fp;
00085 mapstruct *map;
00086 char buf[MAX_BUF], *cp, *cp1;
00087 int do_los, darkness, lock;
00088 long sec = seconds();
00089
00090 snprintf(buf, sizeof(buf), "%s/temp.maps", settings.localdir);
00091 if (!(fp = fopen(buf, "r"))) {
00092 LOG(llevDebug, "Could not open %s for reading\n", buf);
00093 return;
00094 }
00095 while (fgets(buf, MAX_BUF, fp) != NULL) {
00096 map = get_linked_map();
00097
00098
00099
00100
00101 cp = strchr(buf, ':');
00102 *cp++ = '\0';
00103 strcpy(map->path, buf);
00104 cp1 = strchr(cp, ':');
00105 *cp1++ = '\0';
00106 map->tmpname = strdup_local(cp);
00107
00108
00109
00110
00111
00112 sscanf(cp1, "%u:%d:%d:%hu:%d:%d\n", &map->reset_time, &lock, &lock, &map->difficulty, &do_los, &darkness);
00113
00114 map->in_memory = MAP_SWAPPED;
00115 map->darkness = darkness;
00116 map->timeout = 0;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 map->reset_time += sec;
00127 if (map->reset_time > (sec+MAP_MAXRESET))
00128 map->reset_time = 0;
00129
00130 }
00131 fclose(fp);
00132 }
00133
00146 int swap_map(mapstruct *map) {
00147 player *pl;
00148 int res;
00149
00150 if (map->in_memory != MAP_IN_MEMORY) {
00151 LOG(llevError, "Tried to swap out map which was not in memory.\n");
00152 return SAVE_ERROR_NOT_IN_MEMORY;
00153 }
00154 for (pl = first_player; pl != NULL; pl = pl->next)
00155 if (pl->ob == NULL || (!(QUERY_FLAG(pl->ob, FLAG_REMOVED)) && pl->ob->map == map))
00156 break;
00157
00158 if (pl != NULL) {
00159 LOG(llevDebug, "Wanted to swap out map with player.\n");
00160 return SAVE_ERROR_PLAYER;
00161 }
00162 remove_all_pets();
00163
00164
00165 if (!map->fixed_resettime)
00166 set_map_reset_time(map);
00167
00168
00169
00170
00171 if (map->reset_time <= seconds()) {
00172 mapstruct *oldmap = map;
00173
00174 LOG(llevDebug, "Resetting map %s.\n", map->path);
00175
00176 execute_global_event(EVENT_MAPRESET, map);
00177 map = map->next;
00178 delete_map(oldmap);
00179 return SAVE_ERROR_OK;
00180 }
00181
00182 if ((res = save_map(map, SAVE_MODE_NORMAL)) < 0) {
00183 LOG(llevError, "Failed to swap map %s.\n", map->path);
00184
00185 draw_ext_info_format(NDI_ALL_DMS|NDI_UNIQUE|NDI_RED, -1, NULL, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00186 "Failed to swap map %s!", NULL, map->path);
00187
00188 map->in_memory = MAP_IN_MEMORY;
00189 return res;
00190 }
00191
00192 free_map(map);
00193
00194 if (settings.recycle_tmp_maps == TRUE)
00195 write_map_log();
00196
00197 return SAVE_ERROR_OK;
00198 }
00199
00206 void check_active_maps(void) {
00207 mapstruct *map, *next;
00208
00209 for (map = first_map; map != NULL; map = next) {
00210 next = map->next;
00211 if (map->in_memory != MAP_IN_MEMORY)
00212 continue;
00213 if (!map->timeout)
00214 continue;
00215 if (--(map->timeout) > 0)
00216 continue;
00217
00218 #ifndef MAX_OBJECTS_LWM
00219 swap_map(map);
00220 #endif
00221 }
00222 }
00223
00232 static mapstruct *map_least_timeout(const char *except_level) {
00233 mapstruct *map, *chosen = NULL;
00234 int timeout = MAP_MAXTIMEOUT+1;
00235
00236 for (map = first_map; map != NULL; map = map->next)
00237 if (map->in_memory == MAP_IN_MEMORY
00238 && strcmp(map->path, except_level)
00239 && map->timeout
00240 && map->timeout < timeout)
00241 chosen = map, timeout = map->timeout;
00242 return chosen;
00243 }
00244
00253 void swap_below_max(const char *except_level) {
00254 mapstruct *map;
00255
00256 if (nrofallocobjects-nroffreeobjects < MAX_OBJECTS)
00257 return;
00258 for (;;) {
00259 #ifdef MAX_OBJECTS_LWM
00260 if (nrofallocobjects-nroffreeobjects < MAX_OBJECTS_LWM)
00261 return;
00262 #else
00263 if (nrofallocobjects-nroffreeobjects < MAX_OBJECTS)
00264 return;
00265 #endif
00266 if ((map = map_least_timeout(except_level)) == NULL)
00267 return;
00268 LOG(llevDebug, "Trying to swap out %s before its time.\n", map->path);
00269 map->timeout = 0;
00270 swap_map(map);
00271 }
00272 }
00273
00287 int players_on_map(mapstruct *m, int show_all) {
00288 player *pl;
00289 int nr = 0;
00290
00291 for (pl = first_player; pl != NULL; pl = pl->next)
00292 if (pl->ob != NULL
00293 && !QUERY_FLAG(pl->ob, FLAG_REMOVED)
00294 && pl->ob->map == m
00295 && (show_all || !pl->hidden))
00296 nr++;
00297 return nr;
00298 }
00299
00305 void flush_old_maps(void) {
00306 mapstruct *m, *oldmap;
00307 long sec;
00308 sec = seconds();
00309
00310 m = first_map;
00311 while (m) {
00312
00313
00314
00315 if ((m->in_memory == MAP_IN_MEMORY)
00316 && (m->timeout == 0)
00317 && !players_on_map(m, TRUE)) {
00318 set_map_timeout(m);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 if ((m->unique || m->is_template) && m->in_memory == MAP_SWAPPED) {
00332 LOG(llevDebug, "Resetting map %s.\n", m->path);
00333 oldmap = m;
00334 m = m->next;
00335 delete_map(oldmap);
00336 } else if (m->in_memory != MAP_SWAPPED
00337 || m->tmpname == NULL
00338 || sec < m->reset_time) {
00339 m = m->next;
00340 } else {
00341 LOG(llevDebug, "Resetting map %s.\n", m->path);
00342
00343 execute_global_event(EVENT_MAPRESET, m);
00344 clean_tmp_map(m);
00345 oldmap = m;
00346 m = m->next;
00347 delete_map(oldmap);
00348 }
00349 }
00350 }