Atrinik Server  4.0
commands.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 #include <player.h>
35 #include <object.h>
36 #include <toolkit/path.h>
37 
38 static command_struct *commands;
39 
44 
46 static void commands_permissions_read(const char *path);
47 
48 TOOLKIT_API(DEPENDS(path), DEPENDS(string));
49 
50 TOOLKIT_INIT_FUNC(commands)
51 {
52  commands = NULL;
53  permission_groups = NULL;
54 
55  commands_permissions_read("permissions.cfg");
56 
57  if (path_exists("permissions-custom.cfg")) {
58  commands_permissions_read("permissions-custom.cfg");
59  }
60 
61  /* [operator] */
62  commands_add(COMMAND(arrest), 0.0, COMMAND_PERMISSION);
63  commands_add(COMMAND(ban), 0.0, COMMAND_PERMISSION);
64  commands_add(COMMAND(config), 0.0, COMMAND_PERMISSION);
65  commands_add(COMMAND(follow), 0.0, COMMAND_PERMISSION);
66  commands_add(COMMAND(freeze), 0.0, COMMAND_PERMISSION);
67  commands_add(COMMAND(kick), 0.0, COMMAND_PERMISSION);
68  commands_add(COMMAND(memfree), 0.0, COMMAND_PERMISSION);
69  commands_add(COMMAND(memleak), 0.0, COMMAND_PERMISSION);
70  commands_add(COMMAND(mod_chat), 0.0, COMMAND_PERMISSION);
71  commands_add(COMMAND(no_chat), 0.0, COMMAND_PERMISSION);
72  commands_add(COMMAND(opsay), 0.0, COMMAND_PERMISSION);
73  commands_add(COMMAND(password), 0.0, COMMAND_PERMISSION);
74  commands_add(COMMAND(resetmap), 0.0, COMMAND_PERMISSION);
75  commands_add(COMMAND(resetmaps), 0.0, COMMAND_PERMISSION);
76  commands_add(COMMAND(server_chat), 0.0, COMMAND_PERMISSION);
77  commands_add(COMMAND(settime), 0.0, COMMAND_PERMISSION);
78  commands_add(COMMAND(shutdown), 0.0, COMMAND_PERMISSION);
79  commands_add(COMMAND(stats), 0.0, COMMAND_PERMISSION);
80  commands_add(COMMAND(tcl), 0.0, COMMAND_PERMISSION);
81  commands_add(COMMAND(tgm), 0.0, COMMAND_PERMISSION);
82  commands_add(COMMAND(tli), 0.0, COMMAND_PERMISSION);
83  commands_add(COMMAND(tls), 0.0, COMMAND_PERMISSION);
84  commands_add(COMMAND(tp), 0.0, COMMAND_PERMISSION);
85  commands_add(COMMAND(tphere), 0.0, COMMAND_PERMISSION);
86  commands_add(COMMAND(tsi), 0.0, COMMAND_PERMISSION);
87 
88  /* [player] */
89  commands_add(COMMAND(afk), 1.0, 0);
90  commands_add(COMMAND(apply), 1.0, 0);
91  commands_add(COMMAND(chat), 1.0, 0);
92  commands_add(COMMAND(drop), 1.0, 0);
93  commands_add(COMMAND(gsay), 1.0, 0);
94  commands_add(COMMAND(hiscore), 2.0, 0);
95  commands_add(COMMAND(left), 1.0, 0);
96  commands_add(COMMAND(me), 1.0, 0);
97  commands_add(COMMAND(motd), 1.0, 0);
98  commands_add(COMMAND(my), 1.0, 0);
99  commands_add(COMMAND(party), 1.0, 0);
100  commands_add(COMMAND(push), 1.0, 0);
101  commands_add(COMMAND(rename), 1.0, 0);
102  commands_add(COMMAND(reply), 1.0, 0);
103  commands_add(COMMAND(right), 1.0, 0);
104  commands_add(COMMAND(say), 1.0, 0);
105  commands_add(COMMAND(statistics), 1.0, 0);
106  commands_add(COMMAND(take), 1.0, 0);
107  commands_add(COMMAND(tell), 1.0, 0);
108  commands_add(COMMAND(time), 1.0, 0);
109  commands_add(COMMAND(version), 1.0, 0);
110  commands_add(COMMAND(whereami), 1.0, 0);
111  commands_add(COMMAND(who), 1.0, 0);
112 }
113 TOOLKIT_INIT_FUNC_FINISH
114 
115 TOOLKIT_DEINIT_FUNC(commands)
116 {
117  command_struct *curr, *tmp;
118  permission_group_struct *curr2, *tmp2;
119 
120  HASH_ITER(hh, commands, curr, tmp)
121  {
122  HASH_DEL(commands, curr);
123  efree(curr->name);
124  efree(curr);
125  }
126 
127  HASH_ITER(hh, permission_groups, curr2, tmp2)
128  {
129  HASH_DEL(permission_groups, curr2);
131  }
132 }
133 TOOLKIT_DEINIT_FUNC_FINISH
134 
141 {
142  size_t i;
143 
144  efree(tmp->name);
145 
146  for (i = 0; i < tmp->cmd_permissions_num; i++) {
147  efree(tmp->cmd_permissions[i]);
148  }
149 
150  if (tmp->cmd_permissions) {
151  efree(tmp->cmd_permissions);
152  }
153 
154  efree(tmp);
155 }
156 
164 {
166 
167  HASH_FIND(hh, permission_groups, tmp->name, strlen(tmp->name), curr);
168 
169  /* If it already exists, remove it and free it. */
170  if (curr) {
171  HASH_DEL(permission_groups, curr);
173  }
174 
175  HASH_ADD_KEYPTR(hh, permission_groups, tmp->name, strlen(tmp->name), tmp);
176 }
177 
183 static void commands_permissions_read(const char *path)
184 {
185  FILE *fp;
186  char buf[MAX_BUF], *end;
188 
189  fp = fopen(path, "r");
190 
191  if (!fp) {
192  LOG(BUG, "Could not open %s for reading.", path);
193  return;
194  }
195 
196  tmp = NULL;
197 
198  while (fgets(buf, sizeof(buf), fp)) {
199  if (*buf == '\n' || *buf == '#') {
200  continue;
201  }
202 
203  end = strchr(buf, '\n');
204 
205  if (end) {
206  *end = '\0';
207  }
208 
209  if (string_startswith(buf, "[") && string_endswith(buf, "]")) {
210  if (tmp) {
212  }
213 
214  tmp = ecalloc(1, sizeof(*tmp));
215  tmp->name = estrdup(buf);
216  } else if (tmp) {
217  char *cps[2];
218 
219  if (string_split(buf, cps, arraysize(cps), '=') == 2) {
220  string_whitespace_trim(cps[0]);
221  string_whitespace_trim(cps[1]);
222 
223  if (strcmp(cps[0], "cmd") == 0) {
224  tmp->cmd_permissions = erealloc(tmp->cmd_permissions, sizeof(*tmp->cmd_permissions) * (tmp->cmd_permissions_num + 1));
225  tmp->cmd_permissions[tmp->cmd_permissions_num] = estrdup(cps[1]);
226  tmp->cmd_permissions_num++;
227  }
228  }
229  }
230  }
231 
232  if (tmp) {
234  }
235 
236  fclose(fp);
237 }
238 
239 void commands_add(const char *name, command_func handle_func, double delay, uint64_t flags)
240 {
241  command_struct *command;
242 
243  TOOLKIT_PROTECT();
244 
245  command = emalloc(sizeof(*command));
246  command->name = estrdup(name);
247  command->handle_func = handle_func;
248  command->delay = delay;
249  command->flags = flags;
250 
251  HASH_ADD_KEYPTR(hh, commands, command->name, strlen(command->name), command);
252 }
253 
254 static int commands_check_permission_group(const char *name, size_t len, const char *command)
255 {
256  size_t i;
258 
259  HASH_FIND(hh, permission_groups, name, len, tmp);
260 
261  if (!tmp) {
262  return 0;
263  }
264 
265  for (i = 0; i < tmp->cmd_permissions_num; i++) {
266  if (strcmp(tmp->cmd_permissions[i], "*") == 0 || strcmp(tmp->cmd_permissions[i], command) == 0) {
267  return 1;
268  }
269  }
270 
271  return 0;
272 }
273 
274 int commands_check_permission(player *pl, const char *command)
275 {
276  int i;
277 
278  TOOLKIT_PROTECT();
279 
280  if (*settings.default_permission_groups != '\0') {
281  char *curr, *next;
282 
283  for (curr = settings.default_permission_groups; (curr && (next = strchr(curr, ','))) || curr; curr = next ? next + 1 : NULL) {
284  if (commands_check_permission_group(curr, next ? (size_t) (next - curr) : strlen(curr), command)) {
285  return 1;
286  }
287  }
288  }
289 
290  for (i = 0; i < pl->num_cmd_permissions; i++) {
291  if (!pl->cmd_permissions[i]) {
292  continue;
293  }
294 
295  if (string_startswith(pl->cmd_permissions[i], "[") && string_endswith(pl->cmd_permissions[i], "]") && commands_check_permission_group(pl->cmd_permissions[i], strlen(pl->cmd_permissions[i]), command)) {
296  return 1;
297  } else if (strcmp(pl->cmd_permissions[i], command) == 0) {
298  return 1;
299  }
300  }
301 
302  return 0;
303 }
304 
305 void commands_handle(object *op, char *cmd)
306 {
307  TOOLKIT_PROTECT();
308 
309  if (cmd[0] == '/' && cmd[1] != '\0') {
310  char *cp, *params;
311  command_struct *command;
312 
313  cmd++;
314  cp = strchr(cmd, ' ');
315 
316  if (cp) {
317  cmd[cp - cmd] = '\0';
318  params = cp + 1;
319 
320  if (*params == '\0') {
321  params = NULL;
322  }
323  } else {
324  params = NULL;
325  }
326 
327  HASH_FIND(hh, commands, cmd, strlen(cmd), command);
328 
329  if (command) {
330  if (command->flags & COMMAND_PERMISSION && !commands_check_permission(CONTR(op), cmd)) {
331  draw_info(COLOR_WHITE, op, "You do not have sufficient permissions for that command.");
332  return;
333  }
334 
335  if (params && !(command->flags & COMMAND_ALLOW_MARKUP)) {
336  string_replace_char(params, "[]", ' ');
337  }
338 
339  op->speed_left -= command->delay;
340  command->handle_func(op, cmd, params);
341  return;
342  }
343  }
344 
345  draw_info_format(COLOR_WHITE, op, "'/%s' is not a valid command.", cmd);
346 }
#define COMMAND_ALLOW_MARKUP
Definition: commands.h:112
double delay
Definition: commands.h:63
static void commands_permission_group_free(permission_group_struct *tmp)
Definition: commands.c:140
static const char *const stats[]
Definition: stats.c:38
#define COMMAND_PERMISSION
Definition: commands.h:108
static void commands_permission_group_add(permission_group_struct *tmp)
Definition: commands.c:163
double speed_left
Definition: object.h:472
void drop(object *op, object *tmp, int no_mevent)
Definition: player.c:2304
char default_permission_groups[MAX_BUF]
Definition: global.h:424
uint64_t flags
Definition: commands.h:68
struct sound_ambient_match * next
Next match rule in a linked list.
Definition: sound_ambient.c:39
size_t cmd_permissions_num
Definition: commands.h:93
static permission_group_struct * permission_groups
Definition: commands.c:43
#define COMMAND(__name)
Definition: commands.h:118
TOOLKIT_INIT_FUNC(http_server)
Definition: http_server.c:85
int num_cmd_permissions
Definition: player.h:254
static void commands_permissions_read(const char *path)
Definition: commands.c:183
struct settings_struct settings
Definition: init.c:55
Definition: ban.c:49
void version(object *op)
Definition: main.c:84
TOOLKIT_INIT_FUNC_FINISH TOOLKIT_DEINIT_FUNC(http_server)
Definition: http_server.c:124
void(* command_func)(object *op, const char *command, char *params)
Definition: commands.h:44
char ** cmd_permissions
Definition: player.h:168
command_func handle_func
Definition: commands.h:58
char * name
Definition: commands.h:53