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.
7
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 ***********************************************************************/
13
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17
18 #include "fc_prehdrs.h"
19
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25
26 #ifdef HAVE_NETDB_H
27 #include <netdb.h>
28 #endif
29 #ifdef HAVE_SYS_IOCTL_H
30 #include <sys/ioctl.h>
31 #endif
32 #ifdef HAVE_SYS_TERMIO_H
33 #include <sys/termio.h>
34 #endif
35 #ifdef FREECIV_HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38 #ifdef HAVE_TERMIOS_H
39 #include <termios.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44
45 /* utility */
46 #include "astring.h"
47 #include "bitvector.h"
48 #include "capability.h"
49 #include "fc_cmdline.h"
50 #include "fciconv.h"
51 #include "fcintl.h"
52 #include "log.h"
53 #include "mem.h"
54 #include "netintf.h"
55 #include "rand.h"
56 #include "randseed.h"
57 #include "registry.h"
58 #include "support.h"
59 #include "timing.h"
60
61 /* common/aicore */
62 #include "citymap.h"
63
64 /* common */
65 #include "achievements.h"
66 #include "calendar.h"
67 #include "capstr.h"
68 #include "city.h"
69 #include "culture.h"
70 #include "dataio.h"
71 #include "effects.h"
72 #include "events.h"
73 #include "fc_interface.h"
74 #include "government.h"
75 #include "map.h"
76 #include "mapimg.h"
77 #include "nation.h"
78 #include "packets.h"
79 #include "player.h"
80 #include "research.h"
81 #include "tech.h"
82 #include "unitlist.h"
83 #include "version.h"
84 #include "victory.h"
85
86 /* server/generator */
87 #include "mapgen.h"
88 #include "utilities.h"
89
90 /* server/scripting */
91 #include "script_server.h"
92 #include "luascript_types.h"
93
94 /* server */
95 #include "aiiface.h"
96 #include "animals.h"
97 #include "auth.h"
98 #include "barbarian.h"
99 #include "cityhand.h"
100 #include "citytools.h"
101 #include "cityturn.h"
102 #include "connecthand.h"
103 #include "console.h"
104 #include "fcdb.h"
105 #include "diplhand.h"
106 #include "edithand.h"
107 #include "gamehand.h"
108 #include "handchat.h"
109 #include "maphand.h"
110 #include "meta.h"
111 #include "notify.h"
112 #include "plrhand.h"
113 #include "report.h"
114 #include "ruleset.h"
115 #include "sanitycheck.h"
116 #include "savegame2.h"
117 #include "score.h"
118 #include "sernet.h"
119 #include "settings.h"
120 #include "spacerace.h"
121 #include "srv_log.h"
122 #include "stdinhand.h"
123 #include "techtools.h"
124 #include "unithand.h"
125 #include "unittools.h"
126 #include "voting.h"
127
128 /* server/advisors */
129 #include "advdata.h"
130 #include "autosettlers.h"
131 #include "advbuilding.h"
132 #include "advspace.h"
133 #include "infracache.h"
134
135 /* ai */
136 #include "aitraits.h"
137 #include "difficulty.h"
138
139 #include "srv_main.h"
140
141 static void end_turn(void);
142 static void announce_player(struct player *pplayer);
143 static void fc_interface_init_server(void);
144
145 static enum known_type mapimg_server_tile_known(const struct tile *ptile,
146 const struct player *pplayer,
147 bool knowledge);
148 static struct terrain
149 *mapimg_server_tile_terrain(const struct tile *ptile,
150 const struct player *pplayer, bool knowledge);
151 static struct player *mapimg_server_tile_owner(const struct tile *ptile,
152 const struct player *pplayer,
153 bool knowledge);
154 static struct player *mapimg_server_tile_city(const struct tile *ptile,
155 const struct player *pplayer,
156 bool knowledge);
157 static struct player *mapimg_server_tile_unit(const struct tile *ptile,
158 const struct player *pplayer,
159 bool knowledge);
160
161 static int mapimg_server_plrcolor_count(void);
162 static struct rgbcolor *mapimg_server_plrcolor_get(int i);
163
164 static void handle_observer_ready(struct connection *pconn);
165
166 /* command-line arguments to server */
167 struct server_arguments srvarg;
168
169 /* server aggregate information */
170 struct civserver server;
171
172 /* server state information */
173 static enum server_states civserver_state = S_S_INITIAL;
174
175 /* this global is checked deep down the netcode.
176 packets handling functions can set it to none-zero, to
177 force end-of-tick asap
178 */
179 bool force_end_of_sniff;
180
181 #define IDENTITY_NUMBER_SIZE 250000
182 BV_DEFINE(bv_identity_numbers, IDENTITY_NUMBER_SIZE);
183 bv_identity_numbers identity_numbers_used;
184
185 /* server initialized flag */
186 static bool has_been_srv_init = FALSE;
187
188 /* time server processing at end-of-turn */
189 static struct timer *eot_timer = NULL;
190
191 static struct timer *between_turns = NULL;
192
193 /**************************************************************************
194 Initialize the game seed. This may safely be called multiple times.
195 **************************************************************************/
init_game_seed(void)196 void init_game_seed(void)
197 {
198 if (game.server.seed_setting == 0) {
199 /* We strip the high bit for now because neither game file nor
200 server options can handle unsigned ints yet. - Cedric */
201 game.server.seed = generate_game_seed() & (MAX_UINT32 >> 1);
202 #ifdef FREECIV_TESTMATIC
203 /* Log command to reproduce the gameseed */
204 log_testmatic("set gameseed %u", game.server.seed);
205 #else /* FREECIV_TESTMATIC */
206 log_debug("Setting game.seed:%u", game.server.seed);
207 #endif /* FREECIV_TESTMATIC */
208 } else {
209 game.server.seed = game.server.seed_setting;
210 }
211
212 if (!fc_rand_is_init()) {
213 fc_srand(game.server.seed);
214 }
215 }
216
217 /**************************************************************************
218 Initialize freeciv server.
219 **************************************************************************/
srv_init(void)220 void srv_init(void)
221 {
222 i_am_server(); /* Tell to libfreeciv that we are server */
223
224 /* NLS init */
225 init_nls();
226 #ifdef ENABLE_NLS
227 (void) bindtextdomain("freeciv-nations", get_locale_dir());
228 #endif
229
230 /* This is before ai module initializations so that if ai module
231 * wants to use registry files, it can. */
232 registry_module_init();
233
234 /* We want this before any AI stuff */
235 timing_log_init();
236
237 /* This must be before command line argument parsing.
238 This allocates default ai, and we want that to take place before
239 loading additional ai modules from command line. */
240 ai_init();
241
242 /* init server arguments... */
243
244 srvarg.metaserver_no_send = DEFAULT_META_SERVER_NO_SEND;
245 sz_strlcpy(srvarg.metaserver_addr, DEFAULT_META_SERVER_ADDR);
246 srvarg.metaconnection_persistent = FALSE;
247 srvarg.identity_name[0] = '\0';
248 srvarg.serverid[0] = '\0';
249
250 srvarg.bind_addr = NULL;
251 srvarg.port = DEFAULT_SOCK_PORT;
252
253 srvarg.bind_meta_addr = NULL;
254
255 srvarg.loglevel = LOG_NORMAL;
256
257 srvarg.log_filename = NULL;
258 srvarg.fatal_assertions = -1;
259 srvarg.ranklog_filename = NULL;
260 srvarg.load_filename[0] = '\0';
261 srvarg.script_filename = NULL;
262 srvarg.saves_pathname = "";
263 srvarg.scenarios_pathname = "";
264
265 srvarg.quitidle = 0;
266
267 srvarg.fcdb_enabled = FALSE;
268 srvarg.fcdb_conf = NULL;
269 srvarg.auth_enabled = FALSE;
270 srvarg.auth_allow_guests = FALSE;
271 srvarg.auth_allow_newusers = FALSE;
272
273 /* mark as initialized */
274 has_been_srv_init = TRUE;
275
276 /* init character encodings. */
277 init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE);
278 #ifdef ENABLE_NLS
279 bind_textdomain_codeset("freeciv-nations", get_internal_encoding());
280 #endif
281
282 /* Initialize callbacks. */
283 game.callbacks.unit_deallocate = identity_number_release;
284
285 /* Initialize global mutexes */
286 fc_init_mutex(&game.server.mutexes.city_list);
287
288 /* done */
289 return;
290 }
291
292 /**************************************************************************
293 Handle client info packet
294 **************************************************************************/
handle_client_info(struct connection * pc,enum gui_type gui,const char * distribution)295 void handle_client_info(struct connection *pc, enum gui_type gui,
296 const char *distribution)
297 {
298 log_debug("%s's client has %s gui.", pc->username, gui_type_name(gui));
299 if (strcmp(distribution, "")) {
300 log_debug("It comes from %s distribution.", distribution);
301 }
302 }
303
304 /**************************************************************************
305 Return current server state.
306 **************************************************************************/
server_state(void)307 enum server_states server_state(void)
308 {
309 return civserver_state;
310 }
311
312 /**************************************************************************
313 Set current server state.
314 **************************************************************************/
set_server_state(enum server_states newstate)315 void set_server_state(enum server_states newstate)
316 {
317 civserver_state = newstate;
318 }
319
320 /**************************************************************************
321 Returns iff the game was started once upon a time.
322 **************************************************************************/
game_was_started(void)323 bool game_was_started(void)
324 {
325 return (!game.info.is_new_game || S_S_INITIAL != server_state());
326 }
327
328 /****************************************************************************
329 Returns TRUE if any one game end condition is fulfilled, FALSE otherwise.
330
331 This function will notify players but will not set the server_state(). The
332 caller must set the server state to S_S_OVER if the function
333 returns TRUE.
334
335 Also send notifications about impending, predictable game end conditions.
336 ****************************************************************************/
check_for_game_over(void)337 bool check_for_game_over(void)
338 {
339 int candidates, defeated;
340 struct player *victor;
341 int winners = 0;
342 struct astring str = ASTRING_INIT;
343
344 /* Check for scenario victory; dead players can win if they are on a team
345 * with the winners. */
346 players_iterate(pplayer) {
347 if (player_status_check(pplayer, PSTATUS_WINNER)
348 || get_player_bonus(pplayer, EFT_VICTORY) > 0) {
349 if (winners) {
350 /* TRANS: Another entry in winners list (", the Tibetans") */
351 astr_add(&str, Q_("?winners:, the %s"),
352 nation_plural_for_player(pplayer));
353 } else {
354 /* TRANS: Beginning of the winners list ("the French") */
355 astr_add(&str, Q_("?winners:the %s"),
356 nation_plural_for_player(pplayer));
357 }
358 pplayer->is_winner = TRUE;
359 winners++;
360 }
361 } players_iterate_end;
362 if (winners) {
363 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
364 /* TRANS: There can be several winners listed */
365 _("Scenario victory to %s."), astr_str(&str));
366 astr_free(&str);
367 return TRUE;
368 }
369 astr_free(&str);
370
371 /* Count candidates for the victory. */
372 candidates = 0;
373 defeated = 0;
374 victor = NULL;
375 /* Do not use player_iterate_alive here - dead player must be counted as
376 * defeated to end the game with a victory. */
377 players_iterate(pplayer) {
378 if (is_barbarian(pplayer)) {
379 continue;
380 }
381
382 if ((pplayer)->is_alive
383 && !player_status_check((pplayer), PSTATUS_SURRENDER)) {
384 candidates++;
385 victor = pplayer;
386 } else {
387 defeated++;
388 }
389 } players_iterate_end;
390
391 if (0 == candidates) {
392 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
393 _("Game is over."));
394 return TRUE;
395 } else if (0 < defeated) {
396 /* If nobody conceded the game, it mays be a solo game or a single team
397 * game. */
398 fc_assert(NULL != victor);
399
400 /* Quit if we have team victory. */
401 if (1 < team_count()) {
402 teams_iterate(pteam) {
403 const struct player_list *members = team_members(pteam);
404 int team_candidates = 0, team_defeated = 0;
405
406 if (1 == player_list_size(members)) {
407 /* This is not really a team, single players are handled below. */
408 continue;
409 }
410
411 player_list_iterate(members, pplayer) {
412 if (pplayer->is_alive
413 && !player_status_check((pplayer), PSTATUS_SURRENDER)) {
414 team_candidates++;
415 } else {
416 team_defeated++;
417 }
418 } player_list_iterate_end;
419
420 fc_assert(team_candidates + team_defeated
421 == player_list_size(members));
422
423 if (team_candidates == candidates && team_defeated < defeated) {
424 /* We need a player in a other team to conced the game here. */
425 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
426 _("Team victory to %s."),
427 team_name_translation(pteam));
428 /* All players of the team win, even dead and surrended ones. */
429 player_list_iterate(members, pplayer) {
430 pplayer->is_winner = TRUE;
431 } player_list_iterate_end;
432 return TRUE;
433 }
434 } teams_iterate_end;
435 }
436
437 /* Check for allied victory. */
438 if (1 < candidates && victory_enabled(VC_ALLIED)) {
439 struct player_list *winner_list = player_list_new();
440
441 /* Try to build a winner list. */
442 players_iterate_alive(pplayer) {
443 if (is_barbarian(pplayer)
444 || player_status_check((pplayer), PSTATUS_SURRENDER)) {
445 continue;
446 }
447
448 player_list_iterate(winner_list, aplayer) {
449 if (!pplayers_allied(aplayer, pplayer)) {
450 player_list_destroy(winner_list);
451 winner_list = NULL;
452 break;
453 }
454 } player_list_iterate_end;
455
456 if (NULL == winner_list) {
457 break;
458 }
459 player_list_append(winner_list, pplayer);
460 } players_iterate_alive_end;
461
462 if (NULL != winner_list) {
463 bool first = TRUE;
464
465 fc_assert(candidates == player_list_size(winner_list));
466
467 astr_init(&str);
468 player_list_iterate(winner_list, pplayer) {
469 if (first) {
470 /* TRANS: Beginning of the winners list ("the French") */
471 astr_add(&str, Q_("?winners:the %s"),
472 nation_plural_for_player(pplayer));
473 first = FALSE;
474 } else {
475 /* TRANS: Another entry in winners list (", the Tibetans") */
476 astr_add(&str, Q_("?winners:, the %s"),
477 nation_plural_for_player(pplayer));
478 }
479 pplayer->is_winner = TRUE;
480 } player_list_iterate_end;
481 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
482 /* TRANS: There can be several winners listed */
483 _("Allied victory to %s."), astr_str(&str));
484 astr_free(&str);
485 player_list_destroy(winner_list);
486 return TRUE;
487 }
488 }
489
490 /* Check for single player victory. */
491 if (1 == candidates && NULL != victor) {
492 bool found = FALSE; /* We need at least one enemy defeated. */
493
494 players_iterate(pplayer) {
495 if (pplayer != victor
496 && !is_barbarian(pplayer)
497 && (!pplayer->is_alive
498 || player_status_check((pplayer), PSTATUS_SURRENDER))
499 && pplayer->team != victor->team
500 && (!victory_enabled(VC_ALLIED)
501 || !pplayers_allied(victor, pplayer))) {
502 found = TRUE;
503 break;
504 }
505 } players_iterate_end;
506
507 if (found) {
508 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
509 _("Game ended in conquest victory for %s."), player_name(victor));
510 victor->is_winner = TRUE;
511 return TRUE;
512 }
513 }
514 }
515
516 /* Check for culture victory */
517 if (victory_enabled(VC_CULTURE)) {
518 struct player *best = NULL;
519 int best_value = -1;
520 int second_value = -1;
521
522 players_iterate(pplayer) {
523 if (is_barbarian(pplayer) || !pplayer->is_alive) {
524 continue;
525 }
526
527 if (pplayer->score.culture > best_value) {
528 best = pplayer;
529 second_value = best_value;
530 best_value = pplayer->score.culture;
531 } else if (pplayer->score.culture > second_value) {
532 second_value = pplayer->score.culture;
533 }
534 } players_iterate_end;
535
536 if (best != NULL && best_value >= game.info.culture_vic_points
537 && best_value > second_value * (100 + game.info.culture_vic_lead) / 100) {
538 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
539 _("Game ended in cultural domination victory for %s."),
540 player_name(best));
541 best->is_winner = TRUE;
542
543 return TRUE;
544 }
545 }
546
547 /* Quit if we are past the turn limit. */
548 if (game.info.turn > game.server.end_turn) {
549 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
550 _("Game ended as the turn limit was exceeded."));
551 return TRUE;
552 } else if (game.info.turn == game.server.end_turn) {
553 /* Give them a chance to decide to extend the game */
554 notify_conn(game.est_connections, NULL, E_GAME_END, ftc_server,
555 _("Notice: game will end at the end of this turn due "
556 "to 'endturn' server setting."));
557 }
558
559 /* Check for a spacerace win (and notify of imminent arrivals).
560 * Check this after checking turn limit, because we are checking for
561 * the spaceship arriving in the year corresponding to the turn
562 * that's about to start. */
563 {
564 int n, i;
565 struct player *arrivals[MAX_NUM_PLAYER_SLOTS];
566
567 n = rank_spaceship_arrival(arrivals);
568
569 for (i = 0; i < n; i++) {
570 struct player *pplayer = arrivals[i];
571 const struct player_list *members;
572 bool win;
573
574 if (game.info.year32 < (int)spaceship_arrival(pplayer)) {
575 /* We are into the future arrivals */
576 break;
577 }
578
579 /* Mark as arrived and notify everyone. */
580 spaceship_arrived(pplayer);
581
582 if (!game.server.endspaceship) {
583 /* Games does not end on spaceship arrival. At least print all the
584 * arrival messages. */
585 continue;
586 }
587
588 /* This player has won, now check if anybody else wins with them. */
589 members = team_members(pplayer->team);
590 win = FALSE;
591 player_list_iterate(members, pteammate) {
592 if (pplayer->is_alive
593 && !player_status_check((pteammate), PSTATUS_SURRENDER)) {
594 /* We need at least one player to be a winner candidate in the
595 * team. */
596 win = TRUE;
597 break;
598 }
599 } player_list_iterate_end;
600
601 if (!win) {
602 /* Let's try next arrival. */
603 continue;
604 }
605
606 if (1 < player_list_size(members)) {
607 notify_conn(NULL, NULL, E_GAME_END, ftc_server,
608 _("Team victory to %s."),
609 team_name_translation(pplayer->team));
610 /* All players of the team win, even dead and surrendered ones. */
611 player_list_iterate(members, pteammate) {
612 pteammate->is_winner = TRUE;
613 } player_list_iterate_end;
614 } else {
615 notify_conn(NULL, NULL, E_GAME_END, ftc_server,
616 _("Game ended in victory for %s."), player_name(pplayer));
617 pplayer->is_winner = TRUE;
618 }
619 return TRUE;
620 }
621
622 /* Print notice(s) of imminent arrival. These are not infallible
623 * (quite apart from risk of enemy action) because arrival is
624 * year-based, and some effect may change the timeline between
625 * now and the end of the next turn.
626 * (Also the order of messages will not always indicate tie-breaks,
627 * if the shuffled order is changed every turn, as it is for
628 * PMT_CONCURRENT games.) */
629 for (; i < n; i++) {
630 const struct player *pplayer = arrivals[i];
631 struct packet_game_info next_info = game.info; /* struct copy */
632
633 /* Advance the calendar in a throwaway copy of game.info. */
634 game_next_year(&next_info);
635
636 if (next_info.year32 < (int)spaceship_arrival(pplayer)) {
637 /* Even further in the future */
638 break;
639 }
640
641 notify_player(NULL, NULL, E_SPACESHIP, ftc_server,
642 _("Notice: the %s spaceship will likely arrive at "
643 "Alpha Centauri next turn."),
644 nation_adjective_for_player(pplayer));
645 }
646 }
647
648 return FALSE;
649 }
650
651 /**************************************************************************
652 Send all information for when game starts or client reconnects.
653 Initial packets should have been sent before calling this function.
654 See comment in connecthand.c::establish_new_connection().
655 **************************************************************************/
send_all_info(struct conn_list * dest)656 void send_all_info(struct conn_list *dest)
657 {
658 conn_list_iterate(dest, pconn) {
659 if (conn_controls_player(pconn)) {
660 send_attribute_block(pconn->playing, pconn);
661 }
662 } conn_list_iterate_end;
663
664 /* Resend player info because it could have more infos (e.g. embassy). */
665 send_player_all_c(NULL, dest);
666 researches_iterate(presearch) {
667 send_research_info(presearch, dest);
668 } researches_iterate_end;
669 send_map_info(dest);
670 send_all_known_tiles(dest);
671 send_all_known_cities(dest);
672 send_all_known_units(dest);
673 send_spaceship_info(NULL, dest);
674
675 cities_iterate(pcity) {
676 package_and_send_worker_tasks(pcity);
677 } cities_iterate_end;
678 }
679
680 /**************************************************************************
681 Give map information to players with EFT_REVEAL_CITIES or
682 EFT_REVEAL_MAP effects (traditionally from the Apollo Program).
683 **************************************************************************/
do_reveal_effects(void)684 static void do_reveal_effects(void)
685 {
686 phase_players_iterate(pplayer) {
687 if (get_player_bonus(pplayer, EFT_REVEAL_CITIES) > 0) {
688 players_iterate(other_player) {
689 city_list_iterate(other_player->cities, pcity) {
690 map_show_tile(pplayer, pcity->tile);
691 } city_list_iterate_end;
692 } players_iterate_end;
693 }
694 if (get_player_bonus(pplayer, EFT_REVEAL_MAP) > 0) {
695 /* map_know_all will mark all unknown tiles as known and send
696 * tile, unit, and city updates as necessary. No other actions are
697 * needed. */
698 map_show_all(pplayer);
699 }
700 } phase_players_iterate_end;
701 }
702
703 /**************************************************************************
704 Give contact to players with the EFT_HAVE_EMBASSIES effect (traditionally
705 from Marco Polo's Embassy).
706 **************************************************************************/
do_have_embassies_effect(void)707 static void do_have_embassies_effect(void)
708 {
709 phase_players_iterate(pplayer) {
710 if (get_player_bonus(pplayer, EFT_HAVE_EMBASSIES) > 0) {
711 players_iterate(pother) {
712 /* Note this gives pplayer contact with pother, but doesn't give
713 * pother contact with pplayer. This may cause problems in other
714 * parts of the code if we're not careful. */
715 make_contact(pplayer, pother, NULL);
716 } players_iterate_end;
717 }
718 } phase_players_iterate_end;
719 }
720
721 /**************************************************************************
722 Handle environmental upsets, meaning currently pollution or fallout.
723 **************************************************************************/
update_environmental_upset(enum environment_upset_type type,int * current,int * accum,int * level,void (* upset_action_fn)(int))724 static void update_environmental_upset(enum environment_upset_type type,
725 int *current, int *accum, int *level,
726 void (*upset_action_fn)(int))
727 {
728 int count;
729
730 count = 0;
731 extra_type_iterate(cause) {
732 if (extra_causes_env_upset(cause, type)) {
733 whole_map_iterate(ptile) {
734 if (tile_has_extra(ptile, cause)) {
735 count++;
736 }
737 } whole_map_iterate_end;
738 }
739 } extra_type_iterate_end;
740
741 *current = count;
742 *accum += count;
743 if (*accum < *level) {
744 *accum = 0;
745 } else {
746 *accum -= *level;
747 if (fc_rand((map_num_tiles() + 19) / 20) < *accum) {
748 upset_action_fn((game.map.xsize / 10) + (game.map.ysize / 10) + ((*accum) * 5));
749 *accum = 0;
750 *level += (map_num_tiles() + 999) / 1000;
751 }
752 }
753
754 log_debug("environmental_upset: type=%-4d current=%-2d "
755 "level=%-2d accum=%-2d", type, *current, *level, *accum);
756 }
757
758 /**********************************************************************//**
759 Notify about units at risk of disband due to armistice.
760 **************************************************************************/
notify_illegal_armistice_units(struct player * phost,struct player * pguest,int turns_left)761 static void notify_illegal_armistice_units(struct player *phost,
762 struct player *pguest,
763 int turns_left)
764 {
765 int nunits = 0;
766 struct unit *a_unit = NULL;
767
768 unit_list_iterate(pguest->units, punit) {
769 if (tile_owner(unit_tile(punit)) == phost && is_military_unit(punit)) {
770 nunits++;
771 a_unit = punit;
772 }
773 } unit_list_iterate_end;
774 if (nunits > 0) {
775 struct astring unitstr = ASTRING_INIT;
776
777 astr_set(&unitstr,
778 /* TRANS: "... 2 military units in Norwegian territory." */
779 PL_("Warning: you still have %d military unit in %s territory.",
780 "Warning: you still have %d military units in %s territory.",
781 nunits),
782 nunits, nation_adjective_for_player(phost));
783 /* If there's one lousy unit left, we may as well include a link for it */
784 notify_player(pguest, nunits == 1 ? unit_tile(a_unit) : NULL,
785 E_DIPLOMACY, ftc_server,
786 /* TRANS: %s is another, separately translated sentence,
787 * ending in a full stop. */
788 PL_("%s Any such units will be disbanded in %d turn, "
789 "in accordance with peace treaty.",
790 "%s Any such units will be disbanded in %d turns, "
791 "in accordance with peace treaty.", turns_left),
792 astr_str(&unitstr), turns_left);
793 astr_free(&unitstr);
794 }
795 }
796
797 /**************************************************************************
798 Remove illegal units when armistice turns into peace treaty.
799 **************************************************************************/
remove_illegal_armistice_units(struct player * plr1,struct player * plr2)800 static void remove_illegal_armistice_units(struct player *plr1,
801 struct player *plr2)
802 {
803 /* Remove illegal units */
804 unit_list_iterate_safe(plr1->units, punit) {
805 if (tile_owner(unit_tile(punit)) == plr2
806 && is_military_unit(punit)) {
807 notify_player(plr1, unit_tile(punit), E_DIPLOMACY, ftc_server,
808 _("Your %s was disbanded in accordance with "
809 "your peace treaty with the %s."),
810 unit_tile_link(punit),
811 nation_plural_for_player(plr2));
812 wipe_unit(punit, ULR_ARMISTICE, NULL);
813 }
814 } unit_list_iterate_safe_end;
815 unit_list_iterate_safe(plr2->units, punit) {
816 if (tile_owner(unit_tile(punit)) == plr1
817 && is_military_unit(punit)) {
818 notify_player(plr2, unit_tile(punit), E_DIPLOMACY, ftc_server,
819 _("Your %s was disbanded in accordance with "
820 "your peace treaty with the %s."),
821 unit_tile_link(punit),
822 nation_plural_for_player(plr1));
823 wipe_unit(punit, ULR_ARMISTICE, NULL);
824 }
825 } unit_list_iterate_safe_end;
826 }
827
828 /**************************************************************************
829 Check for cease-fires and armistices running out; update cancelling
830 reasons and contact information.
831 **************************************************************************/
update_diplomatics(void)832 static void update_diplomatics(void)
833 {
834 players_iterate_alive(plr1) {
835 players_iterate_alive(plr2) {
836 struct player_diplstate *state = player_diplstate_get(plr1, plr2);
837
838 /* Players might just met when first of them was being handled
839 * (pact with third player changed and units got bounced next
840 * to second unit to form first contact)
841 * Do not decrease the counters for the other player yet in this turn */
842 if (state->first_contact_turn != game.info.turn) {
843 struct player_diplstate *state2 = player_diplstate_get(plr2, plr1);
844
845 state->has_reason_to_cancel = MAX(state->has_reason_to_cancel - 1, 0);
846 state->contact_turns_left = MAX(state->contact_turns_left - 1, 0);
847
848 if (state->type == DS_ARMISTICE
849 /* Don't count down if auto canceled this turn. Auto canceling
850 * happens in this loop. */
851 && state->auto_cancel_turn != game.info.turn) {
852 state->turns_left--;
853 if (state->turns_left <= 0) {
854 state->type = DS_PEACE;
855 state2->type = DS_PEACE;
856 state->turns_left = 0;
857 state2->turns_left = 0;
858 remove_illegal_armistice_units(plr1, plr2);
859 } else {
860 notify_illegal_armistice_units(plr1, plr2, state->turns_left);
861 }
862 }
863
864 if (state->type == DS_CEASEFIRE) {
865 state->turns_left--;
866 switch(state->turns_left) {
867 case 1:
868 notify_player(plr1, NULL, E_DIPLOMACY, ftc_server,
869 _("Concerned citizens point out that the cease-fire "
870 "with %s will run out soon."), player_name(plr2));
871 /* Message to plr2 will be done when plr1 and plr2 will be swapped.
872 * Else, we will get a message duplication. Note the case is not
873 * the below, because the state will be changed for both players to
874 * war. */
875 break;
876 case 0:
877 notify_player(plr1, NULL, E_DIPLOMACY, ftc_server,
878 _("The cease-fire with %s has run out. "
879 "You are now at war with the %s."),
880 player_name(plr2),
881 nation_plural_for_player(plr2));
882 notify_player(plr2, NULL, E_DIPLOMACY, ftc_server,
883 _("The cease-fire with %s has run out. "
884 "You are now at war with the %s."),
885 player_name(plr1),
886 nation_plural_for_player(plr1));
887 state->type = DS_WAR;
888 state2->type = DS_WAR;
889 state->turns_left = 0;
890 state2->turns_left = 0;
891
892 enter_war(plr1, plr2);
893
894 city_map_update_all_cities_for_player(plr1);
895 city_map_update_all_cities_for_player(plr2);
896 sync_cities();
897
898 /* Avoid love-love-hate triangles */
899 players_iterate_alive(plr3) {
900 if (plr3 != plr1 && plr3 != plr2
901 && pplayers_allied(plr3, plr1)
902 && pplayers_allied(plr3, plr2)) {
903 struct player_diplstate *to1
904 = player_diplstate_get(plr3, plr1);
905 struct player_diplstate *from1
906 = player_diplstate_get(plr1, plr3);
907 struct player_diplstate *to2
908 = player_diplstate_get(plr3, plr2);
909 struct player_diplstate *from2
910 = player_diplstate_get(plr2, plr3);
911 const char *plr1name = player_name(plr1);
912 const char *plr2name = player_name(plr2);
913 bool cancel1;
914 bool cancel2;
915
916 if (players_on_same_team(plr3, plr1)) {
917 fc_assert(!players_on_same_team(plr3, plr2));
918
919 cancel1 = FALSE;
920 cancel2 = TRUE;
921
922 notify_player(plr3, NULL, E_TREATY_BROKEN, ftc_server,
923 _("The cease-fire between %s and %s has run out. "
924 "They are at war. You cancel your alliance "
925 "with %s."),
926 plr1name, plr2name, plr2name);
927 } else if (players_on_same_team(plr3, plr2)) {
928
929 cancel1 = TRUE;
930 cancel2 = FALSE;
931
932 notify_player(plr3, NULL, E_TREATY_BROKEN, ftc_server,
933 _("The cease-fire between %s and %s has run out. "
934 "They are at war. You cancel your alliance "
935 "with %s."),
936 plr1name, plr2name, plr1name);
937 } else {
938
939 cancel1 = TRUE;
940 cancel2 = TRUE;
941
942 notify_player(plr3, NULL, E_TREATY_BROKEN, ftc_server,
943 _("The cease-fire between %s and %s has run out. "
944 "They are at war. You cancel your alliance "
945 "with both."),
946 player_name(plr1),
947 player_name(plr2));
948 }
949
950 if (cancel1) {
951 /* Cancel the alliance. */
952 to1->has_reason_to_cancel = 1;
953 handle_diplomacy_cancel_pact(plr3, player_number(plr1), CLAUSE_ALLIANCE);
954
955 /* Avoid asymmetric turns_left for the armistice. */
956 to1->auto_cancel_turn = game.info.turn;
957 from1->auto_cancel_turn = game.info.turn;
958
959 /* Count down for this turn. */
960 to1->turns_left--;
961 from1->turns_left--;
962 }
963
964 if (cancel2) {
965 /* Cancel the alliance. */
966 to2->has_reason_to_cancel = 1;
967 handle_diplomacy_cancel_pact(plr3, player_number(plr2), CLAUSE_ALLIANCE);
968
969 /* Avoid asymmetric turns_left for the armistice. */
970 to2->auto_cancel_turn = game.info.turn;
971 from2->auto_cancel_turn = game.info.turn;
972
973 /* Count down for this turn. */
974 to2->turns_left--;
975 from2->turns_left--;
976 }
977 }
978 } players_iterate_alive_end;
979 break;
980 }
981 }
982 }
983 } players_iterate_alive_end;
984 } players_iterate_alive_end;
985 }
986
987 /****************************************************************************
988 Check all players to see whether they are dying.
989
990 WARNING: do not call this while doing any handling of players, units,
991 etc. If a player dies, all his units will be wiped and other data will
992 be overwritten.
993 ****************************************************************************/
kill_dying_players(void)994 static void kill_dying_players(void)
995 {
996 bool voter_died = FALSE;
997
998 players_iterate_alive(pplayer) {
999 /* cities or units remain? */
1000 if (0 == city_list_size(pplayer->cities)
1001 && 0 == unit_list_size(pplayer->units)) {
1002 player_status_add(pplayer, PSTATUS_DYING);
1003 }
1004 /* also UTYF_GAMELOSS in unittools server_remove_unit() */
1005 if (player_status_check(pplayer, PSTATUS_DYING)) {
1006 /* Can't get more dead than this. */
1007 voter_died = voter_died || pplayer->is_connected;
1008 kill_player(pplayer);
1009 }
1010 } players_iterate_alive_end;
1011
1012 if (voter_died) {
1013 send_updated_vote_totals(NULL);
1014 }
1015 }
1016
1017 /**************************************************************************
1018 Called at the start of each (new) phase to do AI activities.
1019 **************************************************************************/
ai_start_phase(void)1020 static void ai_start_phase(void)
1021 {
1022 phase_players_iterate(pplayer) {
1023 if (pplayer->ai_controlled) {
1024 CALL_PLR_AI_FUNC(first_activities, pplayer, pplayer);
1025 }
1026 } phase_players_iterate_end;
1027 kill_dying_players();
1028 }
1029
1030 /**************************************************************************
1031 Handle the beginning of each turn.
1032 Note: This does not give "time" to any player;
1033 it is solely for updating turn-dependent data.
1034 **************************************************************************/
begin_turn(bool is_new_turn)1035 static void begin_turn(bool is_new_turn)
1036 {
1037 log_debug("Begin turn");
1038
1039 event_cache_remove_old();
1040
1041 /* Reset this each turn. */
1042 if (is_new_turn) {
1043 if (game.info.phase_mode != game.server.phase_mode_stored) {
1044 event_cache_phases_invalidate();
1045 game.info.phase_mode = game.server.phase_mode_stored;
1046 }
1047 }
1048
1049 /* NB: Phase logic must match is_player_phase(). */
1050 switch (game.info.phase_mode) {
1051 case PMT_CONCURRENT:
1052 game.server.num_phases = 1;
1053 break;
1054 case PMT_PLAYERS_ALTERNATE:
1055 game.server.num_phases = player_count();
1056 break;
1057 case PMT_TEAMS_ALTERNATE:
1058 game.server.num_phases = team_count();
1059 break;
1060 default:
1061 log_error("Unrecognized phase mode %d in begin_turn().",
1062 game.info.phase_mode);
1063 game.server.num_phases = 1;
1064 break;
1065 }
1066 send_game_info(NULL);
1067
1068 if (is_new_turn) {
1069 script_server_signal_emit("turn_started", 2,
1070 API_TYPE_INT, game.info.turn,
1071 API_TYPE_INT, game.info.year32);
1072
1073 /* We build scores at the beginning of every turn. We have to
1074 * build them at the beginning so that the AI can use the data,
1075 * and we are sure to have it when we need it. */
1076 players_iterate(pplayer) {
1077 calc_civ_score(pplayer);
1078 } players_iterate_end;
1079 log_civ_score_now();
1080
1081 /* Retire useless barbarian units */
1082 players_iterate(pplayer) {
1083 unit_list_iterate_safe(pplayer->units, punit) {
1084 struct tile *ptile = punit->tile;
1085
1086 if (unit_can_be_retired(punit)
1087 && fc_rand(100) < get_unit_bonus(punit, EFT_RETIRE_PCT)) {
1088 notify_player(pplayer, ptile, E_UNIT_LOST_MISC, ftc_server,
1089 /* TRANS: %s is a unit type */
1090 _("%s retired!"), unit_tile_link(punit));
1091 wipe_unit(punit, ULR_RETIRED, NULL);
1092 continue;
1093 }
1094 } unit_list_iterate_safe_end;
1095 } players_iterate_end;
1096 }
1097
1098 /* find out if users attached to players have been attached to those players
1099 * for long enough. The first user to do so becomes "associated" to that
1100 * player for ranking purposes. */
1101 players_iterate(pplayer) {
1102 if (pplayer->unassigned_ranked
1103 && pplayer->user_turns++ > TURNS_NEEDED_TO_RANK
1104 && pplayer->is_alive) {
1105 sz_strlcpy(pplayer->ranked_username, pplayer->username);
1106 pplayer->unassigned_ranked = pplayer->unassigned_user;
1107 }
1108 } players_iterate_end;
1109
1110 if (is_new_turn) {
1111 /* See if the value of fog of war has changed */
1112 if (game.info.fogofwar != game.server.fogofwar_old) {
1113 if (game.info.fogofwar) {
1114 enable_fog_of_war();
1115 game.server.fogofwar_old = TRUE;
1116 } else {
1117 disable_fog_of_war();
1118 game.server.fogofwar_old = FALSE;
1119 }
1120 }
1121
1122 if (game.info.phase_mode == PMT_CONCURRENT) {
1123 log_debug("Shuffleplayers");
1124 shuffle_players();
1125 }
1126
1127 game.info.phase = 0;
1128 }
1129
1130 sanity_check();
1131 }
1132
1133 /**************************************************************************
1134 Begin a phase of movement. This handles all beginning-of-phase actions
1135 for one or more players.
1136 **************************************************************************/
begin_phase(bool is_new_phase)1137 static void begin_phase(bool is_new_phase)
1138 {
1139 log_debug("Begin phase");
1140
1141 conn_list_do_buffer(game.est_connections);
1142
1143 phase_players_iterate(pplayer) {
1144 if (is_new_phase || !game.server.turnblock) {
1145 /* Otherwise respect what was loaded from the savegame. */
1146 pplayer->phase_done = FALSE;
1147 }
1148 pplayer->ai_phase_done = FALSE;
1149 } phase_players_iterate_end;
1150 send_player_all_c(NULL, NULL);
1151
1152 dlsend_packet_start_phase(game.est_connections, game.info.phase);
1153
1154 if (!is_new_phase || game.info.turn == FIRST_TURN) {
1155 /* Starting from a savegame or from the very beginning */
1156 conn_list_iterate(game.est_connections, pconn) {
1157 send_diplomatic_meetings(pconn);
1158 } conn_list_iterate_end;
1159 }
1160
1161 /* Must be the first thing as it is needed for lots of functions below! */
1162 phase_players_iterate(pplayer) {
1163 /* human players also need this for building advice */
1164 adv_data_phase_init(pplayer, is_new_phase);
1165 CALL_PLR_AI_FUNC(phase_begin, pplayer, pplayer, is_new_phase);
1166 } phase_players_iterate_end;
1167
1168 if (is_new_phase) {
1169 /* Unit "end of turn" activities - of course these actually go at
1170 * the start of the turn! */
1171 phase_players_iterate(pplayer) {
1172 update_unit_activities(pplayer);
1173 flush_packets();
1174 } phase_players_iterate_end;
1175 /* Execute orders after activities have been completed (roads built,
1176 * pillage done, etc.). */
1177 phase_players_iterate(pplayer) {
1178 execute_unit_orders(pplayer);
1179 flush_packets();
1180 } phase_players_iterate_end;
1181 phase_players_iterate(pplayer) {
1182 finalize_unit_phase_beginning(pplayer);
1183 } phase_players_iterate_end;
1184 flush_packets();
1185 }
1186
1187 phase_players_iterate(pplayer) {
1188 log_debug("beginning player turn for #%d (%s)",
1189 player_number(pplayer), player_name(pplayer));
1190 if (!pplayer->ai_controlled) {
1191 building_advisor(pplayer);
1192 }
1193 } phase_players_iterate_end;
1194
1195 phase_players_iterate(pplayer) {
1196 send_player_cities(pplayer);
1197 } phase_players_iterate_end;
1198
1199 flush_packets(); /* to curb major city spam */
1200 conn_list_do_unbuffer(game.est_connections);
1201
1202 alive_phase_players_iterate(pplayer) {
1203 update_revolution(pplayer);
1204 } alive_phase_players_iterate_end;
1205
1206 if (is_new_phase) {
1207 /* Try to avoid hiding events under a diplomacy dialog */
1208 phase_players_iterate(pplayer) {
1209 if (pplayer->ai_controlled) {
1210 CALL_PLR_AI_FUNC(diplomacy_actions, pplayer, pplayer);
1211 }
1212 } phase_players_iterate_end;
1213
1214 log_debug("Aistartturn");
1215 ai_start_phase();
1216 } else {
1217 phase_players_iterate(pplayer) {
1218 if (pplayer->ai_controlled) {
1219 CALL_PLR_AI_FUNC(restart_phase, pplayer, pplayer);
1220 }
1221 } phase_players_iterate_end;
1222 }
1223
1224 sanity_check();
1225
1226 game.tinfo.last_turn_change_time = (float)game.server.turn_change_time;
1227 game.tinfo.seconds_to_phasedone = (double)current_turn_timeout();
1228 game.server.phase_timer = timer_renew(game.server.phase_timer,
1229 TIMER_USER, TIMER_ACTIVE);
1230 timer_start(game.server.phase_timer);
1231 send_game_info(NULL);
1232
1233 if (game.server.num_phases == 1) {
1234 /* All players in the same phase.
1235 * This means that AI has been handled above, and server
1236 * will be responsive again */
1237 lsend_packet_begin_turn(game.est_connections);
1238 }
1239 }
1240
1241 /**************************************************************************
1242 End a phase of movement. This handles all end-of-phase actions
1243 for one or more players.
1244 **************************************************************************/
end_phase(void)1245 static void end_phase(void)
1246 {
1247 log_debug("Endphase");
1248
1249 /*
1250 * This empties the client Messages window; put this before
1251 * everything else below, since otherwise any messages from the
1252 * following parts get wiped out before the user gets a chance to
1253 * see them. --dwp
1254 */
1255 phase_players_iterate(pplayer) {
1256 /* Unlike the start_phase packet we only send this one to the active
1257 * player. */
1258 lsend_packet_end_phase(pplayer->connections);
1259 } phase_players_iterate_end;
1260
1261 /* Enact any policy changes.
1262 * Do this first so that following end-phase activities take the
1263 * change into account. */
1264 phase_players_iterate(pplayer) {
1265 multipliers_iterate(pmul) {
1266 pplayer->multipliers[multiplier_index(pmul)] =
1267 pplayer->multipliers_target[multiplier_index(pmul)];
1268 } multipliers_iterate_end;
1269 } phase_players_iterate_end;
1270
1271 phase_players_iterate(pplayer) {
1272 struct research *presearch = research_get(pplayer);
1273
1274 if (A_UNSET == presearch->researching) {
1275 Tech_type_id next_tech = research_goal_step(presearch,
1276 presearch->tech_goal);
1277
1278 if (A_UNSET != next_tech) {
1279 choose_tech(presearch, next_tech);
1280 } else {
1281 choose_random_tech(presearch);
1282 }
1283 /* Add the researched bulbs to the pool; do *NOT* check for finished
1284 * research */
1285 update_bulbs(pplayer, 0, FALSE);
1286 }
1287 } phase_players_iterate_end;
1288
1289 /* Freeze sending of cities. */
1290 send_city_suppression(TRUE);
1291
1292 /* AI end of turn activities */
1293 players_iterate(pplayer) {
1294 unit_list_iterate(pplayer->units, punit) {
1295 CALL_PLR_AI_FUNC(unit_turn_end, pplayer, punit);
1296 } unit_list_iterate_end;
1297 } players_iterate_end;
1298 phase_players_iterate(pplayer) {
1299 auto_settlers_player(pplayer);
1300 if (pplayer->ai_controlled) {
1301 CALL_PLR_AI_FUNC(last_activities, pplayer, pplayer);
1302 }
1303 } phase_players_iterate_end;
1304
1305 /* Refresh cities */
1306 phase_players_iterate(pplayer) {
1307 research_get(pplayer)->got_tech = FALSE;
1308 } phase_players_iterate_end;
1309
1310 alive_phase_players_iterate(pplayer) {
1311 do_tech_parasite_effect(pplayer);
1312 player_restore_units(pplayer);
1313
1314 /* If player finished spaceship parts last turn already, and didn't place them
1315 * during this entire turn, autoplace them. */
1316 if (adv_spaceship_autoplace(pplayer, &pplayer->spaceship)) {
1317 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
1318 _("Automatically placed spaceship parts that were still not placed."));
1319 }
1320
1321 update_city_activities(pplayer);
1322 city_thaw_workers_queue();
1323 pplayer->history += nation_history_gain(pplayer);
1324 research_get(pplayer)->researching_saved = A_UNKNOWN;
1325 /* reduce the number of bulbs by the amount needed for tech upkeep and
1326 * check for finished research */
1327 update_bulbs(pplayer, -player_tech_upkeep(pplayer), TRUE);
1328 flush_packets();
1329 } alive_phase_players_iterate_end;
1330
1331 /* Some player/global effect may have changed cities' vision range */
1332 phase_players_iterate(pplayer) {
1333 refresh_player_cities_vision(pplayer);
1334 } phase_players_iterate_end;
1335
1336 kill_dying_players();
1337
1338 /* Unfreeze sending of cities. */
1339 send_city_suppression(FALSE);
1340
1341 phase_players_iterate(pplayer) {
1342 send_player_cities(pplayer);
1343 } phase_players_iterate_end;
1344 flush_packets(); /* to curb major city spam */
1345
1346 do_reveal_effects();
1347 do_have_embassies_effect();
1348
1349 phase_players_iterate(pplayer) {
1350 CALL_PLR_AI_FUNC(phase_finished, pplayer, pplayer);
1351 /* This has to be after all access to advisor data. */
1352 /* We used to run this for ai players only, but data phase
1353 is initialized for human players also. */
1354 adv_data_phase_done(pplayer);
1355 } phase_players_iterate_end;
1356 }
1357
1358 /**************************************************************************
1359 Handle the end of each turn.
1360 **************************************************************************/
end_turn(void)1361 static void end_turn(void)
1362 {
1363 int food = 0, shields = 0, trade = 0, settlers = 0;
1364
1365 log_debug("Endturn");
1366
1367 /* Hack: because observer players never get an end-phase packet we send
1368 * one here. */
1369 conn_list_iterate(game.est_connections, pconn) {
1370 if (NULL == pconn->playing) {
1371 send_packet_end_phase(pconn);
1372 }
1373 } conn_list_iterate_end;
1374
1375 lsend_packet_end_turn(game.est_connections);
1376
1377 map_calculate_borders();
1378
1379 /* Output some AI measurement information */
1380 players_iterate(pplayer) {
1381 if (!pplayer->ai_controlled || is_barbarian(pplayer)) {
1382 continue;
1383 }
1384 unit_list_iterate(pplayer->units, punit) {
1385 if (unit_is_cityfounder(punit)) {
1386 settlers++;
1387 }
1388 } unit_list_iterate_end;
1389 city_list_iterate(pplayer->cities, pcity) {
1390 shields += pcity->prod[O_SHIELD];
1391 food += pcity->prod[O_FOOD];
1392 trade += pcity->prod[O_TRADE];
1393 } city_list_iterate_end;
1394 log_debug("%s T%d cities:%d pop:%d food:%d prod:%d "
1395 "trade:%d settlers:%d units:%d", player_name(pplayer),
1396 game.info.turn, city_list_size(pplayer->cities),
1397 total_player_citizens(pplayer), food, shields, trade,
1398 settlers, unit_list_size(pplayer->units));
1399 } players_iterate_end;
1400
1401 log_debug("Season of native unrests");
1402 summon_barbarians(); /* wild guess really, no idea where to put it, but
1403 * I want to give them chance to move their units */
1404
1405 if (game.server.migration) {
1406 log_debug("Season of migrations");
1407 if (check_city_migrations()) {
1408 /* Make sure everyone has updated information about BOTH ends of the
1409 * migration movements. */
1410 players_iterate(plr) {
1411 city_list_iterate(plr->cities, pcity) {
1412 send_city_info(NULL, pcity);
1413 } city_list_iterate_end;
1414 } players_iterate_end;
1415 }
1416 }
1417
1418 check_disasters();
1419
1420 /* Check for new achievements during the turn.
1421 * This is not within phase, as multiple players may
1422 * achieve at the same turn and everyone deserves equal opportunity
1423 * to win. */
1424 achievements_iterate(ach) {
1425 struct player_list *achievers = player_list_new();
1426 struct player *first = achievement_plr(ach, achievers);
1427 struct packet_achievement_info pack;
1428
1429 pack.id = achievement_index(ach);
1430 pack.gained = TRUE;
1431
1432 if (first != NULL) {
1433 notify_player(first, NULL, E_ACHIEVEMENT, ftc_server,
1434 "%s", achievement_first_msg(ach));
1435
1436 pack.first = TRUE;
1437
1438 lsend_packet_achievement_info(first->connections, &pack);
1439
1440 script_server_signal_emit("achievement_gained", 3,
1441 API_TYPE_ACHIEVEMENT, ach,
1442 API_TYPE_PLAYER, first,
1443 API_TYPE_BOOL, TRUE);
1444
1445 }
1446
1447 pack.first = FALSE;
1448
1449 if (!ach->unique) {
1450 player_list_iterate(achievers, pplayer) {
1451 /* Message already sent to first one */
1452 if (pplayer != first) {
1453 notify_player(pplayer, NULL, E_ACHIEVEMENT, ftc_server,
1454 "%s", achievement_later_msg(ach));
1455
1456 lsend_packet_achievement_info(pplayer->connections, &pack);
1457
1458 script_server_signal_emit("achievement_gained", 3,
1459 API_TYPE_ACHIEVEMENT, ach,
1460 API_TYPE_PLAYER, pplayer,
1461 API_TYPE_BOOL, FALSE);
1462 }
1463 } player_list_iterate_end;
1464 }
1465
1466 player_list_destroy(achievers);
1467 } achievements_iterate_end;
1468
1469 if (game.info.global_warming) {
1470 update_environmental_upset(EUT_GLOBAL_WARMING, &game.info.heating,
1471 &game.info.globalwarming,
1472 &game.info.warminglevel, global_warming);
1473 }
1474
1475 if (game.info.nuclear_winter) {
1476 update_environmental_upset(EUT_NUCLEAR_WINTER, &game.info.cooling,
1477 &game.info.nuclearwinter,
1478 &game.info.coolinglevel, nuclear_winter);
1479 }
1480
1481 update_diplomatics();
1482 make_history_report();
1483 settings_turn();
1484 stdinhand_turn();
1485 voting_turn();
1486 send_city_turn_notifications(NULL);
1487
1488 log_debug("Gamenextyear");
1489 game_advance_year();
1490 players_iterate_alive(pplayer) {
1491 pplayer->turns_alive++;
1492 } players_iterate_alive_end;
1493
1494 log_debug("Updatetimeout");
1495 update_timeout();
1496
1497 log_debug("Sendgameinfo");
1498 send_game_info(NULL);
1499
1500 log_debug("Sendplayerinfo");
1501 send_player_all_c(NULL, NULL);
1502
1503 log_debug("Sendresearchinfo");
1504 researches_iterate(presearch) {
1505 send_research_info(presearch, NULL);
1506 } researches_iterate_end;
1507
1508 log_debug("Sendyeartoclients");
1509 send_year_to_clients();
1510 }
1511
1512 /**************************************************************************
1513 Unconditionally save the game, with specified filename.
1514 Always prints a message: either save ok, or failed.
1515 **************************************************************************/
save_game(const char * orig_filename,const char * save_reason,bool scenario)1516 void save_game(const char *orig_filename, const char *save_reason,
1517 bool scenario)
1518 {
1519 char filepath[600];
1520 char *dot, *filename;
1521 struct section_file *file;
1522 struct timer *timer_cpu, *timer_user;
1523
1524 if (!orig_filename) {
1525 filepath[0] = '\0';
1526 filename = filepath;
1527 } else {
1528 sz_strlcpy(filepath, orig_filename);
1529 if ((filename = strrchr(filepath, '/'))) {
1530 filename++;
1531 } else {
1532 filename = filepath;
1533 }
1534
1535 /* Ignores the dot at the start of the filename. */
1536 for (dot = filename; '.' == *dot; dot++) {
1537 /* Nothing. */
1538 }
1539 if ('\0' == *dot) {
1540 /* Only dots in this file name, consider it as empty. */
1541 filename[0] = '\0';
1542 } else {
1543 char *end_dot;
1544 char *strip_extensions[] = { ".sav", ".gz", ".bz2", ".xz", NULL };
1545 bool stripped = TRUE;
1546
1547 while ((end_dot = strrchr(dot, '.')) && stripped) {
1548 int i;
1549 stripped = FALSE;
1550
1551 for (i = 0; strip_extensions[i] != NULL && !stripped; i++) {
1552 if (!strcmp(end_dot, strip_extensions[i])) {
1553 *end_dot = '\0';
1554 stripped = TRUE;
1555 }
1556 }
1557 }
1558 }
1559 }
1560
1561 /* If orig_filename is NULL or empty, use a generated default name. */
1562 if (filename[0] == '\0'){
1563 /* manual save */
1564 generate_save_name(game.server.save_name, filename,
1565 sizeof(filepath) + filepath - filename, "manual");
1566 }
1567
1568 timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE);
1569 timer_start(timer_cpu);
1570 timer_user = timer_new(TIMER_USER, TIMER_ACTIVE);
1571 timer_start(timer_user);
1572
1573 /* Allowing duplicates shouldn't be allowed. However, it takes very too
1574 * long time for huge game saving... */
1575 file = secfile_new(TRUE);
1576 savegame2_save(file, save_reason, scenario);
1577
1578 /* Append ".sav" to filename. */
1579 sz_strlcat(filepath, ".sav");
1580
1581 if (game.server.save_compress_level > 0) {
1582 switch (game.server.save_compress_type) {
1583 #ifdef FREECIV_HAVE_LIBZ
1584 case FZ_ZLIB:
1585 /* Append ".gz" to filename. */
1586 sz_strlcat(filepath, ".gz");
1587 break;
1588 #endif
1589 #ifdef FREECIV_HAVE_LIBBZ2
1590 case FZ_BZIP2:
1591 /* Append ".bz2" to filename. */
1592 sz_strlcat(filepath, ".bz2");
1593 break;
1594 #endif
1595 #ifdef FREECIV_HAVE_LIBLZMA
1596 case FZ_XZ:
1597 /* Append ".xz" to filename. */
1598 sz_strlcat(filepath, ".xz");
1599 break;
1600 #endif
1601 case FZ_PLAIN:
1602 break;
1603 default:
1604 log_error(_("Unsupported compression type %d."),
1605 game.server.save_compress_type);
1606 notify_conn(NULL, NULL, E_SETTING, ftc_warning,
1607 _("Unsupported compression type %d."),
1608 game.server.save_compress_type);
1609 break;
1610 }
1611 }
1612
1613 if (!path_is_absolute(filepath)) {
1614 char tmpname[600];
1615
1616 if (!scenario) {
1617 /* Ensure the saves directory exists. */
1618 make_dir(srvarg.saves_pathname);
1619
1620 sz_strlcpy(tmpname, srvarg.saves_pathname);
1621 } else {
1622 /* Make sure scenario directory exist */
1623 make_dir(srvarg.scenarios_pathname);
1624
1625 sz_strlcpy(tmpname, srvarg.scenarios_pathname);
1626 }
1627
1628 if (tmpname[0] != '\0') {
1629 sz_strlcat(tmpname, "/");
1630 }
1631 sz_strlcat(tmpname, filepath);
1632 sz_strlcpy(filepath, tmpname);
1633 }
1634
1635 if (!secfile_save(file, filepath, game.server.save_compress_level,
1636 game.server.save_compress_type)) {
1637 con_write(C_FAIL, _("Failed saving game as %s"), filepath);
1638 log_error("Game saving failed: %s", secfile_error());
1639 notify_conn(NULL, NULL, E_LOG_ERROR, ftc_warning, _("Failed saving game."));
1640 } else {
1641 con_write(C_OK, _("Game saved as %s"), filepath);
1642 }
1643
1644 secfile_destroy(file);
1645
1646 #ifdef LOG_TIMERS
1647 log_verbose("Save time: %g seconds (%g apparent)",
1648 timer_read_seconds(timer_cpu), timer_read_seconds(timer_user));
1649 #endif
1650
1651 timer_destroy(timer_cpu);
1652 timer_destroy(timer_user);
1653 }
1654
1655 /**************************************************************************
1656 Save game with autosave filename
1657 **************************************************************************/
save_game_auto(const char * save_reason,enum autosave_type type)1658 void save_game_auto(const char *save_reason, enum autosave_type type)
1659 {
1660 char filename[512];
1661 const char *reason_filename = NULL;
1662
1663 if (!(game.server.autosaves & (1 << type))) {
1664 return;
1665 }
1666
1667 switch (type) {
1668 case AS_TURN:
1669 reason_filename = NULL;
1670 break;
1671 case AS_GAME_OVER:
1672 reason_filename = "final";
1673 break;
1674 case AS_QUITIDLE:
1675 reason_filename = "quitidle";
1676 break;
1677 case AS_INTERRUPT:
1678 reason_filename = "interrupted";
1679 break;
1680 case AS_TIMER:
1681 reason_filename = "timer";
1682 break;
1683 }
1684
1685 fc_assert(256 > strlen(game.server.save_name));
1686
1687 if (type != AS_TIMER) {
1688 generate_save_name(game.server.save_name, filename, sizeof(filename),
1689 reason_filename);
1690 } else {
1691 fc_snprintf(filename, sizeof(filename), "%s-timer", game.server.save_name);
1692 }
1693 save_game(filename, save_reason, FALSE);
1694 }
1695
1696 /**************************************************************************
1697 Start actual game. Everything has been set up already.
1698 **************************************************************************/
start_game(void)1699 void start_game(void)
1700 {
1701 if (S_S_INITIAL != server_state()) {
1702 con_puts(C_SYNTAX, _("The game is already running."));
1703 return;
1704 }
1705
1706 /* Remove ALLOW_CTRL from whoever has it (gotten from 'first'). */
1707 conn_list_iterate(game.est_connections, pconn) {
1708 if (pconn->access_level == ALLOW_CTRL) {
1709 notify_conn(NULL, NULL, E_SETTING, ftc_server,
1710 _("%s lost control cmdlevel on "
1711 "game start. Use voting from now on."),
1712 pconn->username);
1713 conn_set_access(pconn, ALLOW_BASIC, FALSE);
1714 }
1715 } conn_list_iterate_end;
1716 set_running_game_access_level();
1717
1718 con_puts(C_OK, _("Starting game."));
1719
1720 /* Prevent problems with commands that only make sense in pregame. */
1721 clear_all_votes();
1722
1723 /* This value defines if the player data should be saved for a scenario. It
1724 * is only FALSE if the editor was used to set it to this value. For
1725 * such scenarios it has to be resetted at game start so that player data
1726 * is saved. */
1727 game.scenario.players = TRUE;
1728
1729 force_end_of_sniff = TRUE;
1730 /* There's no stateful packet set to client until srv_ready(). */
1731 }
1732
1733 /**************************************************************************
1734 Quit the server and exit.
1735 **************************************************************************/
server_quit(void)1736 void server_quit(void)
1737 {
1738 if (server_state() == S_S_RUNNING) {
1739 /* Quitting mid-game. */
1740
1741 phase_players_iterate(pplayer) {
1742 CALL_PLR_AI_FUNC(phase_finished, pplayer, pplayer);
1743 /* This has to be after all access to advisor data. */
1744 /* We used to run this for ai players only, but data phase
1745 is initialized for human players also. */
1746 adv_data_phase_done(pplayer);
1747 } phase_players_iterate_end;
1748 }
1749
1750 if (game.server.save_timer != NULL) {
1751 timer_destroy(game.server.save_timer);
1752 game.server.save_timer = NULL;
1753 }
1754 if (between_turns != NULL) {
1755 timer_destroy(between_turns);
1756 between_turns = NULL;
1757 }
1758 if (eot_timer != NULL) {
1759 timer_destroy(eot_timer);
1760 }
1761 set_server_state(S_S_OVER);
1762 mapimg_free();
1763 server_game_free();
1764 diplhand_free();
1765 voting_free();
1766 adv_settlers_free();
1767 ai_timer_free();
1768 if (game.server.phase_timer != NULL) {
1769 timer_destroy(game.server.phase_timer);
1770 game.server.phase_timer = NULL;
1771 }
1772 if (game.server.save_timer != NULL) {
1773 timer_destroy(game.server.save_timer);
1774 game.server.save_timer = NULL;
1775 }
1776
1777 #ifdef HAVE_FCDB
1778 if (srvarg.fcdb_enabled) {
1779 /* If freeciv database has been initialized */
1780 fcdb_free();
1781 }
1782 #endif /* HAVE_FCDB */
1783
1784 settings_free();
1785 stdinhand_free();
1786 edithand_free();
1787 voting_free();
1788 generator_free();
1789 close_connections_and_socket();
1790 rulesets_deinit();
1791 timing_log_free();
1792 registry_module_close();
1793 fc_destroy_mutex(&game.server.mutexes.city_list);
1794 free_libfreeciv();
1795 free_nls();
1796 con_log_close();
1797 cmdline_option_values_free();
1798 exit(EXIT_SUCCESS);
1799 }
1800
1801 /**************************************************************************
1802 Handle request asking report to be sent to client.
1803 **************************************************************************/
handle_report_req(struct connection * pconn,enum report_type type)1804 void handle_report_req(struct connection *pconn, enum report_type type)
1805 {
1806 struct conn_list *dest = pconn->self;
1807
1808 if (S_S_RUNNING != server_state() && S_S_OVER != server_state()) {
1809 log_error("Got a report request %d before game start", type);
1810 return;
1811 }
1812
1813 if (NULL == pconn->playing && !pconn->observer) {
1814 log_error("Got a report request %d from detached connection", type);
1815 return;
1816 }
1817
1818 switch(type) {
1819 case REPORT_WONDERS_OF_THE_WORLD:
1820 report_wonders_of_the_world(dest);
1821 return;
1822 case REPORT_TOP_5_CITIES:
1823 report_top_five_cities(dest);
1824 return;
1825 case REPORT_DEMOGRAPHIC:
1826 report_demographics(pconn);
1827 return;
1828 case REPORT_ACHIEVEMENTS:
1829 report_achievements(pconn);
1830 return;
1831 }
1832
1833 notify_conn(dest, NULL, E_BAD_COMMAND, ftc_server,
1834 _("request for unknown report (type %d)"), type);
1835 }
1836
1837 /**************************************************************************
1838 Mark identity number free.
1839 **************************************************************************/
identity_number_release(int id)1840 void identity_number_release(int id)
1841 {
1842 BV_CLR(identity_numbers_used, id);
1843 }
1844
1845 /**************************************************************************
1846 Mark identity number allocated.
1847 **************************************************************************/
identity_number_reserve(int id)1848 void identity_number_reserve(int id)
1849 {
1850 BV_SET(identity_numbers_used, id);
1851 }
1852
1853 /**************************************************************************
1854 Check whether identity number is currently allocated.
1855 **************************************************************************/
identity_number_is_used(int id)1856 static bool identity_number_is_used(int id)
1857 {
1858 return BV_ISSET(identity_numbers_used, id);
1859 }
1860
1861 /**************************************************************************
1862 Increment identity_number and return result.
1863 **************************************************************************/
increment_identity_number(void)1864 static int increment_identity_number(void)
1865 {
1866 server.identity_number = (server.identity_number + 1) % IDENTITY_NUMBER_SIZE;
1867 return server.identity_number;
1868 }
1869
1870 /**************************************************************************
1871 Identity ids wrap at IDENTITY_NUMBER_SIZE, skipping IDENTITY_NUMBER_ZERO
1872 Setup in server_game_init()
1873 **************************************************************************/
identity_number(void)1874 int identity_number(void)
1875 {
1876 int retries = 0;
1877
1878 while (identity_number_is_used(increment_identity_number())) {
1879 /* try again */
1880 if (++retries >= IDENTITY_NUMBER_SIZE) {
1881 /* Always fails. */
1882 fc_assert_exit_msg(IDENTITY_NUMBER_SIZE > retries,
1883 "Exhausted city and unit numbers!");
1884 }
1885 }
1886 identity_number_reserve(server.identity_number);
1887 return server.identity_number;
1888 }
1889
1890 /**************************************************************************
1891 Returns TRUE if the packet type is an edit packet sent by the client.
1892
1893 NB: The first and last client edit packets here must match those
1894 defined in common/packets.def.
1895 **************************************************************************/
is_client_edit_packet(int type)1896 static bool is_client_edit_packet(int type)
1897 {
1898 return PACKET_EDIT_MODE <= type && type <= PACKET_EDIT_GAME;
1899 }
1900
1901 /**************************************************************************
1902 Returns FALSE if connection should be closed (because the clients was
1903 rejected). Returns TRUE else.
1904 **************************************************************************/
server_packet_input(struct connection * pconn,void * packet,int type)1905 bool server_packet_input(struct connection *pconn, void *packet, int type)
1906 {
1907 struct player *pplayer;
1908
1909 /* a NULL packet can be returned from receive_packet_goto_route() */
1910 if (!packet) {
1911 return TRUE;
1912 }
1913
1914 /*
1915 * Old pre-delta clients (before 2003-11-28) send a
1916 * PACKET_LOGIN_REQUEST (type 0) to the server. We catch this and
1917 * reply with an old reject packet. Since there is no struct for
1918 * this old packet anymore we build it by hand.
1919 */
1920 if (type == 0) {
1921 unsigned char buffer[4096];
1922 struct data_out dout;
1923
1924 log_normal(_("Warning: rejecting old client %s"),
1925 conn_description(pconn));
1926
1927 dio_output_init(&dout, buffer, sizeof(buffer));
1928 DIO_PUT(uint16, &dout, "msg", 0);
1929
1930 /* 1 == PACKET_LOGIN_REPLY in the old client */
1931 DIO_PUT(uint8, &dout, "msg", 1);
1932
1933 DIO_PUT(bool32, &dout, "msg", FALSE);
1934 DIO_PUT(string, &dout, "msg",
1935 _("Your client is too old. To use this server, "
1936 "please upgrade your client to a "
1937 "Freeciv 2.2 or later."));
1938 DIO_PUT(string, &dout, "msg", "");
1939
1940 {
1941 size_t size = dio_output_used(&dout);
1942 dio_output_rewind(&dout);
1943 DIO_PUT(uint16, &dout, "size", size);
1944
1945 /*
1946 * Use send_connection_data instead of send_packet_data to avoid
1947 * compression.
1948 */
1949 connection_send_data(pconn, buffer, size);
1950 }
1951
1952 return FALSE;
1953 }
1954
1955 if (type == PACKET_SERVER_JOIN_REQ) {
1956 return handle_login_request(pconn,
1957 (struct packet_server_join_req *) packet);
1958 }
1959
1960 /* May be received on a non-established connection. */
1961 if (type == PACKET_AUTHENTICATION_REPLY) {
1962 return auth_handle_reply(pconn,
1963 ((struct packet_authentication_reply *)
1964 packet)->password);
1965 }
1966
1967 if (type == PACKET_CONN_PONG) {
1968 handle_conn_pong(pconn);
1969 return TRUE;
1970 }
1971
1972 if (!pconn->established) {
1973 log_error("Received game packet %s(%d) from unaccepted connection %s.",
1974 packet_name(type), type, conn_description(pconn));
1975 return TRUE;
1976 }
1977
1978 /* valid packets from established connections but non-players */
1979 if (type == PACKET_CHAT_MSG_REQ
1980 || type == PACKET_SINGLE_WANT_HACK_REQ
1981 || type == PACKET_NATION_SELECT_REQ
1982 || type == PACKET_REPORT_REQ
1983 || type == PACKET_CLIENT_INFO
1984 || type == PACKET_CONN_PONG
1985 || type == PACKET_CLIENT_HEARTBEAT
1986 || type == PACKET_SAVE_SCENARIO
1987 || is_client_edit_packet(type)) {
1988
1989 /* Except for PACKET_EDIT_MODE (used to set edit mode), check
1990 * that the client is allowed to send the given edit packet. */
1991 if (is_client_edit_packet(type) && type != PACKET_EDIT_MODE
1992 && !can_conn_edit(pconn)) {
1993 notify_conn(pconn->self, NULL, E_BAD_COMMAND, ftc_editor,
1994 _("You are not allowed to edit."));
1995 return TRUE;
1996 }
1997
1998 if (!server_handle_packet(type, packet, NULL, pconn)) {
1999 log_error("Received unknown packet %d from %s.",
2000 type, conn_description(pconn));
2001 }
2002 return TRUE;
2003 }
2004
2005 pplayer = pconn->playing;
2006
2007 if (NULL == pplayer || pconn->observer) {
2008 if (type == PACKET_PLAYER_READY && pconn->observer) {
2009 handle_observer_ready(pconn);
2010 return TRUE;
2011 }
2012 /* don't support these yet */
2013 log_error("Received packet %s(%d) from non-player connection %s.",
2014 packet_name(type), type, conn_description(pconn));
2015 return TRUE;
2016 }
2017
2018 if (S_S_RUNNING != server_state()
2019 && type != PACKET_NATION_SELECT_REQ
2020 && type != PACKET_PLAYER_READY
2021 && type != PACKET_VOTE_SUBMIT) {
2022 if (S_S_OVER == server_state()) {
2023 /* This can happen by accident, so we don't want to print
2024 * out lots of error messages. Ie, we use log_debug(). */
2025 log_debug("Got a packet of type %s(%d) in %s.",
2026 packet_name(type), type, server_states_name(S_S_OVER));
2027 } else {
2028 log_error("Got a packet of type %s(%d) outside %s.",
2029 packet_name(type), type, server_states_name(S_S_RUNNING));
2030 }
2031 return TRUE;
2032 }
2033
2034 pplayer->nturns_idle = 0;
2035
2036 if (!pplayer->is_alive && type != PACKET_REPORT_REQ) {
2037 log_error("Got a packet of type %s(%d) from a dead player.",
2038 packet_name(type), type);
2039 return TRUE;
2040 }
2041
2042 /* Make sure to set this back to NULL before leaving this function: */
2043 pplayer->current_conn = pconn;
2044
2045 if (!server_handle_packet(type, packet, pplayer, pconn)) {
2046 log_error("Received unknown packet %d from %s.",
2047 type, conn_description(pconn));
2048 }
2049
2050 if (S_S_RUNNING == server_state()
2051 && type != PACKET_PLAYER_READY) {
2052 /* handle_player_ready() calls start_game(), but the game isn't started
2053 * until the main loop is re-entered, so kill_dying_players would think
2054 * all players are dead. This should be solved by adding a new
2055 * game state (now S_S_GENERATING_WAITING). */
2056 kill_dying_players();
2057 }
2058
2059 pplayer->current_conn = NULL;
2060 return TRUE;
2061 }
2062
2063 /**************************************************************************
2064 Check if turn is really done. Returns nothing, but as a side effect sets
2065 force_end_of_sniff if no more input is expected this turn (i.e. turn done)
2066 **************************************************************************/
check_for_full_turn_done(void)2067 void check_for_full_turn_done(void)
2068 {
2069 bool connected = FALSE;
2070
2071 if (S_S_RUNNING != server_state()) {
2072 /* Not in a running state, no turn done. */
2073 return;
2074 }
2075
2076 /* fixedlength is only applicable if we have a timeout set */
2077 if (game.server.fixedlength && current_turn_timeout() != 0) {
2078 return;
2079 }
2080
2081 /* If there are no connected players, don't automatically advance. This is
2082 * a hack to prevent all-AI games from running rampant. Note that if
2083 * timeout is set to -1 this function call is skipped entirely and the
2084 * server will run rampant. */
2085 players_iterate_alive(pplayer) {
2086 if (pplayer->is_connected
2087 && (!pplayer->ai_controlled || pplayer->phase_done)) {
2088 connected = TRUE;
2089 break;
2090 }
2091 } players_iterate_alive_end;
2092
2093 if (!connected) {
2094 return;
2095 }
2096
2097 phase_players_iterate(pplayer) {
2098 if (!pplayer->phase_done && pplayer->is_alive) {
2099 if (pplayer->is_connected) {
2100 /* In all cases, we wait for any connected players. */
2101 return;
2102 }
2103 if (game.server.turnblock && !pplayer->ai_controlled) {
2104 /* If turnblock is enabled check for human players, connected
2105 * or not. */
2106 return;
2107 }
2108 if (pplayer->ai_controlled && !pplayer->ai_phase_done) {
2109 /* AI player has not finished */
2110 return;
2111 }
2112 }
2113 } phase_players_iterate_end;
2114
2115 force_end_of_sniff = TRUE;
2116 }
2117
2118 /****************************************************************************
2119 Update information about which nations have start positions on the map.
2120
2121 Call this on server start, or when loading a scenario.
2122 ****************************************************************************/
update_nations_with_startpos(void)2123 void update_nations_with_startpos(void)
2124 {
2125 if (!game_was_started() && 0 < map_startpos_count()) {
2126 /* Restrict nations to those for which start positions are defined. */
2127 nations_iterate(pnation) {
2128 fc_assert_action_msg(NULL == pnation->player,
2129 if (pnation->player->nation == pnation) {
2130 /* At least assignment is consistent. Leave nation assigned,
2131 * and make sure that nation is also marked pickable. */
2132 pnation->server.no_startpos = FALSE;
2133 continue;
2134 } else if (NULL != pnation->player->nation) {
2135 /* Not consistent. Just initialize the pointer and hope for the
2136 * best. */
2137 pnation->player->nation->player = NULL;
2138 pnation->player = NULL;
2139 } else {
2140 /* Not consistent. Just initialize the pointer and hope for the
2141 * best. */
2142 pnation->player = NULL;
2143 }, "Player assigned to nation before %s()!", __FUNCTION__);
2144
2145 if (nation_barbarian_type(pnation) != NOT_A_BARBARIAN) {
2146 /* Always allow land and sea barbarians regardless of start
2147 * positions. */
2148 pnation->server.no_startpos = FALSE;
2149 } else {
2150 /* Restrict the set of nations offered to players, based on
2151 * start positions.
2152 * If there are no start positions for a nation, remove it from the
2153 * available set. */
2154 pnation->server.no_startpos = TRUE;
2155 map_startpos_iterate(psp) {
2156 if (startpos_nation_allowed(psp, pnation)) {
2157 /* There is at least one start position that allows this nation,
2158 * so allow it to be picked.
2159 * (Depending on what nations players actually pick, it's not
2160 * guaranteed that the server can always find a match between
2161 * nations in this subset and start positions, in which case the
2162 * server may create mismatches.) */
2163 pnation->server.no_startpos = FALSE;
2164 break;
2165 }
2166 } map_startpos_iterate_end;
2167 }
2168 } nations_iterate_end;
2169 } else {
2170 /* Not restricting nations by start positions. */
2171 nations_iterate(pnation) {
2172 pnation->server.no_startpos = FALSE;
2173 } nations_iterate_end;
2174 }
2175 }
2176
2177 /**************************************************************************
2178 Handles a pick-nation packet from the client. These packets are
2179 handled by connection because ctrl users may edit anyone's nation in
2180 pregame, and editing is possible during a running game.
2181 **************************************************************************/
handle_nation_select_req(struct connection * pc,int player_no,Nation_type_id nation_no,bool is_male,const char * name,int style)2182 void handle_nation_select_req(struct connection *pc, int player_no,
2183 Nation_type_id nation_no, bool is_male,
2184 const char *name, int style)
2185 {
2186 struct nation_type *new_nation;
2187 struct player *pplayer = player_by_number(player_no);
2188
2189 if (!pplayer || !can_conn_edit_players_nation(pc, pplayer)) {
2190 return;
2191 }
2192
2193 new_nation = nation_by_number(nation_no);
2194
2195 if (new_nation != NO_NATION_SELECTED) {
2196 char message[1024];
2197
2198 /* check sanity of the packet sent by client */
2199 if (style < 0 || style >= game.control.num_styles) {
2200 return;
2201 }
2202
2203 if (!client_can_pick_nation(new_nation)) {
2204 notify_player(pplayer, NULL, E_NATION_SELECTED, ftc_server,
2205 _("%s nation is not available for user selection."),
2206 nation_adjective_translation(new_nation));
2207 return;
2208 }
2209 if (new_nation->player && new_nation->player != pplayer) {
2210 notify_player(pplayer, NULL, E_NATION_SELECTED, ftc_server,
2211 _("%s nation is already in use."),
2212 nation_adjective_translation(new_nation));
2213 return;
2214 }
2215
2216 if (!server_player_set_name_full(pc, pplayer, new_nation, name,
2217 message, sizeof(message))) {
2218 notify_player(pplayer, NULL, E_NATION_SELECTED,
2219 ftc_server, "%s", message);
2220 return;
2221 }
2222
2223 /* Should be caught by is_nation_pickable() */
2224 fc_assert_ret(nation_is_in_current_set(new_nation));
2225
2226 notify_conn(NULL, NULL, E_NATION_SELECTED, ftc_server,
2227 _("%s is the %s ruler %s."),
2228 pplayer->username,
2229 nation_adjective_translation(new_nation),
2230 player_name(pplayer));
2231
2232 pplayer->is_male = is_male;
2233 pplayer->style = style_by_number(style);
2234 } else if (name[0] == '\0') {
2235 char message[1024];
2236
2237 server_player_set_name_full(pc, pplayer, NULL, ANON_PLAYER_NAME,
2238 message, sizeof(message));
2239 }
2240
2241 (void) player_set_nation(pplayer, new_nation);
2242 send_player_info_c(pplayer, game.est_connections);
2243 }
2244
2245 /****************************************************************************
2246 Handle a player-ready packet from global observer.
2247 ****************************************************************************/
handle_observer_ready(struct connection * pconn)2248 static void handle_observer_ready(struct connection *pconn)
2249 {
2250 if (pconn->access_level == ALLOW_HACK) {
2251 players_iterate(plr) {
2252 if (!plr->ai_controlled) {
2253 return;
2254 }
2255 } players_iterate_end;
2256
2257 start_command(NULL, FALSE, TRUE);
2258 }
2259 }
2260
2261 /****************************************************************************
2262 Handle a player-ready packet.
2263 ****************************************************************************/
handle_player_ready(struct player * requestor,int player_no,bool is_ready)2264 void handle_player_ready(struct player *requestor,
2265 int player_no,
2266 bool is_ready)
2267 {
2268 struct player *pplayer = player_by_number(player_no);
2269
2270 if (NULL == pplayer || S_S_INITIAL != server_state()) {
2271 return;
2272 }
2273
2274 if (pplayer != requestor) {
2275 /* Currently you can only change your own readiness. */
2276 return;
2277 }
2278
2279 pplayer->is_ready = is_ready;
2280 send_player_info_c(pplayer, NULL);
2281
2282 /* Note this is called even if the player has pressed /start once
2283 * before. For instance, when a player leaves everyone remaining
2284 * might have pressed /start already but the start won't happen
2285 * until someone presses it again. Also you can press start more
2286 * than once to remind other people to start (which is a good thing
2287 * until somebody does it too much and it gets labeled as spam). */
2288 if (is_ready) {
2289 int num_ready = 0, num_unready = 0;
2290
2291 players_iterate(other_player) {
2292 if (other_player->is_connected) {
2293 if (other_player->is_ready) {
2294 num_ready++;
2295 } else {
2296 num_unready++;
2297 }
2298 }
2299 } players_iterate_end;
2300 if (num_unready > 0) {
2301 notify_conn(NULL, NULL, E_SETTING, ftc_server,
2302 _("Waiting to start game: %d out of %d players "
2303 "are ready to start."),
2304 num_ready, num_ready + num_unready);
2305 } else {
2306 /* Check minplayers etc. and then start */
2307 start_command(NULL, FALSE, TRUE);
2308 }
2309 }
2310 }
2311
2312 /****************************************************************************
2313 Fill or remove players to meet the given aifill.
2314 If return is non-NULL, points to a translated string explaining why
2315 the total number of players is less than 'amount'.
2316 ****************************************************************************/
aifill(int amount)2317 const char *aifill(int amount)
2318 {
2319 char *limitreason = NULL;
2320 int limit;
2321
2322 if (game_was_started()) {
2323 return NULL;
2324 }
2325
2326 limit = MIN(amount, game.server.max_players);
2327 if (limit < amount) {
2328 limitreason = _("requested more than 'maxplayers' setting");
2329 }
2330
2331 /* Limit to nations provided by ruleset */
2332 if (limit > server.playable_nations) {
2333 limit = server.playable_nations;
2334 if (nation_set_count() > 1) {
2335 limitreason = _("not enough playable nations in this nation set "
2336 "(see 'nationset' setting)");
2337 } else {
2338 limitreason = _("not enough playable nations");
2339 }
2340 }
2341
2342 if (limit < player_count()) {
2343 int removal = player_slot_count() - 1;
2344
2345 while (limit < player_count() && 0 <= removal) {
2346 struct player *pplayer = player_by_number(removal);
2347
2348 removal--;
2349 if (!pplayer) {
2350 continue;
2351 }
2352
2353 if (!pplayer->is_connected && !pplayer->was_created) {
2354 server_remove_player(pplayer);
2355 }
2356 }
2357
2358 /* 'limit' can be different from 'player_count()' at this point if
2359 * there are more human or created players than the 'limit'. */
2360 return limitreason;
2361 }
2362
2363 while (limit > player_count()) {
2364 char leader_name[MAX_LEN_NAME];
2365 int filled = 1;
2366 struct player *pplayer;
2367
2368 pplayer = server_create_player(-1, default_ai_type_name(),
2369 NULL, FALSE);
2370 /* !game_was_started() so no need to assign_player_colors() */
2371 if (!pplayer) {
2372 break;
2373 }
2374 server_player_init(pplayer, FALSE, TRUE);
2375
2376 player_set_nation(pplayer, NULL);
2377
2378 do {
2379 fc_snprintf(leader_name, sizeof(leader_name), "AI*%d", filled++);
2380 } while (player_by_name(leader_name));
2381 server_player_set_name(pplayer, leader_name);
2382 pplayer->random_name = TRUE;
2383 sz_strlcpy(pplayer->username, _(ANON_USER_NAME));
2384 pplayer->unassigned_user = TRUE;
2385
2386 pplayer->ai_common.skill_level = game.info.skill_level;
2387 pplayer->ai_controlled = TRUE;
2388 set_ai_level_directer(pplayer, game.info.skill_level);
2389
2390 CALL_PLR_AI_FUNC(gained_control, pplayer, pplayer);
2391
2392 log_normal(_("%s has been added as %s level AI-controlled player (%s)."),
2393 player_name(pplayer),
2394 ai_level_translated_name(pplayer->ai_common.skill_level),
2395 ai_name(pplayer->ai));
2396 notify_conn(NULL, NULL, E_SETTING, ftc_server,
2397 _("%s has been added as %s level AI-controlled player (%s)."),
2398 player_name(pplayer),
2399 ai_level_translated_name(pplayer->ai_common.skill_level),
2400 ai_name(pplayer->ai));
2401
2402 send_player_info_c(pplayer, NULL);
2403 }
2404
2405 return limitreason;
2406 }
2407
2408 /****************************************************************************
2409 Tool for generate_players().
2410 ****************************************************************************/
2411 #define SPECHASH_TAG startpos
2412 #define SPECHASH_IKEY_TYPE struct startpos *
2413 #define SPECHASH_INT_DATA_TYPE
2414 #include "spechash.h"
2415 #define startpos_hash_iterate(hash, psp, c) \
2416 TYPED_HASH_ITERATE(struct startpos *, intptr_t, hash, psp, c)
2417 #define startpos_hash_iterate_end HASH_ITERATE_END
2418
2419 /****************************************************************************
2420 Tool for generate_players().
2421 ****************************************************************************/
player_set_nation_full(struct player * pplayer,struct nation_type * pnation)2422 static void player_set_nation_full(struct player *pplayer,
2423 struct nation_type *pnation)
2424 {
2425 /* Don't change the name of a created player. */
2426 player_nation_defaults(pplayer, pnation, pplayer->random_name);
2427 }
2428
2429 /****************************************************************************
2430 Set nation for player with nation default values.
2431 ****************************************************************************/
player_nation_defaults(struct player * pplayer,struct nation_type * pnation,bool set_name)2432 void player_nation_defaults(struct player *pplayer, struct nation_type *pnation,
2433 bool set_name)
2434 {
2435 struct nation_leader *pleader;
2436
2437 fc_assert(NO_NATION_SELECTED != pnation);
2438 player_set_nation(pplayer, pnation);
2439 fc_assert(pnation == pplayer->nation);
2440
2441 pplayer->style = style_of_nation(pnation);
2442
2443 if (set_name) {
2444 server_player_set_name(pplayer, pick_random_player_name(pnation));
2445 }
2446
2447 if ((pleader = nation_leader_by_name(pnation, player_name(pplayer)))) {
2448 pplayer->is_male = nation_leader_is_male(pleader);
2449 } else {
2450 pplayer->is_male = (fc_rand(2) == 1);
2451 }
2452
2453 ai_traits_init(pplayer);
2454 }
2455
2456 /****************************************************************************
2457 Assign random nations to players at game start. This includes human
2458 players, AI players created with "set aifill <X>", and players created
2459 with "create <PlayerName>".
2460
2461 If a player's name matches one of the leader names for some nation, and
2462 that nation is available, choose that nation, and set the player sex
2463 appropriately. For example, when the Britons have not been chosen by
2464 anyone else, a player called Boudica whose nation has not been specified
2465 (for instance if they were created with "create Boudica") will become
2466 the Britons, and their sex will be female. Otherwise, the sex is chosen
2467 randomly, and the nation is chosen as below.
2468
2469 If this is a scenario and the scenario has specific start positions for
2470 some nations, try to pick those nations, favouring those with start
2471 positions which already-assigned players can't use. (Note that it's
2472 possible that we can't find enough nations with available start positions,
2473 depending on what nations players have already picked; in this case,
2474 it's OK to pick nations without start positions, as init_new_game() will
2475 fall back to mismatched start positions.)
2476
2477 Otherwise, pick available nations using pick_a_nation(), which tries to
2478 pick nations that look good with nations already in the game.
2479
2480 For 'aifill' players, the player name/sex is then reset to that of a
2481 random leader for the chosen nation.
2482 ****************************************************************************/
generate_players(void)2483 static void generate_players(void)
2484 {
2485 int nations_to_assign = 0;
2486
2487 /* Announce players who already have nations, and select nations based
2488 * on player names. */
2489 players_iterate(pplayer) {
2490 if (pplayer->nation != NO_NATION_SELECTED) {
2491 /* Traits are initialized here, and not already when nation gets picked,
2492 * as player may change his/her mind after picking one nation, and picks
2493 * another and we want to init traits only once, for the correct nation. */
2494 ai_traits_init(pplayer);
2495 announce_player(pplayer);
2496 continue;
2497 }
2498
2499 /* See if the player name matches a known leader name.
2500 * If more than one nation has this leader name, pick one at random.
2501 * No attempt is made to avoid clashes to maximise the number of
2502 * nations that can be assigned in this way. */
2503 {
2504 struct nation_list *candidates = nation_list_new();
2505 int n = 0;
2506
2507 allowed_nations_iterate(pnation) {
2508 if (is_nation_playable(pnation)
2509 && client_can_pick_nation(pnation)
2510 && NULL == pnation->player
2511 && (nation_leader_by_name(pnation, player_name(pplayer)))) {
2512 nation_list_append(candidates, pnation);
2513 n++;
2514 }
2515 } allowed_nations_iterate_end;
2516 if (n > 0) {
2517 player_set_nation_full(pplayer,
2518 nation_list_get(candidates, fc_rand(n)));
2519 }
2520 nation_list_destroy(candidates);
2521 }
2522 if (pplayer->nation != NO_NATION_SELECTED) {
2523 announce_player(pplayer);
2524 } else {
2525 nations_to_assign++;
2526 }
2527 } players_iterate_end;
2528
2529 if (0 < nations_to_assign && 0 < map_startpos_count()) {
2530 /* We're running a scenario game with specified start positions.
2531 * Prefer nations assigned to those positions (but we can fall back
2532 * to others, even if game.scenario.startpos_nations is set). */
2533 struct startpos_hash *hash = startpos_hash_new();
2534 struct nation_type *picked;
2535 int c, max = -1;
2536 int i, min;
2537
2538 /* Initialization. */
2539 map_startpos_iterate(psp) {
2540 if (startpos_allows_all(psp)) {
2541 continue;
2542 }
2543
2544 /* Count the already-assigned players whose nations can use this
2545 * start position. */
2546 c = 0;
2547 players_iterate(pplayer) {
2548 if (NO_NATION_SELECTED != pplayer->nation
2549 && startpos_nation_allowed(psp, pplayer->nation)) {
2550 c++;
2551 }
2552 } players_iterate_end;
2553
2554 startpos_hash_insert(hash, psp, c);
2555 if (c > max) {
2556 max = c;
2557 }
2558 } map_startpos_iterate_end;
2559
2560 /* Try to assign nations with start positions to the unassigned
2561 * players, preferring nations whose start positions aren't usable
2562 * by already-assigned players. */
2563 players_iterate(pplayer) {
2564 if (NO_NATION_SELECTED != pplayer->nation) {
2565 continue;
2566 }
2567
2568 picked = NO_NATION_SELECTED;
2569 min = max;
2570 i = 0;
2571
2572 allowed_nations_iterate(pnation) {
2573 if (!is_nation_playable(pnation)
2574 || NULL != pnation->player) {
2575 /* Not available. */
2576 continue;
2577 }
2578
2579 startpos_hash_iterate(hash, psp, val) {
2580 if (!startpos_nation_allowed(psp, pnation)) {
2581 continue;
2582 }
2583
2584 if (val < min) {
2585 /* Pick this nation, as fewer nations already in the game
2586 * can use this start position. */
2587 picked = pnation;
2588 min = val;
2589 i = 1;
2590 } else if (val == min && 0 == fc_rand(++i)) {
2591 /* More than one nation is equally desirable. Pick one at
2592 * random. */
2593 picked = pnation;
2594 }
2595 } startpos_hash_iterate_end;
2596 } allowed_nations_iterate_end;
2597
2598 if (NO_NATION_SELECTED != picked) {
2599 player_set_nation_full(pplayer, picked);
2600 nations_to_assign--;
2601 announce_player(pplayer);
2602 /* Update the counts for the newly assigned nation. */
2603 startpos_hash_iterate(hash, psp, val) {
2604 if (startpos_nation_allowed(psp, picked)) {
2605 startpos_hash_replace(hash, psp, val + 1);
2606 }
2607 } startpos_hash_iterate_end;
2608 } else {
2609 /* No need to continue; we failed to pick a nation this time,
2610 * so we're not going to succeed next time. Fall back to
2611 * standard nation selection. */
2612 break;
2613 }
2614 } players_iterate_end;
2615
2616 startpos_hash_destroy(hash);
2617 }
2618
2619 if (0 < nations_to_assign) {
2620 /* Pick random races. Try to select from the set permitted by
2621 * starting positions -- if we fell through here after failing to
2622 * match start positions, this will at least keep the picked
2623 * nations vaguely in keeping with the scenario.
2624 * However, even this may fail (if there are start positions that
2625 * can only be filled by nations outside the current nationset),
2626 * in which case we fall back to completely random nations. */
2627 bool needs_startpos = TRUE;
2628 players_iterate(pplayer) {
2629 if (NO_NATION_SELECTED == pplayer->nation) {
2630 struct nation_type *pnation = pick_a_nation(NULL, FALSE, needs_startpos,
2631 NOT_A_BARBARIAN);
2632 if (pnation == NO_NATION_SELECTED && needs_startpos) {
2633 needs_startpos = FALSE;
2634 pnation = pick_a_nation(NULL, FALSE, needs_startpos, NOT_A_BARBARIAN);
2635 }
2636 fc_assert(pnation != NO_NATION_SELECTED);
2637 player_set_nation_full(pplayer, pnation);
2638 nations_to_assign--;
2639 announce_player(pplayer);
2640 }
2641 } players_iterate_end;
2642 }
2643
2644 fc_assert(0 == nations_to_assign);
2645
2646 (void) send_server_info_to_metaserver(META_INFO);
2647 }
2648
2649 /****************************************************************************
2650 Returns a random ruler name picked from given nation's ruler names
2651 that is not already in use.
2652 May return NULL if no unique name is available.
2653 ****************************************************************************/
pick_random_player_name(const struct nation_type * pnation)2654 const char *pick_random_player_name(const struct nation_type *pnation)
2655 {
2656 const char *choice = NULL;
2657 struct nation_leader_list *candidates = nation_leader_list_new();
2658 int n;
2659
2660 nation_leader_list_iterate(nation_leaders(pnation), pleader) {
2661 const char *name = nation_leader_name(pleader);
2662
2663 if (NULL == player_by_name(name)
2664 && NULL == player_by_user(name)) {
2665 nation_leader_list_append(candidates, pleader);
2666 }
2667 } nation_leader_list_iterate_end;
2668
2669 n = nation_leader_list_size(candidates);
2670 if (n > 0) {
2671 choice = nation_leader_name(nation_leader_list_get(candidates,
2672 fc_rand(n)));
2673 }
2674 nation_leader_list_destroy(candidates);
2675
2676 return choice;
2677 }
2678
2679 /*************************************************************************
2680 Announce what nation player rules to everyone.
2681 *************************************************************************/
announce_player(struct player * pplayer)2682 static void announce_player(struct player *pplayer)
2683 {
2684 log_normal(_("%s rules the %s."),
2685 player_name(pplayer), nation_plural_for_player(pplayer));
2686
2687 notify_conn(game.est_connections, NULL, E_GAME_START,
2688 ftc_server, _("%s rules the %s."),
2689 player_name(pplayer), nation_plural_for_player(pplayer));
2690
2691 /* Let the clients knows the nation of the players as soon as possible.
2692 * When a player's nation is server assigned its client will think of it
2693 * as NULL until informed about the assigned nation. */
2694 send_player_info_c(pplayer, NULL);
2695 }
2696
2697 /**************************************************************************
2698 Play the game! Returns when S_S_RUNNING != server_state().
2699 **************************************************************************/
srv_running(void)2700 static void srv_running(void)
2701 {
2702 int save_counter = 0, i;
2703 bool is_new_turn = game.info.is_new_game;
2704 bool skip_mapimg = !game.info.is_new_game; /* Do not overwrite start-of-turn image */
2705 bool need_send_pending_events = !game.info.is_new_game;
2706
2707 /* We may as well reset is_new_game now. */
2708 game.info.is_new_game = FALSE;
2709
2710 log_verbose("srv_running() mostly redundant send_server_settings()");
2711 send_server_settings(NULL);
2712
2713 timer_start(eot_timer);
2714
2715 if (game.server.autosaves & (1 << AS_TIMER)) {
2716 game.server.save_timer = timer_renew(game.server.save_timer,
2717 TIMER_USER, TIMER_ACTIVE);
2718 timer_start(game.server.save_timer);
2719 }
2720
2721 /*
2722 * This will freeze the reports and agents at the client.
2723 *
2724 * Do this before the body so that the PACKET_THAW_CLIENT packet is
2725 * balanced.
2726 */
2727 lsend_packet_freeze_client(game.est_connections);
2728
2729 fc_assert(S_S_RUNNING == server_state());
2730 while (S_S_RUNNING == server_state()) {
2731 /* The beginning of a turn.
2732 *
2733 * We have to initialize data as well as do some actions. However when
2734 * loading a game we don't want to do these actions (like AI unit
2735 * movement and AI diplomacy). */
2736 begin_turn(is_new_turn);
2737
2738 if (game.server.num_phases != 1) {
2739 /* We allow everyone to begin adjusting cities and such
2740 * from the beginning of the turn.
2741 * With simultaneous movement we send begin_turn packet in
2742 * begin_phase() only after AI players have finished their actions. */
2743 lsend_packet_begin_turn(game.est_connections);
2744 }
2745
2746 for (; game.info.phase < game.server.num_phases; game.info.phase++) {
2747 log_debug("Starting phase %d/%d.", game.info.phase,
2748 game.server.num_phases);
2749 begin_phase(is_new_turn);
2750 if (need_send_pending_events) {
2751 /* When loading a savegame, we need to send loaded events, after
2752 * the clients switched to the game page (after the first
2753 * packet_start_phase is received). */
2754 conn_list_iterate(game.est_connections, pconn) {
2755 send_pending_events(pconn, TRUE);
2756 } conn_list_iterate_end;
2757 need_send_pending_events = FALSE;
2758 }
2759
2760 is_new_turn = TRUE;
2761
2762 force_end_of_sniff = FALSE;
2763
2764 /*
2765 * This will thaw the reports and agents at the client.
2766 */
2767 lsend_packet_thaw_client(game.est_connections);
2768
2769 #ifdef LOG_TIMERS
2770 /* Before sniff (human player activites), report time to now: */
2771 log_verbose("End/start-turn server/ai activities: %g seconds",
2772 timer_read_seconds(eot_timer));
2773 #endif
2774
2775 /* Do auto-saves just before starting server_sniff_all_input(), so that
2776 * autosave happens effectively "at the same time" as manual
2777 * saves, from the point of view of restarting and AI players.
2778 * Post-increment so we don't count the first loop. */
2779 if (game.info.phase == 0) {
2780 /* Create autosaves if requested. */
2781 if (save_counter >= game.server.save_nturns
2782 && game.server.save_nturns > 0) {
2783 save_counter = 0;
2784 save_game_auto("Autosave", AS_TURN);
2785 }
2786 save_counter++;
2787
2788 if (!skip_mapimg) {
2789 /* Save map image(s). */
2790 for (i = 0; i < mapimg_count(); i++) {
2791 struct mapdef *pmapdef = mapimg_isvalid(i);
2792 if (pmapdef != NULL) {
2793 mapimg_create(pmapdef, FALSE, game.server.save_name,
2794 srvarg.saves_pathname);
2795 } else {
2796 log_error("%s", mapimg_error());
2797 }
2798 }
2799 } else {
2800 skip_mapimg = FALSE;
2801 }
2802 }
2803
2804 log_debug("sniffingpackets");
2805 check_for_full_turn_done(); /* HACK: don't wait during AI phases */
2806
2807 if (between_turns != NULL) {
2808 game.server.turn_change_time = timer_read_seconds(between_turns);
2809 log_debug("Inresponsive between turns %g seconds", game.server.turn_change_time);
2810 }
2811
2812 while (server_sniff_all_input() == S_E_OTHERWISE) {
2813 /* nothing */
2814 }
2815
2816 between_turns = timer_renew(between_turns, TIMER_USER, TIMER_ACTIVE);
2817 timer_start(between_turns);
2818
2819 /* After sniff, re-zero the timer: (read-out above on next loop) */
2820 timer_clear(eot_timer);
2821 timer_start(eot_timer);
2822
2823 conn_list_do_buffer(game.est_connections);
2824
2825 sanity_check();
2826
2827 /*
2828 * This will freeze the reports and agents at the client.
2829 */
2830 lsend_packet_freeze_client(game.est_connections);
2831
2832 end_phase();
2833
2834 conn_list_do_unbuffer(game.est_connections);
2835
2836 if (S_S_OVER == server_state()) {
2837 break;
2838 }
2839 }
2840
2841 /* Make sure is_new_turn is reseted before next turn even if
2842 * we did zero rounds in the loop (i.e. if current phase from
2843 * the savegame was >= num phases). Without this begin_turn()
2844 * would not reset phase, so there would be infinite loop
2845 * where phase is too high for is_new_turn to get set. */
2846 is_new_turn = TRUE;
2847
2848 end_turn();
2849 log_debug("Sendinfotometaserver");
2850 (void) send_server_info_to_metaserver(META_REFRESH);
2851
2852 if (S_S_OVER != server_state() && check_for_game_over()) {
2853 set_server_state(S_S_OVER);
2854 if (game.info.turn > game.server.end_turn) {
2855 /* endturn was reached - rank users based on team scores */
2856 rank_users(TRUE);
2857 } else {
2858 /* game ended for victory conditions - rank users based on survival */
2859 rank_users(FALSE);
2860 }
2861 } else if (S_S_OVER == server_state()) {
2862 /* game terminated by /endgame command - calculate team scores */
2863 rank_users(TRUE);
2864 }
2865 }
2866
2867 /* This will thaw the reports and agents at the client. */
2868 lsend_packet_thaw_client(game.est_connections);
2869
2870 if (game.server.save_timer != NULL) {
2871 timer_destroy(game.server.save_timer);
2872 game.server.save_timer = NULL;
2873 }
2874 if (between_turns != NULL) {
2875 timer_destroy(between_turns);
2876 between_turns = NULL;
2877 }
2878 timer_clear(eot_timer);
2879 }
2880
2881 /**************************************************************************
2882 Server initialization.
2883 **************************************************************************/
srv_prepare(void)2884 static void srv_prepare(void)
2885 {
2886 #ifdef HAVE_FCDB
2887 if (!srvarg.auth_enabled) {
2888 con_write(C_COMMENT, _("This freeciv-server program has player "
2889 "authentication support, but it's currently not "
2890 "in use."));
2891 }
2892 #endif /* HAVE_FCDB */
2893
2894 /* make sure it's initialized */
2895 if (!has_been_srv_init) {
2896 srv_init();
2897 }
2898
2899 fc_init_network();
2900
2901 /* must be before con_log_init() */
2902 init_connections();
2903 con_log_init(srvarg.log_filename, srvarg.loglevel,
2904 srvarg.fatal_assertions);
2905 /* logging available after this point */
2906
2907 server_open_socket();
2908
2909 #if IS_BETA_VERSION
2910 con_puts(C_COMMENT, "");
2911 con_puts(C_COMMENT, beta_message());
2912 con_puts(C_COMMENT, "");
2913 #endif
2914
2915 con_flush();
2916
2917 settings_init(TRUE);
2918 stdinhand_init();
2919 edithand_init();
2920 voting_init();
2921 diplhand_init();
2922 voting_init();
2923 ai_timer_init();
2924
2925 server_game_init();
2926 mapimg_init(mapimg_server_tile_known, mapimg_server_tile_terrain,
2927 mapimg_server_tile_owner, mapimg_server_tile_city,
2928 mapimg_server_tile_unit, mapimg_server_plrcolor_count,
2929 mapimg_server_plrcolor_get);
2930
2931 #ifdef HAVE_FCDB
2932 if (srvarg.fcdb_enabled) {
2933 bool success;
2934
2935 success = fcdb_init(srvarg.fcdb_conf);
2936 free(srvarg.fcdb_conf); /* Never needed again */
2937 srvarg.fcdb_conf = NULL;
2938 if (!success) {
2939 exit(EXIT_FAILURE);
2940 }
2941 }
2942 #endif /* HAVE_FCDB */
2943
2944 /* load a saved game */
2945 if ('\0' == srvarg.load_filename[0]
2946 || !load_command(NULL, srvarg.load_filename, FALSE, TRUE)) {
2947 /* Rulesets are loaded on game initialization, but may be changed later
2948 * if /load or /rulesetdir is done. */
2949 load_rulesets(NULL, TRUE, FALSE);
2950 }
2951
2952 maybe_automatic_meta_message(default_meta_message_string());
2953
2954 if (!(srvarg.metaserver_no_send)) {
2955 log_normal(_("Sending info to metaserver <%s>."), meta_addr_port());
2956 /* Open socket for meta server */
2957 if (!server_open_meta(srvarg.metaconnection_persistent)
2958 || !send_server_info_to_metaserver(META_INFO)) {
2959 con_write(C_FAIL, _("Not starting without explicitly requested metaserver connection."));
2960 exit(EXIT_FAILURE);
2961 }
2962 }
2963
2964 eot_timer = timer_new(TIMER_CPU, TIMER_ACTIVE);
2965 }
2966
2967 /**************************************************************************
2968 Score calculation.
2969 **************************************************************************/
srv_scores(void)2970 static void srv_scores(void)
2971 {
2972 /* Recalculate the scores in case of a spaceship victory */
2973 players_iterate(pplayer) {
2974 calc_civ_score(pplayer);
2975 } players_iterate_end;
2976
2977 log_civ_score_now();
2978
2979 report_final_scores(NULL);
2980 show_map_to_all();
2981 notify_player(NULL, NULL, E_GAME_END, ftc_server,
2982 _("The game is over..."));
2983 send_server_info_to_metaserver(META_INFO);
2984
2985 if (game.server.save_nturns > 0
2986 && (conn_list_size(game.est_connections) > 0
2987 || !srvarg.quitidle)) {
2988 /* Save game on game_over, but not when the gameover was caused by
2989 * the -q parameter. Be sure that it's the -q, and not an autogame
2990 * with no human players. */
2991 save_game_auto("Game over", AS_GAME_OVER);
2992 }
2993 }
2994
2995 /**************************************************************************
2996 Apply some final adjustments from the ruleset on to the game state.
2997 We cannot do this during ruleset loading, since some players may be
2998 added later than that.
2999 **************************************************************************/
final_ruleset_adjustments(void)3000 static void final_ruleset_adjustments(void)
3001 {
3002 players_iterate(pplayer) {
3003 struct nation_type *pnation = nation_of_player(pplayer);
3004
3005 pplayer->government = init_government_of_nation(pnation);
3006
3007 if (pnation->init_government == game.government_during_revolution) {
3008 /* If we do not do this, an assertion will trigger. This enables us to
3009 * select a valid government on game start. */
3010 pplayer->revolution_finishes = 0;
3011 }
3012
3013 multipliers_iterate(pmul) {
3014 pplayer->multipliers[multiplier_index(pmul)]
3015 = pplayer->multipliers_target[multiplier_index(pmul)]
3016 = pmul->def;
3017 } multipliers_iterate_end;
3018 } players_iterate_end;
3019 }
3020
3021 /**************************************************************************
3022 Set up one game.
3023 **************************************************************************/
srv_ready(void)3024 static void srv_ready(void)
3025 {
3026 (void) send_server_info_to_metaserver(META_INFO);
3027
3028 if (game.server.auto_ai_toggle) {
3029 players_iterate(pplayer) {
3030 if (!pplayer->is_connected && !pplayer->ai_controlled) {
3031 toggle_ai_player_direct(NULL, pplayer);
3032 }
3033 } players_iterate_end;
3034 }
3035
3036 init_game_seed();
3037
3038 #ifdef TEST_RANDOM /* not defined anywhere, set it if you want it */
3039 test_random1(200);
3040 test_random1(2000);
3041 test_random1(20000);
3042 test_random1(200000);
3043 #endif
3044
3045 if (game.info.is_new_game) {
3046 game.info.year32 = game.server.start_year;
3047 game.info.year16 = game.server.start_year;
3048 /* Must come before assign_player_colors() */
3049 generate_players();
3050 final_ruleset_adjustments();
3051 }
3052
3053 /* If we have a tile map, and MAPGEN_SCENARIO == map.server.generator,
3054 * call map_fractal_generate anyway to make the specials, huts and
3055 * continent numbers. */
3056 if (map_is_empty()
3057 || (MAPGEN_SCENARIO == game.map.server.generator
3058 && game.info.is_new_game)) {
3059 struct {
3060 const char *name;
3061 char value[MAX_LEN_NAME * 2];
3062 char pretty[MAX_LEN_NAME * 2];
3063 } mapgen_settings[] = {
3064 { "generator", },
3065 { "startpos", },
3066 { "teamplacement", }
3067 };
3068 int i;
3069 /* If a specific seed has been requested, there's no point retrying,
3070 * as the map will be the same every time. */
3071 bool retry_ok = (game.map.server.seed_setting == 0
3072 && game.map.server.generator != MAPGEN_SCENARIO);
3073 int max = retry_ok ? 3 : 1;
3074 bool created = FALSE;
3075 struct unit_type *utype = NULL;
3076 int sucount = strlen(game.server.start_units);
3077
3078 if (sucount > 0) {
3079 for (i = 0; utype == NULL && i < sucount; i++) {
3080 utype = crole_to_unit_type(game.server.start_units[i], NULL);
3081 }
3082 } else {
3083 /* First unit the initial city might build. */
3084 utype = get_role_unit(L_FIRSTBUILD, 0);
3085 }
3086 fc_assert(utype != NULL);
3087
3088 /* Register map generator setting main values. */
3089 for (i = 0; i < ARRAY_SIZE(mapgen_settings); i++) {
3090 const struct setting *pset = setting_by_name(mapgen_settings[i].name);
3091
3092 fc_assert_action(pset != NULL, continue);
3093 (void) setting_value_name(pset, FALSE,
3094 mapgen_settings[i].value,
3095 sizeof(mapgen_settings[i].value));
3096 (void) setting_value_name(pset, TRUE,
3097 mapgen_settings[i].pretty,
3098 sizeof(mapgen_settings[i].pretty));
3099 }
3100
3101 for (i = 0; !created && i < max ; i++) {
3102 created = map_fractal_generate(TRUE, utype);
3103 if (!created && max > 1) {
3104 int set;
3105
3106 /* If we're retrying, seed_setting==0, which will yield a new map
3107 * next time */
3108 fc_assert(game.map.server.seed_setting == 0);
3109 if (i == 0) {
3110 /* We will retry only if max attempts allow it */
3111 log_normal(_("Failed to create suitable map, retrying with another mapseed."));
3112 } else {
3113 /* +1 - start human readable count from 1 and not from 0
3114 * +1 - refers to next round, not to one we just did
3115 * ==
3116 * +2 */
3117 log_normal(_("Attempt %d/%d"), i + 2, max);
3118 }
3119 game.map.server.have_resources = FALSE;
3120
3121 /* Remove old information already present in tiles */
3122 map_free();
3123 /* Restore the settings. */
3124 for (set = 0; set < ARRAY_SIZE(mapgen_settings); set++) {
3125 struct setting *pset = setting_by_name(mapgen_settings[set].name);
3126 #ifdef FREECIV_NDEBUG
3127 setting_enum_set(pset, mapgen_settings[set].value, NULL, NULL, 0);
3128 #else /* FREECIV_NDEBUG */
3129 char error[128];
3130 bool success;
3131
3132 fc_assert_action(pset != NULL, continue);
3133 success = setting_enum_set(pset, mapgen_settings[set].value,
3134 NULL, error, sizeof(error));
3135 fc_assert_msg(success == TRUE,
3136 "Failed to restore '%s': %s",
3137 mapgen_settings[set].name,
3138 error);
3139 #endif /* FREECIV_NDEBUG */
3140 }
3141 map_allocate(); /* NOT map_init() as that would overwrite settings */
3142 }
3143 }
3144 if (!created) {
3145 log_error(_("Cannot create suitable map with given settings."));
3146 /* TRANS: No full stop after the URL, could cause confusion. */
3147 log_error(_("Please report this message at %s"), BUG_URL);
3148 exit(EXIT_FAILURE);
3149 }
3150
3151 if (game.map.server.generator != MAPGEN_SCENARIO) {
3152 script_server_signal_emit("map_generated", 0);
3153 }
3154
3155 game_map_init();
3156
3157 /* Test if main map generator settings have changed. */
3158 for (i = 0; i < ARRAY_SIZE(mapgen_settings); i++) {
3159 const struct setting *pset = setting_by_name(mapgen_settings[i].name);
3160 char pretty[sizeof(mapgen_settings[i].pretty)];
3161
3162 fc_assert_action(pset != NULL, continue);
3163 if (0 == strcmp(setting_value_name(pset, TRUE, pretty,
3164 sizeof(pretty)),
3165 mapgen_settings[i].pretty)) {
3166 continue; /* Setting didn't change. */
3167 }
3168 notify_conn(NULL, NULL, E_SETTING, ftc_server,
3169 _("Setting '%s' has been adjusted from %s to %s."),
3170 setting_name(pset),
3171 mapgen_settings[i].pretty,
3172 pretty);
3173 log_normal(_("Setting '%s' has been adjusted from %s to %s."),
3174 setting_name(pset),
3175 mapgen_settings[i].pretty,
3176 pretty);
3177 }
3178 }
3179
3180 /* start the game */
3181 set_server_state(S_S_RUNNING);
3182 (void) send_server_info_to_metaserver(META_INFO);
3183
3184 if (game.info.is_new_game) {
3185 shuffle_players();
3186
3187 /* If we're starting a new game, reset the max_players to be at
3188 * least the number of players currently in the game. */
3189 game.server.max_players = MAX(normal_player_count(), game.server.max_players);
3190
3191 /* Before the player map is allocated (and initialized)! */
3192 game.server.fogofwar_old = game.info.fogofwar;
3193
3194 players_iterate(pplayer) {
3195 player_map_init(pplayer);
3196 pplayer->economic = player_limit_to_max_rates(pplayer);
3197 pplayer->economic.gold = game.info.gold;
3198 } players_iterate_end;
3199
3200 /* Give initial technologies, as specified in the ruleset and the
3201 * settings. */
3202 researches_iterate(presearch) {
3203 init_tech(presearch, TRUE);
3204 give_initial_techs(presearch, game.info.tech);
3205 } researches_iterate_end;
3206
3207 /* Set up alliances based on team selections */
3208 players_iterate(pplayer) {
3209 players_iterate(pdest) {
3210 if (players_on_same_team(pplayer, pdest)
3211 && player_number(pplayer) != player_number(pdest)) {
3212 player_diplstate_get(pplayer, pdest)->type = DS_TEAM;
3213 give_shared_vision(pplayer, pdest);
3214 BV_SET(pplayer->real_embassy, player_index(pdest));
3215 }
3216 } players_iterate_end;
3217 } players_iterate_end;
3218
3219 /* Assign colors from the ruleset for any players who weren't
3220 * explicitly assigned colors during the pregame.
3221 * This must come after generate_players() since it can depend on
3222 * assigned nations. */
3223 assign_player_colors();
3224
3225 /* Save all settings for the 'reset game' command. */
3226 settings_game_start();
3227 }
3228
3229 /* FIXME: can this be moved? */
3230 players_iterate(pplayer) {
3231 adv_data_analyze_rulesets(pplayer);
3232 } players_iterate_end;
3233
3234 if (!game.info.is_new_game) {
3235 players_iterate(pplayer) {
3236 if (pplayer->ai_controlled) {
3237 set_ai_level_direct(pplayer, pplayer->ai_common.skill_level);
3238 }
3239 } players_iterate_end;
3240 } else {
3241 players_iterate(pplayer) {
3242 /* Initialize this again to be sure */
3243 adv_data_default(pplayer);
3244 } players_iterate_end;
3245 }
3246
3247 conn_list_compression_freeze(game.est_connections);
3248 send_all_info(game.est_connections);
3249 conn_list_compression_thaw(game.est_connections);
3250
3251 if (game.info.is_new_game) {
3252 /* Place players' initial units, etc */
3253 init_new_game();
3254 create_animals();
3255
3256 if (game.server.revealmap & REVEAL_MAP_START) {
3257 players_iterate(pplayer) {
3258 map_show_all(pplayer);
3259 } players_iterate_end;
3260 }
3261 }
3262
3263 if (game.scenario.is_scenario && game.scenario.players) {
3264 /* This is a heavy scenario. It may include research. The sciencebox
3265 * setting may have been changed. A change to the sciencebox setting
3266 * may have caused the stored amount of bulbs to be enough to finish
3267 * the current research. */
3268
3269 players_iterate(pplayer) {
3270 /* Check for finished research. */
3271 update_bulbs(pplayer, 0, TRUE);
3272 } players_iterate_end;
3273 }
3274
3275 CALL_FUNC_EACH_AI(game_start);
3276 }
3277
3278 /**************************************************************************
3279 Initialize game data for the server (corresponds to server_game_free).
3280 **************************************************************************/
server_game_init(void)3281 void server_game_init(void)
3282 {
3283 /* was redundantly in game_load() */
3284 server.playable_nations = 0;
3285 server.nbarbarians = 0;
3286 server.identity_number = IDENTITY_NUMBER_SKIP;
3287
3288 BV_CLR_ALL(identity_numbers_used);
3289 identity_number_reserve(IDENTITY_NUMBER_ZERO);
3290
3291 event_cache_init();
3292 game_init();
3293 /* game_init() set game.server.plr_colors to NULL. So we need to
3294 * initialize the colors after. */
3295 playercolor_init();
3296
3297 game.server.turn_change_time = 0;
3298 }
3299
3300 /**************************************************************************
3301 Free game data that we reinitialize as part of a server soft restart.
3302 Bear in mind that this function is called when the 'load' command is
3303 used, for instance.
3304 **************************************************************************/
server_game_free(void)3305 void server_game_free(void)
3306 {
3307 CALL_FUNC_EACH_AI(game_free);
3308
3309 /* Free all the treaties that were left open when game finished. */
3310 free_treaties();
3311
3312 /* Free the vision data, without sending updates. */
3313 players_iterate(pplayer) {
3314 unit_list_iterate(pplayer->units, punit) {
3315 /* don't bother using vision_clear_sight() */
3316 vision_layer_iterate(v) {
3317 punit->server.vision->radius_sq[v] = -1;
3318 } vision_layer_iterate_end;
3319 vision_free(punit->server.vision);
3320 punit->server.vision = NULL;
3321 } unit_list_iterate_end;
3322
3323 city_list_iterate(pplayer->cities, pcity) {
3324 /* don't bother using vision_clear_sight() */
3325 vision_layer_iterate(v) {
3326 pcity->server.vision->radius_sq[v] = -1;
3327 } vision_layer_iterate_end;
3328 vision_free(pcity->server.vision);
3329 pcity->server.vision = NULL;
3330 adv_city_free(pcity);
3331 } city_list_iterate_end;
3332 } players_iterate_end;
3333
3334 /* Destroy all players; with must be separate as the player information is
3335 * needed above. This also sends the information to the clients. */
3336 players_iterate(pplayer) {
3337 server_remove_player(pplayer);
3338 } players_iterate_end;
3339
3340 event_cache_free();
3341 log_civ_score_free();
3342 playercolor_free();
3343 citymap_free();
3344 game_free();
3345 }
3346
3347 /**************************************************************************
3348 Server main loop.
3349 **************************************************************************/
srv_main(void)3350 void srv_main(void)
3351 {
3352 fc_interface_init_server();
3353 advisors_init();
3354
3355 srv_prepare();
3356
3357 /* Run server loop */
3358 do {
3359 set_server_state(S_S_INITIAL);
3360
3361 /* Load a script file. */
3362 if (NULL != srvarg.script_filename) {
3363 /* Adding an error message more here will duplicate them. */
3364 (void) read_init_script(NULL, srvarg.script_filename, TRUE, FALSE);
3365 }
3366
3367 (void) aifill(game.info.aifill);
3368 if (!game_was_started()) {
3369 event_cache_clear();
3370 }
3371
3372 log_normal(_("Now accepting new client connections on port %d."),
3373 srvarg.port);
3374 /* Remain in S_S_INITIAL until all players are ready. */
3375 while (S_E_FORCE_END_OF_SNIFF != server_sniff_all_input()) {
3376 /* When force_end_of_sniff is used in pregame, it means that the server
3377 * is ready to start (usually set within start_game()). */
3378 }
3379
3380 if (S_S_RUNNING > server_state()) {
3381 /* If restarting for lack of players, the state is S_S_OVER,
3382 * so don't try to start the game. */
3383 srv_ready(); /* srv_ready() sets server state to S_S_RUNNING. */
3384 srv_running();
3385 srv_scores();
3386 }
3387
3388 /* Remain in S_S_OVER until players log out */
3389 while (conn_list_size(game.est_connections) > 0) {
3390 server_sniff_all_input();
3391 }
3392
3393 if (game.info.timeout == -1 || srvarg.exit_on_end) {
3394 /* For autogames or if the -e option is specified, exit the server. */
3395 server_quit();
3396 }
3397
3398 /* Reset server */
3399 server_game_free();
3400 fc_rand_uninit();
3401 server_game_init();
3402 mapimg_reset();
3403 load_rulesets(NULL, TRUE, FALSE);
3404 game.info.is_new_game = TRUE;
3405 } while (TRUE);
3406
3407 /* Technically, we won't ever get here. We exit via server_quit. */
3408 }
3409
3410 /***************************************************************
3411 Initialize client specific functions.
3412 ***************************************************************/
3413 struct color;
server_gui_color_free(struct color * pcolor)3414 static inline void server_gui_color_free(struct color *pcolor)
3415 {
3416 fc_assert_ret(pcolor == NULL);
3417
3418 return;
3419 }
3420
3421 /***************************************************************
3422 Initialize server specific functions.
3423 ***************************************************************/
fc_interface_init_server(void)3424 static void fc_interface_init_server(void)
3425 {
3426 struct functions *funcs = fc_interface_funcs();
3427
3428 funcs->create_extra = create_extra;
3429 funcs->destroy_extra = destroy_extra;
3430 funcs->player_tile_vision_get = map_is_known_and_seen;
3431 funcs->gui_color_free = server_gui_color_free;
3432
3433 /* Keep this function call at the end. It checks if all required functions
3434 are defined. */
3435 fc_interface_init();
3436 }
3437
3438 /***************************************************************************
3439 Helper function for the mapimg module - tile knowledge.
3440 ****************************************************************************/
mapimg_server_tile_known(const struct tile * ptile,const struct player * pplayer,bool knowledge)3441 static enum known_type mapimg_server_tile_known(const struct tile *ptile,
3442 const struct player *pplayer,
3443 bool knowledge)
3444 {
3445 if (knowledge && pplayer) {
3446 return tile_get_known(ptile, pplayer);
3447 }
3448
3449 return TILE_KNOWN_SEEN;
3450 }
3451
3452 /****************************************************************************
3453 Helper function for the mapimg module - tile terrain.
3454 ****************************************************************************/
3455 static struct terrain
mapimg_server_tile_terrain(const struct tile * ptile,const struct player * pplayer,bool knowledge)3456 *mapimg_server_tile_terrain(const struct tile *ptile,
3457 const struct player *pplayer, bool knowledge)
3458 {
3459 if (knowledge && pplayer) {
3460 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
3461 return plrtile->terrain;
3462 }
3463
3464 return tile_terrain(ptile);
3465 }
3466
3467 /****************************************************************************
3468 Helper function for the mapimg module - tile owner.
3469 ****************************************************************************/
mapimg_server_tile_owner(const struct tile * ptile,const struct player * pplayer,bool knowledge)3470 static struct player *mapimg_server_tile_owner(const struct tile *ptile,
3471 const struct player *pplayer,
3472 bool knowledge)
3473 {
3474 if (knowledge && pplayer
3475 && tile_get_known(ptile, pplayer) != TILE_KNOWN_SEEN) {
3476 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
3477 return plrtile->owner;
3478 }
3479
3480 return tile_owner(ptile);
3481 }
3482
3483 /****************************************************************************
3484 Helper function for the mapimg module - city owner.
3485 ****************************************************************************/
mapimg_server_tile_city(const struct tile * ptile,const struct player * pplayer,bool knowledge)3486 static struct player *mapimg_server_tile_city(const struct tile *ptile,
3487 const struct player *pplayer,
3488 bool knowledge)
3489 {
3490 struct city *pcity = tile_city(ptile);
3491
3492 if (!pcity) {
3493 return NULL;
3494 }
3495
3496 if (knowledge && pplayer) {
3497 struct vision_site *pdcity = map_get_player_city(ptile, pplayer);
3498
3499 if (pdcity) {
3500 return pdcity->owner;
3501 } else {
3502 return NULL;
3503 }
3504 }
3505
3506 return city_owner(tile_city(ptile));
3507 }
3508
3509 /****************************************************************************
3510 Helper function for the mapimg module - unit owner.
3511 ****************************************************************************/
mapimg_server_tile_unit(const struct tile * ptile,const struct player * pplayer,bool knowledge)3512 static struct player *mapimg_server_tile_unit(const struct tile *ptile,
3513 const struct player *pplayer,
3514 bool knowledge)
3515 {
3516 int unit_count = unit_list_size(ptile->units);
3517
3518 if (unit_count == 0) {
3519 return NULL;
3520 }
3521
3522 if (knowledge && pplayer
3523 && tile_get_known(ptile, pplayer) != TILE_KNOWN_SEEN) {
3524 return NULL;
3525 }
3526
3527 return unit_owner(unit_list_get(ptile->units, 0));
3528 }
3529
3530 /****************************************************************************
3531 Helper function for the mapimg module - number of player colors.
3532 ****************************************************************************/
mapimg_server_plrcolor_count(void)3533 static int mapimg_server_plrcolor_count(void)
3534 {
3535 return playercolor_count();
3536 }
3537
3538 /****************************************************************************
3539 Helper function for the mapimg module - one player color.
3540 ****************************************************************************/
mapimg_server_plrcolor_get(int i)3541 static struct rgbcolor *mapimg_server_plrcolor_get(int i)
3542 {
3543 return playercolor_get(i);
3544 }
3545