|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00032 #if RECYCLE_TMP_MAPS 00033 00035 static void write_map_log() 00036 { 00037 FILE *fp; 00038 mapstruct *map; 00039 char buf[MAX_BUF]; 00040 long current_time = time(NULL); 00041 00042 snprintf(buf, sizeof(buf), "%s/temp.maps", settings.localdir); 00043 00044 if (!(fp = fopen(buf, "w"))) 00045 { 00046 LOG(llevBug, "Could not open %s for writing\n", buf); 00047 return; 00048 } 00049 00050 for (map = first_map; map; map = map->next) 00051 { 00052 /* If tmpname is null, it is probably a unique player map, 00053 * so don't save information on it. */ 00054 if (map->in_memory != MAP_IN_MEMORY && map->tmpname && strncmp(map->path, "/random", 7)) 00055 { 00056 /* the 0 written out is a leftover from the lock number for 00057 * unique items and second one is from encounter maps. 00058 * Keep using it so that old temp files continue 00059 * to work. */ 00060 fprintf(fp, "%s:%s:%ld:%d:%d\n", map->path, map->tmpname, (map->reset_time == -1 ? -1: map->reset_time - current_time), map->difficulty, map->darkness); 00061 } 00062 } 00063 00064 fclose(fp); 00065 } 00066 #endif 00067 00070 void read_map_log() 00071 { 00072 FILE *fp; 00073 mapstruct *map; 00074 char buf[MAX_BUF]; 00075 int darkness; 00076 00077 snprintf(buf, sizeof(buf), "%s/temp.maps", settings.localdir); 00078 00079 if (!(fp = fopen(buf, "r"))) 00080 { 00081 LOG(llevDebug, "Could not open %s for reading\n", buf); 00082 return; 00083 } 00084 00085 while (fgets(buf, sizeof(buf), fp)) 00086 { 00087 char *tmp[3]; 00088 00089 map = get_linked_map(); 00090 00091 if (split_string(buf, tmp, sizeof(tmp) / sizeof(*tmp), ':') != 3) 00092 { 00093 LOG(llevDebug, "%s/temp.maps: ignoring invalid line: %s\n", settings.localdir, buf); 00094 continue; 00095 } 00096 00097 FREE_AND_COPY_HASH(map->path, tmp[0]); 00098 map->tmpname = strdup_local(tmp[1]); 00099 00100 sscanf(tmp[2], "%ud:%d:%d\n", &map->reset_time, &map->difficulty, &darkness); 00101 00102 map->in_memory = MAP_SWAPPED; 00103 map->darkness = darkness; 00104 00105 if (darkness == -1) 00106 { 00107 darkness = MAX_DARKNESS; 00108 } 00109 00110 map->light_value = global_darkness_table[MAX_DARKNESS]; 00111 } 00112 00113 fclose(fp); 00114 } 00115 00120 void swap_map(mapstruct *map, int force_flag) 00121 { 00122 int i; 00123 00124 if (map->in_memory != MAP_IN_MEMORY) 00125 { 00126 LOG(llevBug, "Tried to swap out map which was not in memory (%s).\n", map->path); 00127 return; 00128 } 00129 00130 /* Test for players. */ 00131 if (!force_flag) 00132 { 00133 if (map->player_first) 00134 { 00135 return; 00136 } 00137 00138 for (i = 0; i < TILED_MAPS; i++) 00139 { 00140 /* If there is a map, is loaded and in memory, has players, then no swap */ 00141 if (map->tile_map[i] && map->tile_map[i]->in_memory == MAP_IN_MEMORY && map->tile_map[i]->player_first) 00142 { 00143 return; 00144 } 00145 } 00146 } 00147 00148 /* Update the reset time. */ 00149 if (!MAP_FIXED_RESETTIME(map)) 00150 { 00151 set_map_reset_time(map); 00152 } 00153 00154 /* If it is immediate reset time, don't bother saving it - just get 00155 * rid of it right away. */ 00156 if (map->reset_time <= (uint32) seconds()) 00157 { 00158 mapstruct *oldmap = map; 00159 00160 LOG(llevDebug, "Resetting1 map %s.\n", map->path); 00161 00162 if (map->events) 00163 { 00164 /* Trigger the map reset event */ 00165 trigger_map_event(MEVENT_RESET, map, NULL, NULL, NULL, map->path, 0); 00166 } 00167 00168 map = map->next; 00169 delete_map(oldmap); 00170 return; 00171 } 00172 00173 if (new_save_map(map, 0) == -1) 00174 { 00175 LOG(llevBug, "Failed to swap map %s.\n", map->path); 00176 /* Need to reset the in_memory flag so that delete map will also 00177 * free the objects with it. */ 00178 map->in_memory = MAP_IN_MEMORY; 00179 delete_map(map); 00180 } 00181 else 00182 { 00183 free_map(map, 1); 00184 } 00185 00186 #if RECYCLE_TMP_MAPS 00187 write_map_log(); 00188 #endif 00189 } 00190 00193 void check_active_maps() 00194 { 00195 mapstruct *map, *next; 00196 00197 for (map = first_map; map != NULL; map = next) 00198 { 00199 next = map->next; 00200 00201 if (map->in_memory != MAP_IN_MEMORY) 00202 { 00203 continue; 00204 } 00205 00206 if (!map->timeout) 00207 { 00208 if (!map->player_first) 00209 { 00210 set_map_timeout(map); 00211 } 00212 00213 continue; 00214 } 00215 00216 if (--(map->timeout) > 0) 00217 { 00218 continue; 00219 } 00220 00221 swap_map(map, 0); 00222 } 00223 } 00224 00230 void flush_old_maps() 00231 { 00232 mapstruct *m = first_map, *oldmap; 00233 long sec = seconds(); 00234 00235 while (m) 00236 { 00237 /* There can be cases (ie death) where a player leaves a map and 00238 * the timeout is not set so it isn't swapped out. */ 00239 if ((m->in_memory == MAP_IN_MEMORY) && (m->timeout == 0) && !m->player_first) 00240 { 00241 set_map_timeout(m); 00242 } 00243 00244 /* Per player unique maps are never really reset. */ 00245 if (MAP_UNIQUE(m) && m->in_memory == MAP_SWAPPED) 00246 { 00247 LOG(llevDebug, "Resetting2 map %s.\n", m->path); 00248 oldmap = m; 00249 m = m->next; 00250 delete_map(oldmap); 00251 } 00252 /* No need to flush them if there are no resets */ 00253 else if (m->in_memory != MAP_SWAPPED || m->tmpname == NULL || (uint32) sec < m->reset_time) 00254 { 00255 m = m->next; 00256 } 00257 else 00258 { 00259 LOG(llevDebug, "Resetting3 map %s.\n", m->path); 00260 00261 if (m->events) 00262 { 00263 /* Trigger the map reset event */ 00264 trigger_map_event(MEVENT_RESET, m, NULL, NULL, NULL, m->path, 0); 00265 } 00266 00267 clean_tmp_map(m); 00268 oldmap = m; 00269 m = m->next; 00270 delete_map(oldmap); 00271 } 00272 } 00273 }
1.7.4