Clarify character encoding arrangements, and stop claiming in various
[freeciv.git] / server / sanitycheck.c
blobf45430059da61d619fff55d4125ec9d9c728be12
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "bitvector.h"
20 #include "log.h"
22 /* common */
23 #include "city.h"
24 #include "game.h"
25 #include "government.h"
26 #include "map.h"
27 #include "movement.h"
28 #include "player.h"
29 #include "specialist.h"
30 #include "terrain.h"
31 #include "unit.h"
32 #include "unitlist.h"
34 /* server */
35 #include "citytools.h"
36 #include "cityturn.h" /* city_repair_size() */
37 #include "maphand.h"
38 #include "plrhand.h"
39 #include "srv_main.h"
40 #include "unittools.h"
42 #include "sanitycheck.h"
45 #ifdef SANITY_CHECKING
47 #define SANITY_FAIL(format, ...) \
48 fc_assert_fail(file, function, line, NULL, format, ## __VA_ARGS__)
50 #define SANITY_CHECK(check) \
51 fc_assert_full(file, function, line, check, , NOLOGMSG, NOLOGMSG)
53 #define SANITY_CITY(_city, check) \
54 fc_assert_full(file, function, line, check, , \
55 "(%4d, %4d) in \"%s\"[%d]", TILE_XY((_city)->tile), \
56 city_name(_city), city_size_get(_city))
58 #define SANITY_TERRAIN(_tile, check) \
59 fc_assert_full(file, function, line, check, , \
60 "(%4d, %4d) at \"%s\"", TILE_XY(_tile), \
61 terrain_rule_name(tile_terrain(_tile)))
63 #define SANITY_TILE(_tile, check) \
64 do { \
65 struct city *_tile##_city = tile_city(_tile); \
66 if (NULL != _tile##_city) { \
67 SANITY_CITY(_tile##_city, check); \
68 } else { \
69 SANITY_TERRAIN(_tile, check); \
70 } \
71 } while(0)
73 static void check_city_feelings(const struct city *pcity, const char *file,
74 const char *function, int line);
76 /**************************************************************************
77 Sanity checking on map (tile) specials.
78 **************************************************************************/
79 static void check_specials(const char *file, const char *function, int line)
81 whole_map_iterate(ptile) {
82 const struct terrain *pterrain = tile_terrain(ptile);
83 bv_special special = tile_specials(ptile);
85 if (contains_special(special, S_FARMLAND)) {
86 SANITY_TILE(ptile, contains_special(special, S_IRRIGATION));
89 if (contains_special(special, S_MINE)) {
90 SANITY_TILE(ptile, pterrain->mining_result == pterrain);
92 if (contains_special(special, S_IRRIGATION)) {
93 SANITY_TILE(ptile, pterrain->irrigation_result == pterrain);
96 SANITY_TILE(ptile, terrain_index(pterrain) >= T_FIRST
97 && terrain_index(pterrain) < terrain_count());
98 } whole_map_iterate_end;
101 /**************************************************************************
102 Sanity checking on fog-of-war (visibility, shared vision, etc.).
103 **************************************************************************/
104 static void check_fow(const char *file, const char *function, int line)
106 if (!game_was_started()) {
107 /* The private map of the players is only allocated at game start. */
108 return;
111 whole_map_iterate(ptile) {
112 players_iterate(pplayer) {
113 struct player_tile *plr_tile = map_get_player_tile(ptile, pplayer);
115 vision_layer_iterate(v) {
116 /* underflow of unsigned int */
117 SANITY_TILE(ptile, plr_tile->seen_count[v] < 30000);
118 SANITY_TILE(ptile, plr_tile->own_seen[v] < 30000);
119 SANITY_TILE(ptile, plr_tile->own_seen[v] <= plr_tile->seen_count[v]);
120 } vision_layer_iterate_end;
122 /* Lots of server bits depend on this. */
123 SANITY_TILE(ptile, plr_tile->seen_count[V_INVIS]
124 <= plr_tile->seen_count[V_MAIN]);
125 SANITY_TILE(ptile, plr_tile->own_seen[V_INVIS]
126 <= plr_tile->own_seen[V_MAIN]);
127 } players_iterate_end;
128 } whole_map_iterate_end;
130 SANITY_CHECK(game.government_during_revolution != NULL);
131 SANITY_CHECK(game.government_during_revolution
132 == government_by_number(game.info.government_during_revolution_id));
135 /**************************************************************************
136 Miscellaneous sanity checks.
137 **************************************************************************/
138 static void check_misc(const char *file, const char *function, int line)
140 int nplayers = 0, nbarbs = 0;
142 /* Do not use player_slots_iterate as we want to check the index! */
143 player_slots_iterate(pslot) {
144 if (player_slot_is_used(pslot)) {
145 if (is_barbarian(player_slot_get_player(pslot))) {
146 nbarbs++;
148 nplayers++;
150 } player_slots_iterate_end;
152 SANITY_CHECK(nplayers == player_count());
153 SANITY_CHECK(nbarbs == server.nbarbarians);
155 SANITY_CHECK(player_count() <= player_slot_count());
156 SANITY_CHECK(team_count() <= MAX_NUM_TEAM_SLOTS);
157 SANITY_CHECK(normal_player_count() <= game.server.max_players);
160 /**************************************************************************
161 Sanity checks on the map itself. See also check_specials.
162 **************************************************************************/
163 static void check_map(const char *file, const char *function, int line)
165 whole_map_iterate(ptile) {
166 struct city *pcity = tile_city(ptile);
167 int cont = tile_continent(ptile);
169 CHECK_INDEX(tile_index(ptile));
171 if (NULL != pcity) {
172 SANITY_TILE(ptile, same_pos(pcity->tile, ptile));
173 if (BORDERS_DISABLED != game.info.borders) {
174 SANITY_TILE(ptile, tile_owner(ptile) != NULL);
178 if (is_ocean_tile(ptile)) {
179 SANITY_TILE(ptile, cont < 0);
180 adjc_iterate(ptile, tile1) {
181 if (is_ocean_tile(tile1)) {
182 SANITY_TILE(ptile, tile_continent(tile1) == cont);
184 } adjc_iterate_end;
185 } else {
186 SANITY_TILE(ptile, cont > 0);
187 adjc_iterate(ptile, tile1) {
188 if (!is_ocean_tile(tile1)) {
189 SANITY_TILE(ptile, tile_continent(tile1) == cont);
191 } adjc_iterate_end;
194 unit_list_iterate(ptile->units, punit) {
195 SANITY_TILE(ptile, same_pos(unit_tile(punit), ptile));
197 /* Check diplomatic status of stacked units. */
198 unit_list_iterate(ptile->units, punit2) {
199 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
200 unit_owner(punit2)));
201 } unit_list_iterate_end;
202 if (pcity) {
203 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
204 city_owner(pcity)));
206 } unit_list_iterate_end;
207 } whole_map_iterate_end;
210 /**************************************************************************
211 Verify that the city itself has sane values.
212 **************************************************************************/
213 static bool check_city_good(struct city *pcity, const char *file,
214 const char *function, int line)
216 struct player *pplayer = city_owner(pcity);
217 struct tile *pcenter = city_tile(pcity);
219 if (NULL == pcenter) {
220 /* Editor! */
221 SANITY_FAIL("(----,----) city has no tile (skipping remaining tests), "
222 "at %s \"%s\"[%d]%s",
223 nation_rule_name(nation_of_player(pplayer)),
224 city_name(pcity), city_size_get(pcity),
225 "{city center}");
226 return FALSE;
229 SANITY_CITY(pcity, !terrain_has_flag(tile_terrain(pcenter), TER_NO_CITIES));
231 if (BORDERS_DISABLED != game.info.borders) {
232 SANITY_CITY(pcity, NULL != tile_owner(pcenter));
235 if (NULL != tile_owner(pcenter)) {
236 if (tile_owner(pcenter) != pplayer) {
237 SANITY_FAIL("(%4d,%4d) tile owned by %s, at %s \"%s\"[%d]%s",
238 TILE_XY(pcenter),
239 nation_rule_name(nation_of_player(tile_owner(pcenter))),
240 nation_rule_name(nation_of_player(pplayer)),
241 city_name(pcity), city_size_get(pcity),
242 "{city center}");
246 unit_list_iterate(pcity->units_supported, punit) {
247 SANITY_CITY(pcity, punit->homecity == pcity->id);
248 SANITY_CITY(pcity, unit_owner(punit) == pplayer);
249 } unit_list_iterate_end;
251 city_built_iterate(pcity, pimprove) {
252 if (is_small_wonder(pimprove)) {
253 SANITY_CITY(pcity, city_from_small_wonder(pplayer, pimprove) == pcity);
254 } else if (is_great_wonder(pimprove)) {
255 SANITY_CITY(pcity, city_from_great_wonder(pimprove) == pcity);
257 } city_built_iterate_end;
259 return TRUE;
262 /**************************************************************************
263 Sanity check city size versus worker and specialist counts.
264 **************************************************************************/
265 static void check_city_size(struct city *pcity, const char *file,
266 const char *function, int line)
268 int delta;
269 int citizens = 0;
270 struct tile *pcenter = city_tile(pcity);
272 SANITY_CITY(pcity, city_size_get(pcity) >= 1);
274 city_tile_iterate_skip_free_worked(city_map_radius_sq_get(pcity), pcenter,
275 ptile, _index, _x, _y) {
276 if (tile_worked(ptile) == pcity) {
277 citizens++;
279 } city_tile_iterate_skip_free_worked_end;
281 citizens += city_specialists(pcity);
282 delta = city_size_get(pcity) - citizens;
283 if (0 != delta) {
284 SANITY_FAIL("(%4d,%4d) %d citizens not equal [size], "
285 "repairing \"%s\"[%d]", TILE_XY(pcity->tile),
286 citizens, city_name(pcity), city_size_get(pcity));
288 citylog_map_workers(LOG_DEBUG, pcity);
289 log_debug("[%s (%d)] specialists: %d", city_name(pcity), pcity->id,
290 city_specialists(pcity));
292 city_repair_size(pcity, delta);
293 city_refresh_from_main_map(pcity, NULL);
297 /**************************************************************************
298 Verify that the number of people with feelings + specialists equal
299 city size.
300 **************************************************************************/
301 static void check_city_feelings(const struct city *pcity, const char *file,
302 const char *function, int line)
304 int feel;
305 int spe = city_specialists(pcity);
307 for (feel = FEELING_BASE; feel < FEELING_LAST; feel++) {
308 int sum = 0;
309 int ccategory;
311 for (ccategory = CITIZEN_HAPPY; ccategory < CITIZEN_LAST; ccategory++) {
312 sum += pcity->feel[ccategory][feel];
315 SANITY_CITY(pcity, city_size_get(pcity) - spe == sum);
319 /**************************************************************************
320 Verify that the city has sane values.
321 **************************************************************************/
322 void real_sanity_check_city(struct city *pcity, const char *file,
323 const char *function, int line)
325 if (check_city_good(pcity, file, function, line)) {
326 check_city_size(pcity, file, function, line);
327 check_city_feelings(pcity, file, function, line);
331 /**************************************************************************
332 Sanity checks on all cities in the world.
333 **************************************************************************/
334 static void check_cities(const char *file, const char *function, int line)
336 players_iterate(pplayer) {
337 city_list_iterate(pplayer->cities, pcity) {
338 SANITY_CITY(pcity, city_owner(pcity) == pplayer);
340 real_sanity_check_city(pcity, file, function, line);
341 } city_list_iterate_end;
342 } players_iterate_end;
345 /**************************************************************************
346 Sanity checks on all units in the world.
347 **************************************************************************/
348 static void check_units(const char *file, const char *function, int line)
350 players_iterate(pplayer) {
351 unit_list_iterate(pplayer->units, punit) {
352 struct tile *ptile = unit_tile(punit);
353 struct city *pcity;
354 struct city *phome;
355 struct unit *ptrans = unit_transport_get(punit);
357 SANITY_CHECK(unit_owner(punit) == pplayer);
359 if (IDENTITY_NUMBER_ZERO != punit->homecity) {
360 SANITY_CHECK(phome = player_city_by_number(pplayer,
361 punit->homecity));
362 if (phome) {
363 SANITY_CHECK(city_owner(phome) == pplayer);
367 /* Unit in the correct player list? */
368 SANITY_CHECK(player_unit_by_number(unit_owner(punit),
369 punit->id) != NULL);
371 if (!can_unit_continue_current_activity(punit)) {
372 SANITY_FAIL("(%4d,%4d) %s has activity %s, "
373 "but it can't continue at %s",
374 TILE_XY(ptile), unit_rule_name(punit),
375 get_activity_text(punit->activity),
376 tile_get_info_text(ptile, TRUE, 0));
379 pcity = tile_city(ptile);
380 if (pcity) {
381 SANITY_CHECK(pplayers_allied(city_owner(pcity), pplayer));
384 SANITY_CHECK(punit->moves_left >= 0);
385 SANITY_CHECK(punit->hp > 0);
387 /* Check for ground units in the ocean. */
388 if (!can_unit_exist_at_tile(punit, ptile)) {
389 SANITY_CHECK(ptrans != NULL);
392 /* Check for over-full transports. */
393 SANITY_CHECK(get_transporter_occupancy(punit)
394 <= get_transporter_capacity(punit));
396 /* Check transporter. This should be last as the pointer ptrans will
397 * be modified. */
398 if (ptrans != NULL) {
399 struct unit *plevel = punit;
400 int level = 0;
402 /* Make sure the transporter is on the tile. */
403 SANITY_CHECK(same_pos(unit_tile(punit), unit_tile(ptrans)));
405 /* Can punit be cargo for its transporter? */
406 SANITY_CHECK(unit_transport_check(punit, ptrans));
408 /* Check that the unit is listed as transported. */
409 SANITY_CHECK(unit_list_search(unit_transport_cargo(ptrans),
410 punit) != NULL);
412 /* Check the depth of the transportation. */
413 while (ptrans) {
414 struct unit_list *pcargos = unit_transport_cargo(ptrans);
416 SANITY_CHECK(pcargos != NULL);
417 SANITY_CHECK(level < GAME_TRANSPORT_MAX_RECURSIVE);
419 /* Check for next level. */
420 plevel = ptrans;
421 ptrans = unit_transport_get(plevel);
422 level++;
425 /* Transporter capacity will be checked when transporter itself
426 * is checked */
429 /* Check that cargo is marked as transported with this unit */
430 unit_list_iterate(unit_transport_cargo(punit), pcargo) {
431 SANITY_CHECK(unit_transport_get(pcargo) == punit);
432 } unit_list_iterate_end;
433 } unit_list_iterate_end;
434 } players_iterate_end;
437 /**************************************************************************
438 Sanity checks on all players.
439 **************************************************************************/
440 static void check_players(const char *file, const char *function, int line)
442 players_iterate(pplayer) {
443 int found_palace = 0;
445 if (!pplayer->is_alive) {
446 /* Dead players' units and cities are disbanded in kill_player(). */
447 SANITY_CHECK(unit_list_size(pplayer->units) == 0);
448 SANITY_CHECK(city_list_size(pplayer->cities) == 0);
450 continue;
453 SANITY_CHECK(pplayer->server.adv != NULL);
454 SANITY_CHECK(!pplayer->nation || pplayer->nation->player == pplayer);
455 SANITY_CHECK(player_list_search(team_members(pplayer->team), pplayer));
457 SANITY_CHECK(!(city_list_size(pplayer->cities) > 0
458 && !pplayer->server.got_first_city));
460 city_list_iterate(pplayer->cities, pcity) {
461 if (is_capital(pcity)) {
462 found_palace++;
464 SANITY_CITY(pcity, found_palace <= 1);
465 } city_list_iterate_end;
467 players_iterate(pplayer2) {
468 struct player_diplstate *state1 = player_diplstate_get(pplayer, pplayer2);
469 struct player_diplstate *state2 = player_diplstate_get(pplayer2, pplayer);
471 SANITY_CHECK(state1->type == state2->type);
472 if (state1->type == DS_CEASEFIRE) {
473 SANITY_CHECK(state1->turns_left == state2->turns_left);
475 if (state1->type == DS_TEAM) {
476 SANITY_CHECK(players_on_same_team(pplayer, pplayer2));
478 if (pplayer->is_alive
479 && pplayer2->is_alive
480 && pplayers_allied(pplayer, pplayer2)) {
481 enum dipl_reason allied_players_can_be_allied =
482 pplayer_can_make_treaty(pplayer, pplayer2, DS_ALLIANCE);
483 SANITY_CHECK(allied_players_can_be_allied
484 != DIPL_ALLIANCE_PROBLEM_US);
485 SANITY_CHECK(allied_players_can_be_allied
486 != DIPL_ALLIANCE_PROBLEM_THEM);
488 } players_iterate_end;
490 if (pplayer->revolution_finishes == -1) {
491 if (government_of_player(pplayer) == game.government_during_revolution) {
492 SANITY_FAIL("%s government is anarchy, but does not finish!",
493 nation_rule_name(nation_of_player(pplayer)));
495 SANITY_CHECK(government_of_player(pplayer) != game.government_during_revolution);
496 } else if (pplayer->revolution_finishes > game.info.turn) {
497 SANITY_CHECK(government_of_player(pplayer) == game.government_during_revolution);
498 } else {
499 /* Things may vary in this case depending on when the sanity_check
500 * call is made. No better check is possible. */
503 /* Dying players shouldn't be left around. But they are. */
504 SANITY_CHECK(!BV_ISSET(pplayer->server.status, PSTATUS_DYING));
505 } players_iterate_end;
507 nations_iterate(pnation) {
508 SANITY_CHECK(!pnation->player || pnation->player->nation == pnation);
509 } nations_iterate_end;
511 teams_iterate(pteam) {
512 player_list_iterate(team_members(pteam), pplayer) {
513 SANITY_CHECK(pplayer->team == pteam);
514 } player_list_iterate_end;
515 } teams_iterate_end;
518 /****************************************************************************
519 Sanity checking on teams.
520 ****************************************************************************/
521 static void check_teams(const char *file, const char *function, int line)
523 int count[MAX_NUM_TEAM_SLOTS];
525 memset(count, 0, sizeof(count));
526 players_iterate(pplayer) {
527 /* For the moment, all players have teams. */
528 SANITY_CHECK(pplayer->team != NULL);
529 if (pplayer->team) {
530 count[team_index(pplayer->team)]++;
532 } players_iterate_end;
534 team_slots_iterate(tslot) {
535 if (team_slot_is_used(tslot)) {
536 struct team *pteam = team_slot_get_team(tslot);
537 fc_assert_exit(pteam);
538 SANITY_CHECK(player_list_size(team_members(pteam))
539 == count[team_slot_index(tslot)]);
541 } team_slots_iterate_end;
544 /**************************************************************************
545 Sanity checking on connections.
546 **************************************************************************/
547 static void check_connections(const char *file, const char *function,
548 int line)
550 /* est_connections is a subset of all_connections */
551 SANITY_CHECK(conn_list_size(game.all_connections)
552 >= conn_list_size(game.est_connections));
555 /**************************************************************************
556 Do sanity checks on the server state. Call this once per turn or
557 whenever you feel like it.
559 But be careful, calling it too much would make the server slow down. And
560 at some times the server isn't supposed to be in a sane state so you
561 can't call it in the middle of an operation that is supposed to be
562 atomic.
563 **************************************************************************/
564 void real_sanity_check(const char *file, const char *function, int line)
566 if (!map_is_empty()) {
567 /* Don't sanity-check the map if it hasn't been created yet (this
568 * happens when loading scenarios). */
569 check_specials(file, function, line);
570 check_map(file, function, line);
571 check_cities(file, function, line);
572 check_units(file, function, line);
573 check_fow(file, function, line);
575 check_misc(file, function, line);
576 check_players(file, function, line);
577 check_teams(file, function, line);
578 check_connections(file, function, line);
581 /*****************************************************************************
582 Verify that the tile has sane values. This should be called after the
583 terrain is changed.
584 *****************************************************************************/
585 void real_sanity_check_tile(struct tile *ptile, const char *file,
586 const char *function, int line)
588 SANITY_CHECK(ptile != NULL);
589 SANITY_CHECK(ptile->terrain != NULL);
591 unit_list_iterate(ptile->units, punit) {
592 /* Check if the units can survive on the tile (terrain). Here only the
593 * 'easy' test if the unit is transported is done. A complete check is
594 * done by check_units() in real_sanity_check(). */
595 if (!can_unit_exist_at_tile(punit, ptile)
596 && !unit_transported(punit)) {
597 SANITY_FAIL("(%4d,%4d) %s can't survive on %s", TILE_XY(ptile),
598 unit_rule_name(punit), tile_get_info_text(ptile, TRUE, 0));
600 } unit_list_iterate_end;
603 #endif /* SANITY_CHECKING */