Atrinik Server  4.0
swap.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <toolkit/string.h>
32 #include <plugin.h>
33 
37 void write_map_log(void)
38 {
39  FILE *fp;
40  mapstruct *map;
41  char buf[MAX_BUF];
42  long current_time = time(NULL);
43 
44  snprintf(buf, sizeof(buf), "%s/temp.maps", settings.datapath);
45 
46  if (!(fp = fopen(buf, "w"))) {
47  LOG(BUG, "Could not open %s for writing", buf);
48  return;
49  }
50 
51  DL_FOREACH(first_map, map)
52  {
53  /* If tmpname is null, it is probably a unique player map,
54  * so don't save information on it. */
55  if (map->in_memory != MAP_IN_MEMORY && map->tmpname && strncmp(map->path, "/random", 7)) {
56  fprintf(fp, "%s:%s:%ld:%d:%d\n", map->path, map->tmpname, (map->reset_time - current_time), map->difficulty, map->darkness);
57  }
58  }
59 
60  fclose(fp);
61 }
62 
66 void read_map_log(void)
67 {
68  FILE *fp;
69  mapstruct *map;
70  char buf[MAX_BUF];
71  int darkness;
72 
73  snprintf(buf, sizeof(buf), "%s/temp.maps", settings.datapath);
74 
75  if (!(fp = fopen(buf, "r"))) {
76  return;
77  }
78 
79  while (fgets(buf, sizeof(buf), fp)) {
80  char *tmp[3];
81 
82  map = get_linked_map();
83 
84  if (string_split(buf, tmp, sizeof(tmp) / sizeof(*tmp), ':') != 3) {
85  LOG(DEBUG, "%s/temp.maps: ignoring invalid line: %s", settings.datapath, buf);
86  continue;
87  }
88 
89  FREE_AND_COPY_HASH(map->path, tmp[0]);
90  map->tmpname = estrdup(tmp[1]);
91 
92  sscanf(tmp[2], "%ud:%d:%d\n", &map->reset_time, &map->difficulty, &darkness);
93 
94  map->in_memory = MAP_SWAPPED;
95  map->darkness = darkness;
96 
97  if (darkness == -1) {
98  darkness = MAX_DARKNESS;
99  }
100 
101  map->light_value = global_darkness_table[MAX_DARKNESS];
102  }
103 
104  fclose(fp);
105 }
106 
116 static int swap_map_check(mapstruct *tiled, mapstruct *map)
117 {
118  return tiled->player_first != NULL;
119 }
120 
128 void swap_map(mapstruct *map, int force_flag)
129 {
130  if (map->in_memory != MAP_IN_MEMORY) {
131  LOG(BUG, "Tried to swap out map which was not in memory (%s).", map->path);
132  return;
133  }
134 
135  if (!force_flag) {
137  {
138  if (MAP_TILES_WALK_RETVAL != 0) {
139  return;
140  }
141  }
143  }
144 
145  /* Update the reset time. */
146  if (!MAP_FIXED_RESETTIME(map)) {
147  set_map_reset_time(map);
148  }
149 
150  /* If it is immediate reset time, don't bother saving it - just get
151  * rid of it right away. */
152  if (map->reset_time <= (uint32_t) seconds()) {
153  if (map->events) {
154  /* Trigger the map reset event */
155  trigger_map_event(MEVENT_RESET, map, NULL, NULL, NULL, map->path, 0);
156  }
157 
158  delete_map(map);
159  return;
160  }
161 
162  if (new_save_map(map, 0) == -1) {
163  LOG(BUG, "Failed to swap map %s.", map->path);
164  /* Need to reset the in_memory flag so that delete map will also
165  * free the objects with it. */
166  map->in_memory = MAP_IN_MEMORY;
167  delete_map(map);
168  } else {
169  free_map(map, 1);
170  }
171 }
172 
177 {
178  mapstruct *map, *tmp;
179 
180  DL_FOREACH_SAFE(first_map, map, tmp)
181  {
182  if (map->in_memory != MAP_IN_MEMORY) {
183  continue;
184  }
185 
186  if (!map->timeout) {
187  if (!map->player_first) {
188  set_map_timeout(map);
189  }
190 
191  continue;
192  }
193 
194  if (--(map->timeout) > 0) {
195  continue;
196  }
197 
198  swap_map(map, 0);
199  }
200 }
201 
208 void flush_old_maps(void)
209 {
210  mapstruct *m, *tmp;
211  long sec = seconds();
212 
213  DL_FOREACH_SAFE(first_map, m, tmp)
214  {
215  /* There can be cases (ie death) where a player leaves a map and
216  * the timeout is not set so it isn't swapped out. */
217  if ((m->in_memory == MAP_IN_MEMORY) && (m->timeout == 0) && !m->player_first) {
218  set_map_timeout(m);
219  }
220 
221  /* Per player unique maps are never really reset. */
222  if (MAP_UNIQUE(m) && m->in_memory == MAP_SWAPPED) {
223  delete_map(m);
224  continue;
225  }
226 
227  if (m->in_memory != MAP_SWAPPED || m->tmpname == NULL ||
228  (uint32_t) sec < m->reset_time) {
229  /* No need to flush them if there are no resets */
230  continue;
231  }
232 
233  if (m->events != NULL) {
234  /* Trigger the map reset event */
235  trigger_map_event(MEVENT_RESET, m, NULL, NULL, NULL, m->path, 0);
236  }
237 
238  clean_tmp_map(m);
239  delete_map(m);
240  }
241 }
#define FREE_AND_COPY_HASH(_sv_, _nv_)
Definition: global.h:100
#define MAP_FIXED_RESETTIME(m)
Definition: map.h:98
#define MAP_IN_MEMORY
Definition: map.h:170
long seconds(void)
Definition: time.c:338
char datapath[MAX_BUF]
Definition: global.h:343
int darkness
Definition: map.h:638
shstr * path
Definition: map.h:568
mapstruct * get_linked_map(void)
Definition: map.c:948
uint32_t in_memory
Definition: map.h:627
uint32_t reset_time
Definition: map.h:608
void check_active_maps(void)
Definition: swap.c:176
#define MAP_TILES_WALK_START(_m, _fnc,...)
Definition: map.h:733
int new_save_map(mapstruct *m, int flag)
Definition: map.c:1363
void delete_map(mapstruct *m)
Definition: map.c:1555
void free_map(mapstruct *m, int flag)
Definition: map.c:1493
#define MAP_SWAPPED
Definition: map.h:172
void read_map_log(void)
Definition: swap.c:66
void swap_map(mapstruct *map, int force_flag)
Definition: swap.c:128
int trigger_map_event(int event_id, mapstruct *m, object *activator, object *other, object *other2, const char *text, int parm)
Definition: plugins.c:416
static int swap_map_check(mapstruct *tiled, mapstruct *map)
Definition: swap.c:116
struct settings_struct settings
Definition: init.c:55
char * tmpname
Definition: map.h:562
struct map_event * events
Definition: map.h:583
int32_t timeout
Definition: map.h:617
int difficulty
Definition: map.h:650
void flush_old_maps(void)
Definition: swap.c:208
int light_value
Definition: map.h:644
void write_map_log(void)
Definition: swap.c:37
#define MAP_UNIQUE(m)
Definition: map.h:96
object * player_first
Definition: map.h:594
#define MAX_DARKNESS
Definition: map.h:37
#define MAP_TILES_WALK_END
Definition: map.h:766
#define MEVENT_RESET
Definition: plugin.h:123
Definition: map.h:536
void clean_tmp_map(mapstruct *m)
Definition: map.c:1662
mapstruct * first_map
Definition: main.c:59
#define MAP_TILES_WALK_RETVAL
Definition: map.h:761
void set_map_timeout(mapstruct *map)
Definition: main.c:124
void set_map_reset_time(mapstruct *map)
Definition: map.c:1814