Crossfire Server, Trunk
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 <string.h>
30 
31 #include <string>
32 #include <unordered_map>
33 
34 static int last_hr;
35 
37 struct Region {
38  std::unordered_map<std::string, std::string> bells;
39  std::string fallback;
40 };
41 
43 static std::unordered_map<std::string, Region *> regions;
44 
50 static void load_bells(BufferReader *reader, const char *filename) {
51  Region *current = NULL;
52  char *line;
53  char *split[20];
54 
55  while ((line = bufferreader_next_line(reader))) {
56  if (line[0] == '\0' || line[0] == '#') {
57  continue;
58  }
59  char *space = strchr(line, ' ');
60  if (!space) {
61  LOG(llevError, "Invalid bell line '%s' in %s:%zu\n", line, filename, bufferreader_current_line(reader));
62  continue;
63  }
64  *space = '\0';
65  space++;
66 
67  if (strcmp(line, "region") == 0) {
68  current = new Region();
70  continue;
71  }
72  if (!current) {
73  LOG(llevError, "Missing 'region' in bell file %s\n", filename);
74  continue;
75  }
76  size_t count = split_string(line, split, sizeof(split), ',');
77  for (size_t i = 0; i < count; i++) {
78  if (strcmp(split[i], "*") == 0) {
79  current->fallback = space;
80  } else {
81  current->bells[split[i]] = space;
82  }
83  }
84  }
85 }
86 
90 static void ring_bell(void) {
91 
92  object *pl = first_player ? first_player->ob : NULL;
93  while (pl) {
94  // If the player is on a map, then try to ring the bell
95  if (pl->map) {
96  region *reg = get_region_by_map(pl->map);
97  if (reg) {
98  auto found = regions.find(reg->name);
99  if (found != regions.end()) {
100  const char *god_name = determine_god(pl);
101  auto god = found->second->bells.find(god_name);
102  std::string msg = god == found->second->bells.end() ? found->second->fallback : god->second;
103  auto r = msg.find("%god");
104  if (r != std::string::npos) {
105  msg.replace(r, 4, god_name);
106  }
108  }
109  }
110  }
111 
112  pl = pl->contr->next ? pl->contr->next->ob : NULL;
113  }
114 }
115 
123 static int clock_listener(int *type, ...) {
124  va_list args;
125  int code;
126  timeofday_t tod;
127 
128  va_start(args, type);
129  code = va_arg(args, int);
130 
131  switch (code) {
132  case EVENT_CLOCK:
133  get_tod(&tod);
134  if (tod.hour != last_hr) {
135  last_hr = tod.hour;
136  ring_bell();
137  }
138  break;
139  }
140 
141  va_end(args);
142 
143  return 0;
144 }
145 
147 
153  timeofday_t tod;
154  get_tod(&tod);
155  last_hr = tod.hour;
157 
158  settings->add_hook(".bells", load_bells);
159 
160  /* Disable the plugin in case it's still there */
161  settings->disabled_plugins.push_back(strdup("cfcitybell"));
162 }
163 
166  for (auto reg : regions) {
167  delete reg.second;
168  }
169  all_regions.clear();
170 }
171 
ring_bell
static void ring_bell(void)
Definition: cfcitybell.cpp:90
global.h
line
Install Bug reporting Credits so make sure you have version or later There are files involved in the automatic convert convertall and filelist py GuildList has the list of guilds for the server GuildLocations is what is used by the install script for setting up the maps It has columns in the first is the name of the no spaces The second is the region of the the third is the destination folder for the the fourth is the exit the fifth and sixth are the x and y coords within the exit the seventh eighth and ninth are the exit location for the storage hall If field seven is then it uses the same exit map as for the guild hall itself filelist py has a list of which files to process for each guild hall convert py takes all the files in filelist py and customises them to the specific guild then outputs them into a in the same order that they are listed in GuildLocations convertall py reads the lines from GuildLocations and runs line by line
Definition: README.txt:12
first_player
player * first_player
Definition: init.cpp:106
settings
struct Settings settings
Definition: init.cpp:139
Region::fallback
std::string fallback
Definition: cfcitybell.cpp:39
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Definition: bufferreader.cpp:140
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
Settings
Definition: global.h:240
player::ob
object * ob
Definition: player.h:177
timeofday_t
Definition: tod.h:38
get_tod
void get_tod(timeofday_t *tod)
Definition: time.cpp:215
region::name
char * name
Definition: map.h:274
Region::bells
std::unordered_map< std::string, std::string > bells
Definition: cfcitybell.cpp:38
last_hr
static int last_hr
Definition: cfcitybell.cpp:34
npc_dialog.filename
filename
Definition: npc_dialog.py:99
MSG_TYPE_MISC
#define MSG_TYPE_MISC
Definition: newclient.h:402
NDI_ORANGE
#define NDI_ORANGE
Definition: newclient.h:235
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)
Definition: events.cpp:16
space
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As consult the README file to find out how to get in touch with helpful people via mailing and more History the communications plan was set to be a text based system It was up to the server and client to parse these messages and determine what to do These messages were assumed to be line per message At a reasonably early stage of Eric Anderson wrote a then the data itself you could send many data and after the other end could decode these commands This works fairly but I think the creation of numerous sub packets has some performance hit the eutl was not especially well so writing a client for a different platform became more Eric left to work on other products shortly after writing his which didn t really leave anyone with a full understanding of the socket code I have decided to remove the eutl dependency At least one advantage is that having this network related code directly in the client and server makes error handling a bit easier cleaner Packet Format the outside packet method the byte size for the size information is not included here Eutl originally used bytes for the size to bytes seems it makes a least some sense The actual data is something of the nature of the commands listed below It is a text followed by possible other data The remaining data can be binary it is up to the client and server to decode what it sent The commands as described below is just the data portion of the packet If writing a new remember that you must take into account the size of the packet There is no termination of other than knowing how long it should be For most everything that is sent is text This is more or less how things worked under except it packed the ints into bytes in a known order In some we handle ints as in they are sent as binary information How any command handles it is detailed below in the command description The S and C represent the direction of the we use MSB as well as any ints or shorts that get sent inside the packets All packets are defined to have at least one word of followed by a space
Definition: protocol.txt:85
determine_god
const char * determine_god(object *op)
Definition: gods.cpp:55
EVENT_CLOCK
#define EVENT_CLOCK
Definition: events.h:40
make_face_from_files.args
args
Definition: make_face_from_files.py:37
events_unregister_global_handler
void events_unregister_global_handler(int eventcode, event_registration id)
Definition: events.cpp:23
navar-midane_pickup.msg
list msg
Definition: navar-midane_pickup.py:13
Settings::add_hook
void add_hook(const char *name, collectorHook hook)
Definition: global.h:339
disinfect.count
int count
Definition: disinfect.py:7
sproto.h
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:409
cfcitybell_init
void cfcitybell_init(Settings *settings)
Definition: cfcitybell.cpp:152
Settings::disabled_plugins
std::vector< char * > disabled_plugins
Definition: global.h:326
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
region
Definition: map.h:273
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
all_regions
std::vector< region * > all_regions
Definition: init.cpp:108
event_registration
unsigned long event_registration
Definition: events.h:69
BufferReader
Definition: bufferreader.cpp:21
timeofday_t::hour
int hour
Definition: tod.h:43
cfcitybell_close
void cfcitybell_close()
Definition: cfcitybell.cpp:164
regions
static std::unordered_map< std::string, Region * > regions
Definition: cfcitybell.cpp:43
split_string
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Definition: utils.cpp:473
global_handler
static event_registration global_handler
Definition: cfcitybell.cpp:146
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.cpp:72
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:2608
Region
Definition: cfcitybell.cpp:37
replace.current
current
Definition: replace.py:64
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
clock_listener
static int clock_listener(int *type,...)
Definition: cfcitybell.cpp:123
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
object.h
load_bells
static void load_bells(BufferReader *reader, const char *filename)
Definition: cfcitybell.cpp:50
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102