Crossfire Server, Trunk  1.75.0
cfcitybell.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2021 The Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
26 #include "global.h"
27 #include "object.h"
28 #include "sproto.h"
29 #include "server.h"
30 #include "assets.h"
31 
32 #include <string.h>
33 #include <unordered_map>
34 
35 static int last_hr;
36 
38 struct Region {
39  std::unordered_map<std::string, std::string> bells;
40  std::string fallback;
41 };
42 
44 static std::unordered_map<std::string, Region *> regions;
45 
51 static void load_bells(BufferReader *reader, const char *filename) {
52  Region *current = NULL;
53  char *line;
54  char *split[20];
55 
56  while ((line = bufferreader_next_line(reader))) {
57  if (line[0] == '\0' || line[0] == '#') {
58  continue;
59  }
60  char *space = strchr(line, ' ');
61  if (!space) {
62  LOG(llevError, "Invalid bell line '%s' in %s:%zu\n", line, filename, bufferreader_current_line(reader));
63  continue;
64  }
65  *space = '\0';
66  space++;
67 
68  if (strcmp(line, "region") == 0) {
69  current = new Region();
70  regions[space] = current;
71  continue;
72  }
73  if (!current) {
74  LOG(llevError, "Missing 'region' in bell file %s\n", filename);
75  continue;
76  }
77  size_t count = split_string(line, split, sizeof(split), ',');
78  for (size_t i = 0; i < count; i++) {
79  if (strcmp(split[i], "*") == 0) {
80  current->fallback = space;
81  } else {
82  current->bells[split[i]] = space;
83  }
84  }
85  }
86 }
87 
91 static void ring_bell(void) {
92 
93  object *pl = first_player ? first_player->ob : NULL;
94  while (pl) {
95  // If the player is on a map, then try to ring the bell
96  if (pl->map) {
97  region *reg = get_region_by_map(pl->map);
98  if (reg) {
99  auto found = regions.find(reg->name);
100  if (found != regions.end()) {
101  const char *god_name = determine_god(pl);
102  auto god = found->second->bells.find(god_name);
103  std::string msg = god == found->second->bells.end() ? found->second->fallback : god->second;
104  auto r = msg.find("%god");
105  if (r != std::string::npos) {
106  msg.replace(r, 4, god_name);
107  }
109  }
110  }
111  }
112 
113  pl = pl->contr->next ? pl->contr->next->ob : NULL;
114  }
115 }
116 
124 static int clock_listener(int *type, ...) {
125  va_list args;
126  int code;
127  timeofday_t tod;
128 
129  va_start(args, type);
130  code = va_arg(args, int);
131 
132  switch (code) {
133  case EVENT_CLOCK:
134  get_tod(&tod);
135  if (tod.hour != last_hr) {
136  last_hr = tod.hour;
137  ring_bell();
138  }
139  break;
140  }
141 
142  va_end(args);
143 
144  return 0;
145 }
146 
148 
154  timeofday_t tod;
155  get_tod(&tod);
156  last_hr = tod.hour;
158 
160 
161  /* Disable the plugin in case it's still there */
162  serverSettings->disabled_plugins.push_back(strdup("cfcitybell"));
163 }
164 
167  for (auto reg : regions) {
168  delete reg.second;
169  }
170  all_regions.clear();
171 }
172 
ring_bell
static void ring_bell(void)
Ring the city bells for each player.
Definition: cfcitybell.cpp:91
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:106
global.h
first_player
player * first_player
First player.
Definition: init.cpp:106
Region::fallback
std::string fallback
Message if the god's name is not in Region::bells.
Definition: cfcitybell.cpp:40
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
Definition: bufferreader.cpp:140
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
player::ob
object * ob
The object representing the player.
Definition: player.h:177
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
timeofday_t
Represents the ingame time.
Definition: tod.h:38
Region
One region with bells.
Definition: cfcitybell.cpp:38
get_tod
void get_tod(timeofday_t *tod)
Computes the ingame time of the day.
Definition: time.cpp:219
region::name
char * name
Shortend name of the region as maps refer to it.
Definition: map.h:275
Region::bells
std::unordered_map< std::string, std::string > bells
Map between a god's name and the message to display.
Definition: cfcitybell.cpp:39
last_hr
static int last_hr
Definition: cfcitybell.cpp:35
MSG_TYPE_MISC
#define MSG_TYPE_MISC
Messages that don't go elsewhere.
Definition: newclient.h:417
NDI_ORANGE
#define NDI_ORANGE
Definition: newclient.h:250
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
events_register_global_handler
event_registration events_register_global_handler(int eventcode, f_plug_event hook)
Register a global event handler.
Definition: events.cpp:19
ServerSettings::disabled_plugins
std::vector< char * > disabled_plugins
List of disabled plugins, 'All' means all.
Definition: server.h:16
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
determine_god
const char * determine_god(object *op)
Determines if op worships a god.
Definition: gods.cpp:55
assets_add_collector_hook
void assets_add_collector_hook(const char *name, collectorHook hook)
Definition: assets.cpp:552
events_unregister_global_handler
void events_unregister_global_handler(int eventcode, event_registration id)
Remove a global event handler.
Definition: events.cpp:26
split_string
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Splits a string delimited by passed in sep value into characters into an array of strings.
Definition: utils.cpp:473
cfcitybell_init
void cfcitybell_init(Settings *, ServerSettings *serverSettings)
Citybells module initialisation.
Definition: cfcitybell.cpp:153
EVENT_CLOCK
#define EVENT_CLOCK
Global time event.
Definition: events.h:53
sproto.h
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:424
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
Settings
Server settings.
Definition: global.h:241
region
This is a game region.
Definition: map.h:274
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
all_regions
std::vector< region * > all_regions
Definition: init.cpp:108
event_registration
unsigned long event_registration
Registration identifier type.
Definition: events.h:84
serverSettings
ServerSettings serverSettings
Definition: init.cpp:42
ServerSettings
Definition: server.h:15
timeofday_t::hour
int hour
Definition: tod.h:43
assets.h
cfcitybell_close
void cfcitybell_close()
Definition: cfcitybell.cpp:165
regions
static std::unordered_map< std::string, Region * > regions
All defined regions.
Definition: cfcitybell.cpp:44
global_handler
static event_registration global_handler
Definition: cfcitybell.cpp:147
get_region_by_map
region * get_region_by_map(mapstruct *m)
Gets a region from a map.
Definition: region.cpp:71
code
Crossfire Architecture the general intention is to enhance the enjoyability and playability of CF In this code
Definition: arch-handbook.txt:14
split
static std::vector< std::string > split(const std::string &field, const std::string &by)
Definition: mapper.cpp:2734
server.h
BufferReader
Definition: bufferreader.cpp:21
clock_listener
static int clock_listener(int *type,...)
Global event handling, only uses EVENT_CLOCK.
Definition: cfcitybell.cpp:124
object.h
load_bells
static void load_bells(BufferReader *reader, const char *filename)
Load a .bells file.
Definition: cfcitybell.cpp:51
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:102