Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/notify.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
notify.c
Go to the documentation of this file.
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 <stdarg.h>
19
20/* utility */
21#include "bitvector.h"
22#include "log.h"
23#include "registry.h"
24
25/* common */
26#include "connection.h"
27#include "events.h"
28#include "featured_text.h"
29#include "game.h"
30#include "research.h"
31#include "packets.h"
32#include "player.h"
33#include "tile.h"
34
35/* server */
36#include "maphand.h"
37#include "srv_main.h"
38
39#include "notify.h"
40
41
42/**********************************************************************/
55 static void package_event_full(struct packet_chat_msg *packet,
56 const struct tile *ptile,
57 enum event_type event,
58 const struct connection *pconn,
59 const struct ft_color color,
60 const char *format, va_list vargs)
61{
62 char buf[MAX_LEN_MSG];
63 char *str;
64
65 fc_assert_ret(NULL != packet);
66
67 packet->tile = (NULL != ptile ? tile_index(ptile) : -1);
68 packet->event = event;
69 packet->conn_id = pconn ? pconn->id : -1;
70 packet->turn = game.info.turn;
71 packet->phase = game.info.phase;
72
73 fc_vsnprintf(buf, sizeof(buf), format, vargs);
74 if (is_capitalization_enabled()) {
75 str = capitalized_string(buf);
76 } else {
77 str = buf;
78 }
79
80 if (ft_color_requested(color)) {
81 featured_text_apply_tag(str, packet->message, sizeof(packet->message),
82 TTT_COLOR, 0, FT_OFFSET_UNSET, color);
83 } else {
84 /* Simple case */
85 sz_strlcpy(packet->message, str);
86 }
87
88 if (is_capitalization_enabled()) {
89 free_capitalized(str);
90 }
91}
92
93/**********************************************************************/
104 void vpackage_chat_msg(struct packet_chat_msg *packet,
105 const struct connection *sender,
106 const struct ft_color color,
107 const char *format, va_list vargs)
108{
109 package_event_full(packet, NULL, E_CHAT_MSG, sender, color, format, vargs);
110}
111
112/**********************************************************************/
123 void package_chat_msg(struct packet_chat_msg *packet,
124 const struct connection *sender,
125 const struct ft_color color,
126 const char *format, ...)
127{
128 va_list args;
129
130 va_start(args, format);
131 vpackage_chat_msg(packet, sender, color, format, args);
132 va_end(args);
133}
134
135/**********************************************************************/
147 void vpackage_event(struct packet_chat_msg *packet,
148 const struct tile *ptile,
149 enum event_type event,
150 const struct ft_color color,
151 const char *format, va_list vargs)
152{
153 package_event_full(packet, ptile, event, NULL, color, format, vargs);
154}
155
156/**********************************************************************/
168 void package_event(struct packet_chat_msg *packet,
169 const struct tile *ptile,
170 enum event_type event,
171 const struct ft_color color,
172 const char *format, ...)
173{
174 va_list args;
175
176 va_start(args, format);
177 vpackage_event(packet, ptile, event, color, format, args);
178 va_end(args);
179}
180
181
182/**********************************************************************/
193 static void notify_conn_packet(struct conn_list *dest,
194 const struct packet_chat_msg *packet,
195 bool early)
196{
197 struct packet_chat_msg real_packet = *packet;
198 int tile = packet->tile;
199 struct tile *ptile = index_to_tile(&(wld.map), tile);
200
201 if (!dest) {
202 dest = game.est_connections;
203 }
204
205 conn_list_iterate(dest, pconn) {
206 /* Avoid sending messages that could potentially reveal
207 * internal information about the server machine to
208 * connections that do not already have hack access. */
209 if ((packet->event == E_LOG_ERROR || packet->event == E_LOG_FATAL)
210 && pconn->access_level != ALLOW_HACK) {
211 continue;
212 }
213
214 if (S_S_RUNNING <= server_state()
215 && ptile /* special case, see above */
216 && ((NULL == pconn->playing && pconn->observer)
217 || (NULL != pconn->playing
218 && map_is_known(ptile, pconn->playing)))) {
219 /* tile info is OK; see above. */
220 /* FIXME: in the case this is a city event, we should check if the
221 * city is really known. */
222 real_packet.tile = tile;
223 } else {
224 /* No tile info. */
225 real_packet.tile = -1;
226 }
227
228 if (early) {
229 send_packet_early_chat_msg(pconn, (struct packet_early_chat_msg *)(&real_packet));
230 } else {
231 send_packet_chat_msg(pconn, &real_packet);
232 }
233 } conn_list_iterate_end;
234}
235
236/**********************************************************************/
239 void notify_conn(struct conn_list *dest,
240 const struct tile *ptile,
241 enum event_type event,
242 const struct ft_color color,
243 const char *format, ...)
244{
245 struct packet_chat_msg genmsg;
246 va_list args;
247
248 va_start(args, format);
249 vpackage_event(&genmsg, ptile, event, color, format, args);
250 va_end(args);
251
252 notify_conn_packet(dest, &genmsg, FALSE);
253
254 if (!dest || dest == game.est_connections) {
255 /* Add to the cache */
256 event_cache_add_for_all(&genmsg);
257 }
258}
259
260/**********************************************************************/
264 void notify_conn_early(struct conn_list *dest,
265 const struct tile *ptile,
266 enum event_type event,
267 const struct ft_color color,
268 const char *format, ...)
269{
270 struct packet_chat_msg genmsg;
271 va_list args;
272
273 va_start(args, format);
274 vpackage_event(&genmsg, ptile, event, color, format, args);
275 va_end(args);
276
277 notify_conn_packet(dest, &genmsg, TRUE);
278
279 if (!dest || dest == game.est_connections) {
280 /* Add to the cache */
281 event_cache_add_for_all(&genmsg);
282 }
283}
284
285/**********************************************************************/
292 void notify_player(const struct player *pplayer,
293 const struct tile *ptile,
294 enum event_type event,
295 const struct ft_color color,
296 const char *format, ...)
297{
298 struct conn_list *dest = pplayer ? pplayer->connections : NULL;
299 struct packet_chat_msg genmsg;
300 va_list args;
301
302 va_start(args, format);
303 vpackage_event(&genmsg, ptile, event, color, format, args);
304 va_end(args);
305
306 notify_conn_packet(dest, &genmsg, FALSE);
307
308 /* Add to the cache */
309 event_cache_add_for_player(&genmsg, pplayer);
310}
311
312/**********************************************************************/
316 void notify_embassies(const struct player *pplayer,
317 const struct tile *ptile,
318 enum event_type event,
319 const struct ft_color color,
320 const char *format, ...)
321{
322 struct packet_chat_msg genmsg;
323 struct event_cache_players *players = NULL;
324 va_list args;
325
326 va_start(args, format);
327 vpackage_event(&genmsg, ptile, event, color, format, args);
328 va_end(args);
329
330 players_iterate(other_player) {
331 if (team_has_embassy(other_player->team, pplayer)
332 && pplayer != other_player) {
333 notify_conn_packet(other_player->connections, &genmsg, FALSE);
334 players = event_cache_player_add(players, other_player);
335 }
336 } players_iterate_end;
337
338 /* Add to the cache */
339 event_cache_add_for_players(&genmsg, players);
340}
341
342/**********************************************************************/
346 void notify_team(const struct player *pplayer,
347 const struct tile *ptile,
348 enum event_type event,
349 const struct ft_color color,
350 const char *format, ...)
351{
352 struct conn_list *dest = game.est_connections;
353 struct packet_chat_msg genmsg;
354 struct event_cache_players *players = NULL;
355 va_list args;
356
357 va_start(args, format);
358 vpackage_event(&genmsg, ptile, event, color, format, args);
359 va_end(args);
360
361 if (pplayer) {
362 dest = conn_list_new();
363 players_iterate(other_player) {
364 if (!players_on_same_team(pplayer, other_player)) {
365 continue;
366 }
367 conn_list_iterate(other_player->connections, pconn) {
368 conn_list_append(dest, pconn);
369 } conn_list_iterate_end;
370 players = event_cache_player_add(players, other_player);
371 } players_iterate_end;
372
373 /* Add to the cache */
374 event_cache_add_for_players(&genmsg, players);
375
376 } else {
377 /* Add to the cache for all players. */
378 event_cache_add_for_all(&genmsg);
379 }
380
381 notify_conn_packet(dest, &genmsg, FALSE);
382
383 if (pplayer) {
384 conn_list_destroy(dest);
385 }
386}
387
388/**********************************************************************/
394 void notify_research(const struct research *presearch,
395 const struct player *exclude,
396 enum event_type event,
397 const struct ft_color color,
398 const char *format, ...)
399{
400 struct packet_chat_msg genmsg;
401 struct event_cache_players *players = NULL;
402 va_list args;
403
404 va_start(args, format);
405 vpackage_event(&genmsg, NULL, event, color, format, args);
406 va_end(args);
407
408 research_players_iterate(presearch, aplayer) {
409 if (exclude != aplayer) {
410 lsend_packet_chat_msg(aplayer->connections, &genmsg);
411 players = event_cache_player_add(players, aplayer);
412 }
413 } research_players_iterate_end;
414
415 /* Add to the cache */
416 event_cache_add_for_players(&genmsg, players);
417}
418
419/**********************************************************************/
434 void notify_research_embassies(const struct research *presearch,
435 const struct player *exclude,
436 enum event_type event,
437 const struct ft_color color,
438 const char *format, ...)
439{
440 struct packet_chat_msg genmsg;
441 struct event_cache_players *players = NULL;
442 va_list args;
443
444 va_start(args, format);
445 vpackage_event(&genmsg, NULL, event, color, format, args);
446 va_end(args);
447
448 players_iterate(aplayer) {
449 if (exclude == aplayer || research_get(aplayer) == presearch) {
450 continue;
451 }
452
453 research_players_iterate(presearch, rplayer) {
454 if (team_has_embassy(aplayer->team, rplayer)) {
455 lsend_packet_chat_msg(aplayer->connections, &genmsg);
456 players = event_cache_player_add(players, aplayer);
457 break;
458 }
459 } research_players_iterate_end;
460 } players_iterate_end;
461
462 /* Add to the cache */
463 event_cache_add_for_players(&genmsg, players);
464}
465
466
467/**************************************************************************
468 Event cache datas.
469**************************************************************************/
470 enum event_cache_target {
471 ECT_ALL,
472 ECT_PLAYERS,
473 ECT_GLOBAL_OBSERVERS
474};
475
476/* Events are saved in that structure. */
477 struct event_cache_data {
478 struct packet_chat_msg packet;
479 time_t timestamp;
480 enum server_states server_state;
481 enum event_cache_target target_type;
482 bv_player target; /* Used if target_type == ECT_PLAYERS. */
483};
484
485#define SPECLIST_TAG event_cache_data
486#define SPECLIST_TYPE struct event_cache_data
487#include "speclist.h"
488#define event_cache_iterate(pdata) \
489 TYPED_LIST_ITERATE(struct event_cache_data, event_cache, pdata)
490#define event_cache_iterate_end LIST_ITERATE_END
491
492 struct event_cache_players {
493 bv_player vector;
494};
495
496/* The full list of the events. */
497 static struct event_cache_data_list *event_cache = NULL;
498
499/* Event cache status: ON(TRUE) / OFF(FALSE); used for saving the
500 * event cache */
501 static bool event_cache_status = FALSE;
502
503/**********************************************************************/
506 static void event_cache_data_free(struct event_cache_data *data)
507{
508 free(data);
509}
510
511/**********************************************************************/
515static struct event_cache_data *
516event_cache_data_new(const struct packet_chat_msg *packet,
517 time_t timestamp, enum server_states server_status,
518 enum event_cache_target target_type,
519 struct event_cache_players *players)
520{
521 struct event_cache_data *pdata;
522 int max_events;
523
524 if (NULL == event_cache) {
525 /* Don't do log for this, because this could make an infinite
526 * recursion. */
527 return NULL;
528 }
529 fc_assert_ret_val(NULL != packet, NULL);
530
531 if (packet->event == E_MESSAGE_WALL) {
532 /* No popups at save game load. */
533 return NULL;
534 }
535
536 if (!game.server.event_cache.chat && packet->event == E_CHAT_MSG) {
537 /* chat messages should _not_ be saved */
538 return NULL;
539 }
540
541 /* check if cache is active */
542 if (!event_cache_status) {
543 return NULL;
544 }
545
546 pdata = fc_malloc(sizeof(*pdata));
547 pdata->packet = *packet;
548 pdata->timestamp = timestamp;
549 pdata->server_state = server_status;
550 pdata->target_type = target_type;
551 if (players) {
552 pdata->target = players->vector;
553 } else {
554 BV_CLR_ALL(pdata->target);
555 }
556 event_cache_data_list_append(event_cache, pdata);
557
558 max_events = game.server.event_cache.max_size
559 ? game.server.event_cache.max_size
560 : GAME_MAX_EVENT_CACHE_MAX_SIZE;
561 while (event_cache_data_list_size(event_cache) > max_events) {
562 event_cache_data_list_pop_front(event_cache);
563 }
564
565 return pdata;
566}
567
568/**********************************************************************/
571 void event_cache_init(void)
572{
573 if (event_cache != NULL) {
574 event_cache_free();
575 }
576 event_cache = event_cache_data_list_new_full(event_cache_data_free);
577 event_cache_status = TRUE;
578}
579
580/**********************************************************************/
583 void event_cache_free(void)
584{
585 if (event_cache != NULL) {
586 event_cache_data_list_destroy(event_cache);
587 event_cache = NULL;
588 }
589 event_cache_status = FALSE;
590}
591
592/**********************************************************************/
595 void event_cache_clear(void)
596{
597 event_cache_data_list_clear(event_cache);
598}
599
600/**********************************************************************/
603 void event_cache_remove_old(void)
604{
605 struct event_cache_data *current;
606
607 /* This assumes that entries are in order, the ones to be removed first. */
608 current = event_cache_data_list_get(event_cache, 0);
609
610 while (current != NULL
611 && current->packet.turn + game.server.event_cache.turns <= game.info.turn) {
612 event_cache_data_list_pop_front(event_cache);
613 current = event_cache_data_list_get(event_cache, 0);
614 }
615}
616
617/**********************************************************************/
620 void event_cache_add_for_all(const struct packet_chat_msg *packet)
621{
622 if (0 < game.server.event_cache.turns) {
623 (void) event_cache_data_new(packet, time(NULL),
624 server_state(), ECT_ALL, NULL);
625 }
626}
627
628/**********************************************************************/
631 void event_cache_add_for_global_observers(const struct packet_chat_msg *packet)
632{
633 if (0 < game.server.event_cache.turns) {
634 (void) event_cache_data_new(packet, time(NULL),
635 server_state(), ECT_GLOBAL_OBSERVERS, NULL);
636 }
637}
638
639/**********************************************************************/
646 void event_cache_add_for_player(const struct packet_chat_msg *packet,
647 const struct player *pplayer)
648{
649 if (NULL == pplayer) {
650 event_cache_add_for_all(packet);
651 return;
652 }
653
654 if (0 < game.server.event_cache.turns
655 && (server_state() > S_S_INITIAL || !game.info.is_new_game)) {
656 struct event_cache_data *pdata;
657
658 pdata = event_cache_data_new(packet, time(NULL),
659 server_state(), ECT_PLAYERS, NULL);
660 fc_assert_ret(NULL != pdata);
661 BV_SET(pdata->target, player_index(pplayer));
662 }
663}
664
665/**********************************************************************/
672 void event_cache_add_for_players(const struct packet_chat_msg *packet,
673 struct event_cache_players *players)
674{
675 if (0 < game.server.event_cache.turns
676 && NULL != players
677 && BV_ISSET_ANY(players->vector)
678 && (server_state() > S_S_INITIAL || !game.info.is_new_game)) {
679 (void) event_cache_data_new(packet, time(NULL),
680 server_state(), ECT_PLAYERS, players);
681 }
682
683 if (NULL != players) {
684 free(players);
685 }
686}
687
688/**********************************************************************/
703struct event_cache_players *
704event_cache_player_add(struct event_cache_players *players,
705 const struct player *pplayer)
706{
707 if (NULL == players) {
708 players = fc_malloc(sizeof(*players));
709 BV_CLR_ALL(players->vector);
710 }
711
712 if (NULL != pplayer) {
713 BV_SET(players->vector, player_index(pplayer));
714 }
715
716 return players;
717}
718
719/**********************************************************************/
722 static bool event_cache_match(const struct event_cache_data *pdata,
723 const struct player *pplayer,
724 bool is_global_observer,
725 bool include_public)
726{
727 if (server_state() != pdata->server_state) {
728 return FALSE;
729 }
730
731 if (server_state() == S_S_RUNNING
732 && game.info.turn < pdata->packet.turn
733 && game.info.turn > pdata->packet.turn - game.server.event_cache.turns) {
734 return FALSE;
735 }
736
737 switch (pdata->target_type) {
738 case ECT_ALL:
739 return include_public;
740 case ECT_PLAYERS:
741 return (NULL != pplayer
742 && BV_ISSET(pdata->target, player_index(pplayer)));
743 case ECT_GLOBAL_OBSERVERS:
744 return is_global_observer;
745 }
746
747 return FALSE;
748}
749
750/**********************************************************************/
754 void send_pending_events(struct connection *pconn, bool include_public)
755{
756 const struct player *pplayer = conn_get_player(pconn);
757 bool is_global_observer = conn_is_global_observer(pconn);
758 char timestr[64];
759 struct packet_chat_msg pcm;
760
761 event_cache_iterate(pdata) {
762 if (event_cache_match(pdata, pplayer,
763 is_global_observer, include_public)) {
764 if (game.server.event_cache.info) {
765 struct tm tr;
766
767 /* Add turn and time to the message */
768 strftime(timestr, sizeof(timestr), "%H:%M:%S",
769 fc_localtime(&pdata->timestamp, &tr));
770 pcm = pdata->packet;
771 fc_snprintf(pcm.message, sizeof(pcm.message), "(T%d - %s) %s",
772 pdata->packet.turn, timestr, pdata->packet.message);
773 notify_conn_packet(pconn->self, &pcm, FALSE);
774 } else {
775 notify_conn_packet(pconn->self, &pdata->packet, FALSE);
776 }
777 }
778 } event_cache_iterate_end;
779}
780
781/**********************************************************************/
784 void event_cache_load(struct section_file *file, const char *section)
785{
786 struct packet_chat_msg packet;
787 enum event_cache_target target_type;
788 enum server_states server_status;
789 struct event_cache_players *players = NULL;
790 int i, x, y, event_count;
791 time_t timestamp, now;
792 const char *p, *q;
793
794 event_count = secfile_lookup_int_default(file, 0, "%s.count", section);
795 log_verbose("Saved events: %d.", event_count);
796
797 if (0 >= event_count) {
798 return;
799 }
800
801 now = time(NULL);
802 for (i = 0; i < event_count; i++) {
803 int turn;
804 int phase;
805
806 /* restore packet */
807 x = secfile_lookup_int_default(file, -1, "%s.events%d.x", section, i);
808 y = secfile_lookup_int_default(file, -1, "%s.events%d.y", section, i);
809 packet.tile = (is_normal_map_pos(x, y)
810 ? map_pos_to_index(&(wld.map), x, y) : -1);
811 packet.conn_id = -1;
812
813 p = secfile_lookup_str(file, "%s.events%d.event", section, i);
814 if (NULL == p) {
815 log_verbose("[Event cache %4d] Missing event type.", i);
816 continue;
817 }
818 packet.event = event_type_by_name(p, fc_strcasecmp);
819 if (!event_type_is_valid(packet.event)) {
820 log_verbose("[Event cache %4d] Not supported event type: %s", i, p);
821 continue;
822 }
823
824 p = secfile_lookup_str(file, "%s.events%d.message", section, i);
825 if (NULL == p) {
826 log_verbose("[Event cache %4d] Missing message.", i);
827 continue;
828 }
829 sz_strlcpy(packet.message, p);
830
831 /* restore event cache data */
832 turn = secfile_lookup_int_default(file, 0, "%s.events%d.turn",
833 section, i);
834 packet.turn = turn;
835
836 phase = secfile_lookup_int_default(file, PHASE_UNKNOWN, "%s.events%d.phase",
837 section, i);
838 packet.phase = phase;
839
840 timestamp = secfile_lookup_int_default(file, now,
841 "%s.events%d.timestamp",
842 section, i);
843
844 p = secfile_lookup_str(file, "%s.events%d.server_state", section, i);
845 if (NULL == p) {
846 log_verbose("[Event cache %4d] Missing server state info.", i);
847 continue;
848 }
849 server_status = server_states_by_name(p, fc_strcasecmp);
850 if (!server_states_is_valid(server_status)) {
851 log_verbose("[Event cache %4d] Server state no supported: %s", i, p);
852 continue;
853 }
854
855 p = secfile_lookup_str(file, "%s.events%d.target", section, i);
856 if (NULL == p) {
857 log_verbose("[Event cache %4d] Missing target info.", i);
858 continue;
859 } else if (0 == fc_strcasecmp(p, "All")) {
860 target_type = ECT_ALL;
861 } else if (0 == fc_strcasecmp(p, "Global Observers")) {
862 target_type = ECT_GLOBAL_OBSERVERS;
863 } else {
864 bool valid = TRUE;
865
866 target_type = ECT_PLAYERS;
867 q = p;
868 players_iterate(pplayer) {
869 if ('1' == *q) {
870 players = event_cache_player_add(players, pplayer);
871 } else if ('0' != *q) {
872 /* a value not '0' or '1' means a corruption of the savegame */
873 valid = FALSE;
874 break;
875 }
876
877 q++;
878 } players_iterate_end;
879
880 if (!valid && NULL == players) {
881 log_verbose("[Event cache %4d] invalid target bitmap: %s", i, p);
882 if (NULL != players) {
883 FC_FREE(players);
884 }
885 }
886 }
887
888 /* insert event into the cache */
889 (void) event_cache_data_new(&packet, timestamp, server_status,
890 target_type, players);
891
892 if (NULL != players) {
893 /* free the event cache player selection */
894 FC_FREE(players);
895 }
896
897 log_verbose("Event %4d loaded.", i);
898 }
899}
900
901/**********************************************************************/
904 void event_cache_save(struct section_file *file, const char *section)
905{
906 int event_count = 0;
907
908 /* stop event logging; this way events from log_*() will not be added
909 * to the event list while saving the event list */
910 event_cache_status = FALSE;
911
912 event_cache_iterate(pdata) {
913 struct tile *ptile = index_to_tile(&(wld.map), pdata->packet.tile);
914 char target[MAX_NUM_PLAYER_SLOTS + 1];
915 char *p;
916 int tile_x = -1, tile_y = -1;
917
918 if (ptile != NULL) {
919 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
920 }
921
922 secfile_insert_int(file, pdata->packet.turn, "%s.events%d.turn",
923 section, event_count);
924 if (pdata->packet.phase != PHASE_UNKNOWN) {
925 /* Do not save current value of PHASE_UNKNOWN to savegame.
926 * It practically means that "savegame had no phase stored".
927 * Note that the only case where phase might be PHASE_UNKNOWN
928 * may be present is that the event was loaded from previous
929 * savegame created by a freeciv version that did not store event
930 * phases. */
931 secfile_insert_int(file, pdata->packet.phase, "%s.events%d.phase",
932 section, event_count);
933 }
934 secfile_insert_int(file, pdata->timestamp, "%s.events%d.timestamp",
935 section, event_count);
936 secfile_insert_int(file, tile_x, "%s.events%d.x", section, event_count);
937 secfile_insert_int(file, tile_y, "%s.events%d.y", section, event_count);
938 secfile_insert_str(file, server_states_name(pdata->server_state),
939 "%s.events%d.server_state", section, event_count);
940 secfile_insert_str(file, event_type_name(pdata->packet.event),
941 "%s.events%d.event", section, event_count);
942 switch (pdata->target_type) {
943 case ECT_ALL:
944 fc_snprintf(target, sizeof(target), "All");
945 break;
946 case ECT_PLAYERS:
947 p = target;
948 players_iterate(pplayer) {
949 *p++ = (BV_ISSET(pdata->target, player_index(pplayer)) ? '1' : '0');
950 } players_iterate_end;
951 *p = '\0';
952 break;
953 case ECT_GLOBAL_OBSERVERS:
954 fc_snprintf(target, sizeof(target), "Global Observers");
955 break;
956 }
957 secfile_insert_str(file, target, "%s.events%d.target",
958 section, event_count);
959 secfile_insert_str(file, pdata->packet.message, "%s.events%d.message",
960 section, event_count);
961
962 log_verbose("Event %4d saved.", event_count);
963
964 event_count++;
965 } event_cache_iterate_end;
966
967 /* save the number of events in the event cache */
968 secfile_insert_int(file, event_count, "%s.count", section);
969
970 log_verbose("Events saved: %d.", event_count);
971
972 event_cache_status = TRUE;
973}
974
975/**********************************************************************/
978 void event_cache_phases_invalidate(void)
979{
980 event_cache_iterate(pdata) {
981 if (pdata->packet.phase >= 0) {
982 pdata->packet.phase = PHASE_INVALIDATED;
983 }
984 } event_cache_iterate_end;
985}
str
#define str
Definition astring.c:76
bitvector.h
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_ISSET_ANY
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
conn_get_player
struct player * conn_get_player(const struct connection *pconn)
Definition connection.c:760
conn_is_global_observer
bool conn_is_global_observer(const struct connection *pconn)
Definition connection.c:750
connection.h
conn_list_iterate
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
conn_list_iterate_end
#define conn_list_iterate_end
Definition connection.h:115
event
enum event_type event
Definition events.c:81
events.h
PHASE_INVALIDATED
#define PHASE_INVALIDATED
Definition fc_types.h:885
MAX_NUM_PLAYER_SLOTS
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
PHASE_UNKNOWN
#define PHASE_UNKNOWN
Definition fc_types.h:887
capitalized_string
char * capitalized_string(const char *str)
Definition fcintl.c:66
is_capitalization_enabled
bool is_capitalization_enabled(void)
Definition fcintl.c:101
free_capitalized
void free_capitalized(char *str)
Definition fcintl.c:85
featured_text_apply_tag
size_t featured_text_apply_tag(const char *text_source, char *featured_text, size_t featured_text_len, enum text_tag_type tag_type, ft_offset_t start_offset, ft_offset_t stop_offset,...)
Definition featured_text.c:993
featured_text.h
FT_OFFSET_UNSET
#define FT_OFFSET_UNSET
Definition featured_text.h:104
ft_color_requested
static bool ft_color_requested(const struct ft_color color)
Definition featured_text.h:160
TTT_COLOR
@ TTT_COLOR
Definition featured_text.h:125
game
struct civ_game game
Definition game.c:57
wld
struct world wld
Definition game.c:58
game.h
GAME_MAX_EVENT_CACHE_MAX_SIZE
#define GAME_MAX_EVENT_CACHE_MAX_SIZE
Definition game.h:688
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
is_normal_map_pos
bool is_normal_map_pos(int x, int y)
Definition map.c:961
index_to_tile
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
map_pos_to_index
static int map_pos_to_index(struct civ_map *nmap, int map_x, int map_y)
Definition map.h:677
index_to_map_pos
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:227
map_is_known
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:886
maphand.h
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
notify_research
void notify_research(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:394
event_cache_iterate
#define event_cache_iterate(pdata)
Definition notify.c:488
notify_player
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:292
event_cache_remove_old
void event_cache_remove_old(void)
Definition notify.c:603
send_pending_events
void send_pending_events(struct connection *pconn, bool include_public)
Definition notify.c:754
package_chat_msg
void package_chat_msg(struct packet_chat_msg *packet, const struct connection *sender, const struct ft_color color, const char *format,...)
Definition notify.c:123
event_cache_add_for_players
void event_cache_add_for_players(const struct packet_chat_msg *packet, struct event_cache_players *players)
Definition notify.c:672
event_cache_player_add
struct event_cache_players * event_cache_player_add(struct event_cache_players *players, const struct player *pplayer)
Definition notify.c:704
event_cache_load
void event_cache_load(struct section_file *file, const char *section)
Definition notify.c:784
notify_research_embassies
void notify_research_embassies(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:434
event_cache_data_new
static struct event_cache_data * event_cache_data_new(const struct packet_chat_msg *packet, time_t timestamp, enum server_states server_status, enum event_cache_target target_type, struct event_cache_players *players)
Definition notify.c:516
notify_conn
void notify_conn(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:239
vpackage_event
void vpackage_event(struct packet_chat_msg *packet, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format, va_list vargs)
Definition notify.c:147
event_cache_target
event_cache_target
Definition notify.c:470
ECT_ALL
@ ECT_ALL
Definition notify.c:471
ECT_PLAYERS
@ ECT_PLAYERS
Definition notify.c:472
ECT_GLOBAL_OBSERVERS
@ ECT_GLOBAL_OBSERVERS
Definition notify.c:473
notify_team
void notify_team(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:346
notify_embassies
void notify_embassies(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:316
notify_conn_packet
static void notify_conn_packet(struct conn_list *dest, const struct packet_chat_msg *packet, bool early)
Definition notify.c:193
package_event
void package_event(struct packet_chat_msg *packet, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:168
event_cache_clear
void event_cache_clear(void)
Definition notify.c:595
event_cache_free
void event_cache_free(void)
Definition notify.c:583
event_cache_phases_invalidate
void event_cache_phases_invalidate(void)
Definition notify.c:978
notify_conn_early
void notify_conn_early(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:264
event_cache_add_for_global_observers
void event_cache_add_for_global_observers(const struct packet_chat_msg *packet)
Definition notify.c:631
package_event_full
static void package_event_full(struct packet_chat_msg *packet, const struct tile *ptile, enum event_type event, const struct connection *pconn, const struct ft_color color, const char *format, va_list vargs)
Definition notify.c:55
event_cache_match
static bool event_cache_match(const struct event_cache_data *pdata, const struct player *pplayer, bool is_global_observer, bool include_public)
Definition notify.c:722
event_cache_data_free
static void event_cache_data_free(struct event_cache_data *data)
Definition notify.c:506
event_cache_add_for_player
void event_cache_add_for_player(const struct packet_chat_msg *packet, const struct player *pplayer)
Definition notify.c:646
vpackage_chat_msg
void vpackage_chat_msg(struct packet_chat_msg *packet, const struct connection *sender, const struct ft_color color, const char *format, va_list vargs)
Definition notify.c:104
event_cache_iterate_end
#define event_cache_iterate_end
Definition notify.c:490
event_cache_status
static bool event_cache_status
Definition notify.c:501
event_cache_add_for_all
void event_cache_add_for_all(const struct packet_chat_msg *packet)
Definition notify.c:620
event_cache_save
void event_cache_save(struct section_file *file, const char *section)
Definition notify.c:904
event_cache
static struct event_cache_data_list * event_cache
Definition notify.c:497
event_cache_init
void event_cache_init(void)
Definition notify.c:571
notify.h
packets.h
MAX_LEN_MSG
#define MAX_LEN_MSG
Definition packets.h:43
lsend_packet_chat_msg
void lsend_packet_chat_msg(struct conn_list *dest, const struct packet_chat_msg *packet)
Definition packets_gen.c:10787
send_packet_chat_msg
int send_packet_chat_msg(struct connection *pc, const struct packet_chat_msg *packet)
Definition packets_gen.c:10775
send_packet_early_chat_msg
int send_packet_early_chat_msg(struct connection *pc, const struct packet_early_chat_msg *packet)
Definition packets_gen.c:11101
players_on_same_team
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
team_has_embassy
bool team_has_embassy(const struct team *pteam, const struct player *tgt_player)
Definition player.c:214
player_index
int player_index(const struct player *pplayer)
Definition player.c:820
player.h
players_iterate_end
#define players_iterate_end
Definition player.h:535
players_iterate
#define players_iterate(_pplayer)
Definition player.h:530
registry.h
secfile_lookup_str
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:2112
secfile_lookup_int_default
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Definition registry_ini.c:1937
secfile_insert_int
#define secfile_insert_int(secfile, value, path,...)
Definition registry_ini.h:116
secfile_insert_str
#define secfile_insert_str(secfile, string, path,...)
Definition registry_ini.h:170
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:126
research.h
research_players_iterate
#define research_players_iterate(_presearch, _pplayer)
Definition research.h:168
research_players_iterate_end
#define research_players_iterate_end
Definition research.h:172
speclist.h
server_state
enum server_states server_state(void)
Definition srv_main.c:323
srv_main.h
civ_game::chat
bool chat
Definition game.h:249
civ_game::max_size
int max_size
Definition game.h:248
civ_game::server
struct civ_game::@30::@34 server
civ_game::event_cache
struct civ_game::@30::@34::@35 event_cache
civ_game::est_connections
struct conn_list * est_connections
Definition game.h:97
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::turns
int turns
Definition game.h:247
color
Definition colors.h:20
connection
Definition connection.h:141
connection::self
struct conn_list * self
Definition connection.h:168
connection::id
int id
Definition connection.h:142
event_cache_data
Definition notify.c:477
event_cache_data::server_state
enum server_states server_state
Definition notify.c:480
event_cache_data::packet
struct packet_chat_msg packet
Definition notify.c:478
event_cache_data::target
bv_player target
Definition notify.c:482
event_cache_data::timestamp
time_t timestamp
Definition notify.c:479
event_cache_data::target_type
enum event_cache_target target_type
Definition notify.c:481
event_cache_players
Definition notify.c:492
event_cache_players::vector
bv_player vector
Definition notify.c:493
ft_color
Definition featured_text.h:141
packet_chat_msg
Definition packets_gen.h:287
packet_chat_msg::phase
int phase
Definition packets_gen.h:292
packet_chat_msg::message
char message[MAX_LEN_MSG]
Definition packets_gen.h:288
packet_chat_msg::conn_id
int conn_id
Definition packets_gen.h:293
packet_chat_msg::event
enum event_type event
Definition packets_gen.h:290
packet_chat_msg::turn
int turn
Definition packets_gen.h:291
packet_chat_msg::tile
int tile
Definition packets_gen.h:289
packet_early_chat_msg
Definition packets_gen.h:296
packet_game_info::is_new_game
bool is_new_game
Definition packets_gen.h:186
packet_game_info::turn
int turn
Definition packets_gen.h:241
packet_game_info::phase
int phase
Definition packets_gen.h:206
player
Definition player.h:249
player::connections
struct conn_list * connections
Definition player.h:298
research
Definition research.h:39
section_file
Definition section_file.h:36
section
Definition section_file.h:28
tile
Definition tile.h:49
world::map
struct civ_map map
Definition world_object.h:38
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc_localtime
struct tm * fc_localtime(const time_t *timep, struct tm *result)
Definition support.c:1310
fc_vsnprintf
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:896
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:161
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
tile.h
tile_index
#define tile_index(_pt_)
Definition tile.h:87