Crossfire Server, Trunk
languages.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
14 #include "global.h"
15 
16 #include <errno.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <map>
20 #include <memory>
21 
25 struct i18n_file {
28  std::map<sstring, sstring> messages;
29 };
30 
32 static std::vector<i18n_file *> i18n_files;
34 static i18n_file *i18n_default = nullptr;
35 
42 const char *i18n(const object *who, const char *code) {
43  if (!who || !who->contr || !who->contr->language)
44  return code;
45 
46  sstring scode = add_string(code);
47  i18n_file *file = static_cast<i18n_file *>(who->contr->language);
48  auto found = file->messages.find(scode);
49  free_string(scode);
50 
51  return found == file->messages.end() ? code : found->second;
52 }
53 
60  for (auto language : i18n_files) {
61  if (strcmp(code, language->code) == 0)
62  return language;
63  }
64 
65  return nullptr;
66 }
67 
75  if (found)
76  return found;
77  return i18n_default;
78 }
79 
86  if (!language)
87  return i18n_default->code;
88  return static_cast<i18n_file *>(language)->code;
89 }
90 
95 void i18n_list_languages(object *who) {
96  for (auto language : i18n_files) {
98  "[fixed]%s: %s",
99  language->code,
100  language->name
101  );
102  }
103 }
104 
113 static void convert_newline(char *line) {
114  char *next;
115  char buf[MAX_BUF];
116 
117  while ((next = strstr(line, "\\n")) != NULL) {
118  *next = '\n';
119  *(next+1) = '\0';
120  snprintf(buf, MAX_BUF, "%s%s", line, next+2);
121  strcpy(line, buf);
122  }
123 }
124 
130 void i18n_init(void) {
131  char dirname[MAX_BUF], filename[MAX_BUF*2], *line;
132  BufferReader *br;
133  char *token;
134  DIR *dir;
135  struct dirent *file;
136 
137  snprintf(dirname, sizeof(dirname), "%s/i18n/", settings.datadir);
138 
139  dir = opendir(dirname);
140  if (dir == NULL) {
141  LOG(llevError, "i18n: couldn't open %s\n", dirname);
143  }
144 
145  sstring code = add_string("LN");
146 
147  while ((file = readdir(dir)) != NULL) {
148  if (strncmp(file->d_name, "messages.", 9) != 0)
149  continue;
150 
151  snprintf(filename, sizeof(filename), "%s%s", dirname, file->d_name);
152  br = bufferreader_init_from_file(NULL, filename, "i18n: couldn't open %s: %s\n", llevError);
153  if (!br) {
155  }
156  i18n_file *language = new i18n_file();
157 
158  if (!language) {
159  LOG(llevError, "i18n: couldn't allocate memory!\n");
161  }
162  language->code = add_string(file->d_name + 9);
163  i18n_files.push_back(language);
164 
165  while ((line = bufferreader_next_line(br)) != NULL) {
166  if (line[0] != '#' && line[0] != '\0') {
167 
168  token = strtok(line, "|");
170  sstring scode = add_string(token), smessage;
171  token = strtok(NULL, "|");
172  if (token != NULL) {
174  smessage = add_string(token);
175  } else {
176  smessage = add_refcount(scode);
177  }
178  language->messages[scode] = smessage;
179  }
180  }
182 
183  auto found = language->messages.find(code);
184  if (found == language->messages.end()) {
185  LOG(llevError, "i18n: no language set in %s\n", filename);
187  }
188 
189  language->name = found->second;
190  LOG(llevDebug, "i18n: %zu strings for %s\n",
191  language->messages.size(), language->name);
192 
193  if (strcmp(language->code, "en") == 0)
194  i18n_default = language;
195  }
196  closedir(dir);
197 
198  free_string(code);
199 
200  if (i18n_default == nullptr) {
201  LOG(llevError, "i18n: couldn't find default language (en)\n");
203  }
204 }
205 
209 void i18n_free(void) {
210  for (auto language : i18n_files) {
211  free_string(language->code); /* name is a copy of a message */
212  for (auto message : language->messages) {
213  free_string(message.first);
214  free_string(message.second);
215  }
216  delete language;
217  }
218  i18n_files.clear();
219 }
give.next
def next
Definition: give.py:44
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
i18n_free
void i18n_free(void)
Definition: languages.cpp:209
settings
struct Settings settings
Definition: init.cpp:139
i18n_files
static std::vector< i18n_file * > i18n_files
Definition: languages.cpp:32
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
language_t
void * language_t
Definition: global.h:67
token
Definition: token.py:1
i18n_file::messages
std::map< sstring, sstring > messages
Definition: languages.cpp:28
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
mad_mage_user.file
file
Definition: mad_mage_user.py:15
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
i18n_file::name
sstring name
Definition: languages.cpp:27
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
npc_dialog.filename
filename
Definition: npc_dialog.py:99
buf
StringBuffer * buf
Definition: readable.cpp:1552
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Definition: newclient.h:393
i18n_init
void i18n_init(void)
Definition: languages.cpp:130
autojail.who
who
Definition: autojail.py:3
bufferreader_init_from_file
BufferReader * bufferreader_init_from_file(BufferReader *br, const char *filepath, const char *failureMessage, LogLevel failureLevel)
Definition: bufferreader.cpp:65
opendir
DIR * opendir(const char *)
add_refcount
sstring add_refcount(sstring str)
Definition: shstr.cpp:210
i18n_get_language_code
sstring i18n_get_language_code(language_t language)
Definition: languages.cpp:85
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
readdir
struct dirent * readdir(DIR *)
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
i18n_file
Definition: languages.cpp:25
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:409
MAX_BUF
#define MAX_BUF
Definition: define.h:35
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:570
i18n_get_language_by_code
language_t i18n_get_language_by_code(const char *code)
Definition: languages.cpp:73
BufferReader
Definition: bufferreader.cpp:21
sstring
const typedef char * sstring
Definition: sstring.h:2
i18n_list_languages
void i18n_list_languages(object *who)
Definition: languages.cpp:95
i18n_find_language_by_code
language_t i18n_find_language_by_code(const char *code)
Definition: languages.cpp:59
i18n_file::code
sstring code
Definition: languages.cpp:26
Settings::datadir
const char * datadir
Definition: global.h:248
code
Crossfire Architecture the general intention is to enhance the enjoyability and playability of CF In this code
Definition: arch-handbook.txt:14
closedir
int closedir(DIR *)
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
i18n_default
static i18n_file * i18n_default
Definition: languages.cpp:34
llevDebug
@ llevDebug
Definition: logger.h:13
i18n
const char * i18n(const object *who, const char *code)
Definition: languages.cpp:42
convert_newline
static void convert_newline(char *line)
Definition: languages.cpp:113
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102