Atrinik Client  4.0
server_settings.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <toolkit/string.h>
34 
37 
42 {
43  FILE *fp = server_file_open_name(SERVER_FILE_SETTINGS);
44  if (fp == NULL) {
45  return;
46  }
47 
49  s_settings = ecalloc(1, sizeof(server_settings));
50 
51  char_struct *cur_char = NULL;
52  size_t text_id = 0;
53 
54  char buf[HUGE_BUF * 4];
55  uint64_t linenum = 0;
56 
57  while (fgets(VS(buf), fp) != NULL) {
58  linenum++;
59 
60  char *cp = buf;
61  string_skip_whitespace(cp);
62  string_strip_newline(cp);
63 
64  char *cps[2];
65  if (string_split(cp, cps, arraysize(cps), ' ') < 1) {
66  continue;
67  }
68 
69  const char *key = cps[0], *error_str;
70  char *value = cps[1];
71 
72  if (strcmp(key, "char") == 0) {
73  if (cur_char != NULL) {
74  error_str = "superfluous char attribute";
75  goto error;
76  }
77 
78  s_settings->characters = ereallocz(s_settings->characters,
79  sizeof(*s_settings->characters) *
80  s_settings->num_characters,
81  sizeof(*s_settings->characters) *
82  (s_settings->num_characters + 1));
83  cur_char = &s_settings->characters[s_settings->num_characters];
84  s_settings->num_characters++;
85  cur_char->name = estrdup(value);
86  } else if (string_isempty(value)) {
87  if (strcmp(key, "end") == 0) {
88  if (cur_char == NULL) {
89  error_str = "superfluous end attribute";
90  goto error;
91  }
92 
93  cur_char = NULL;
94  }
95  } else if (cur_char != NULL) {
96  if (strcmp(key, "gender") == 0) {
97  char *cps2[3];
98 
99  if (string_split(value, cps2, arraysize(cps2), ' ') == 3) {
100  int gender_id = gender_to_id(cps2[0]);
101  if (gender_id != -1) {
102  cur_char->gender_archetypes[gender_id] =
103  estrdup(cps2[1]);
104  cur_char->gender_faces[gender_id] = estrdup(cps2[2]);
105  }
106  }
107  } else if (strcmp(key, "desc") == 0) {
108  cur_char->desc = estrdup(value);
109  }
110  } else if (strcmp(key, "level") == 0) {
111  s_settings->max_level = atoi(value);
112  s_settings->level_exp = emalloc(sizeof(*s_settings->level_exp) *
113  (s_settings->max_level + 2));
114 
115  for (uint32_t lev = 0; lev <= s_settings->max_level; lev++) {
116  if (fgets(VS(buf), fp) == NULL) {
117  break;
118  }
119 
120  s_settings->level_exp[lev] = strtoull(buf, NULL, 16);
121  }
122 
123  s_settings->level_exp[s_settings->max_level + 1] = 0;
124  } else if (strcmp(key, "text") == 0) {
125  if (text_id == SERVER_TEXT_MAX) {
126  error_str = "reached maximum amount of text entries";
127  goto error;
128  }
129 
130  s_settings->text[text_id] = estrdup(value);
131  string_newline_to_literal(s_settings->text[text_id]);
132 
133  if (text_id == SERVER_TEXT_PROTECTION_GROUPS ||
134  text_id == SERVER_TEXT_PROTECTION_LETTERS ||
135  text_id == SERVER_TEXT_PROTECTION_FULL ||
136  text_id == SERVER_TEXT_SPELL_PATHS) {
137  char **dst;
138  size_t arraymax;
139  if (text_id == SERVER_TEXT_PROTECTION_GROUPS) {
140  dst = s_settings->protection_groups;
141  arraymax = arraysize(s_settings->protection_groups);
142  } else if (text_id == SERVER_TEXT_PROTECTION_LETTERS) {
143  dst = s_settings->protection_letters;
144  arraymax = arraysize(s_settings->protection_letters);
145  } else if (text_id == SERVER_TEXT_PROTECTION_FULL) {
146  dst = s_settings->protection_full;
147  arraymax = arraysize(s_settings->protection_full);
148  } else if (text_id == SERVER_TEXT_SPELL_PATHS) {
149  dst = s_settings->spell_paths;
150  arraymax = arraysize(s_settings->spell_paths);
151  } else {
152  HARD_ASSERT(false);
153  }
154 
155  size_t i = 0, pos = 0;
156  while (string_get_word(s_settings->text[text_id], &pos, ' ',
157  VS(buf), 0)) {
158  if (i == arraymax) {
159  error_str = "reached maximum array size";
160  goto error;
161  }
162 
163  dst[i++] = estrdup(buf);
164  }
165  }
166 
167  text_id++;
168  }
169 
170  continue;
171 
172 error:
173  LOG(ERROR, "Error parsing %s, line %" PRIu64 ", %s: %s %s",
174  SERVER_FILE_SETTINGS, linenum, error_str, key,
175  value != NULL ? value : "");
176  }
177 
178  for (size_t i = text_id; i < SERVER_TEXT_MAX; i++) {
179  s_settings->text[i] = estrdup("???");
180  }
181 
182  fclose(fp);
183 }
184 
189 {
190  if (s_settings == NULL) {
191  return;
192  }
193 
194  if (s_settings->level_exp != NULL) {
195  efree(s_settings->level_exp);
196  }
197 
198  for (size_t i = 0; i < s_settings->num_characters; i++) {
199  if (s_settings->characters[i].name != NULL) {
200  efree(s_settings->characters[i].name);
201  }
202 
203  if (s_settings->characters[i].desc != NULL) {
204  efree(s_settings->characters[i].desc);
205  }
206 
207  for (size_t gender = 0; gender < GENDER_MAX; gender++) {
208  if (s_settings->characters[i].gender_archetypes[gender] != NULL) {
209  efree(s_settings->characters[i].gender_archetypes[gender]);
210  }
211 
212  if (s_settings->characters[i].gender_faces[gender] != NULL) {
213  efree(s_settings->characters[i].gender_faces[gender]);
214  }
215  }
216  }
217 
218  if (s_settings->characters != NULL) {
219  efree(s_settings->characters);
220  }
221 
222  for (size_t i = 0; i < SERVER_TEXT_MAX; i++) {
223  if (s_settings->text[i] != NULL) {
224  efree(s_settings->text[i]);
225  }
226  }
227 
228  for (size_t i = 0; i < arraysize(s_settings->protection_groups); i++) {
229  if (s_settings->protection_groups[i] != NULL) {
230  efree(s_settings->protection_groups[i]);
231  }
232  }
233 
234  for (size_t i = 0; i < arraysize(s_settings->protection_letters); i++) {
235  if (s_settings->protection_letters[i] != NULL) {
236  efree(s_settings->protection_letters[i]);
237  }
238  }
239 
240  for (size_t i = 0; i < arraysize(s_settings->protection_full); i++) {
241  if (s_settings->protection_full[i] != NULL) {
242  efree(s_settings->protection_full[i]);
243  }
244  }
245 
246  for (size_t i = 0; i < arraysize(s_settings->spell_paths); i++) {
247  if (s_settings->spell_paths[i] != NULL) {
248  efree(s_settings->spell_paths[i]);
249  }
250  }
251 
252  efree(s_settings);
253  s_settings = NULL;
254 }
void server_settings_deinit(void)
char * text[SERVER_TEXT_MAX]
#define GENDER_MAX
Definition: player.h:46
server_settings * s_settings
char * protection_full[20]
char * protection_letters[20]
FILE * server_file_open_name(const char *name)
Definition: server_files.c:437
char * protection_groups[5]
char * spell_paths[SPELL_PATH_NUM]
int gender_to_id(const char *gender)
Definition: player.c:226
char * gender_archetypes[GENDER_MAX]
void server_settings_init(void)
int64_t * level_exp
char * gender_faces[GENDER_MAX]
char_struct * characters