Atrinik Client  4.0
menu.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 
30 #include <global.h>
31 #include <toolkit/packet.h>
32 #include <toolkit/string.h>
33 
44 int client_command_check(const char *cmd)
45 {
46  if (cmd_aliases_handle(cmd)) {
47  return 1;
48  } else if (strncasecmp(cmd, "/ready_spell", 12) == 0) {
49  cmd = strchr(cmd, ' ');
50 
51  if (!cmd || *++cmd == '\0') {
52  draw_info(COLOR_RED, "Usage: /ready_spell <spell name>");
53  return 1;
54  } else {
55  object *tmp;
56 
57  for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
58  if (tmp->itype == TYPE_SPELL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
59  if (!(tmp->flags & CS_FLAG_APPLIED)) {
60  client_send_apply(tmp);
61  }
62 
63  return 1;
64  }
65  }
66  }
67 
68  draw_info(COLOR_RED, "Unknown spell.");
69  return 1;
70  } else if (strncasecmp(cmd, "/ready_skill", 12) == 0) {
71  cmd = strchr(cmd, ' ');
72 
73  if (!cmd || *++cmd == '\0') {
74  draw_info(COLOR_RED, "Usage: /ready_skill <skill name>");
75  return 1;
76  } else {
77  object *tmp;
78 
79  for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
80  if (tmp->itype == TYPE_SKILL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
81  if (!(tmp->flags & CS_FLAG_APPLIED)) {
82  client_send_apply(tmp);
83  }
84 
85  return 1;
86  }
87  }
88  }
89 
90  draw_info(COLOR_RED, "Unknown skill.");
91  return 1;
92  } else if (!strncmp(cmd, "/help", 5)) {
93  cmd += 5;
94 
95  if (*cmd == '\0') {
96  help_show("main");
97  } else {
98  help_show(cmd + 1);
99  }
100 
101  return 1;
102  } else if (!strncmp(cmd, "/resetwidgets", 13)) {
103  widgets_reset();
104  return 1;
105  } else if (!strncmp(cmd, "/effect ", 8)) {
106  if (!strcmp(cmd + 8, "none")) {
107  effect_stop();
108  draw_info(COLOR_GREEN, "Stopped effect.");
109  return 1;
110  }
111 
112  if (effect_start(cmd + 8)) {
113  draw_info_format(COLOR_GREEN, "Started effect %s.", cmd + 8);
114  } else {
115  draw_info_format(COLOR_RED, "No such effect %s.", cmd + 8);
116  }
117 
118  return 1;
119  } else if (!strncmp(cmd, "/d_effect ", 10)) {
120  effect_debug(cmd + 10);
121  return 1;
122  } else if (!strncmp(cmd, "/music_pause", 12)) {
124  return 1;
125  } else if (!strncmp(cmd, "/music_resume", 13)) {
127  return 1;
128  } else if (!strncmp(cmd, "/party joinpassword ", 20)) {
129  cmd += 20;
130 
131  if (cpl.partyjoin[0] != '\0') {
132  char buf[MAX_BUF];
133 
134  snprintf(VS(buf), "/party join %s\t%s", cpl.partyjoin, cmd);
135  send_command(buf);
136  }
137 
138  return 1;
139  } else if (!strncmp(cmd, "/invfilter ", 11)) {
140  inventory_filter_set_names(cmd + 11);
141  return 1;
142  } else if (!strncasecmp(cmd, "/screenshot", 11)) {
143  SDL_Surface *surface_save;
144 
145  cmd += 11;
146 
147  if (!strncasecmp(cmd, " map", 4)) {
148  surface_save = cur_widget[MAP_ID]->surface;
149  } else {
150  surface_save = ScreenSurface;
151  }
152 
153  if (!surface_save) {
154  draw_info(COLOR_RED, "No surface to save.");
155  return 1;
156  }
157 
158  screenshot_create(surface_save);
159  return 1;
160  } else if (!strncasecmp(cmd, "/console-load ", 14)) {
161  FILE *fp;
162  char path[HUGE_BUF], buf[HUGE_BUF * 4], *cp;
163  StringBuffer *sb;
164 
165  cmd += 14;
166 
167  snprintf(path, sizeof(path), "%s/.atrinik/console/%s", get_config_dir(), cmd);
168 
169  fp = fopen(path, "r");
170 
171  if (!fp) {
172  draw_info_format(COLOR_RED, "Could not read %s.", path);
173  return 1;
174  }
175 
176  send_command("/console noinf::");
177 
178  while (fgets(buf, sizeof(buf) - 1, fp)) {
179  cp = strchr(buf, '\n');
180 
181  if (cp) {
182  *cp = '\0';
183  }
184 
185  sb = stringbuffer_new();
186  stringbuffer_append_string(sb, "/console noinf::");
187  stringbuffer_append_string(sb, buf);
188  cp = stringbuffer_finish(sb);
189  send_command(cp);
190  efree(cp);
191  }
192 
193  send_command("/console noinf::");
194 
195  fclose(fp);
196 
197  return 1;
198  } else if (strncasecmp(cmd, "/console-obj", 11) == 0) {
200  return 1;
201  } else if (strncasecmp(cmd, "/patch-obj", 11) == 0) {
203  return 1;
204  } else if (string_startswith(cmd, "/cast ") || string_startswith(cmd, "/use_skill ")) {
205  object *tmp;
206  uint8_t type;
207 
208  type = string_startswith(cmd, "/cast ") ? TYPE_SPELL : TYPE_SKILL;
209  cmd = strchr(cmd, ' ') + 1;
210 
211  if (string_isempty(cmd)) {
212  return 1;
213  }
214 
215  for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
216  if (tmp->itype == type && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
217  client_send_fire(5, tmp->tag);
218  return 1;
219  }
220  }
221 
222  draw_info_format(COLOR_RED, "Unknown %s.", type == TYPE_SPELL ? "spell" : "skill");
223  return 1;
224  } else if (strncasecmp(cmd, "/clearcache", 11) == 0) {
225  cmd += 12;
226 
227  if (string_isempty(cmd)) {
228  return 1;
229  }
230 
231  if (strcasecmp(cmd, "sound") == 0) {
233  draw_info(COLOR_GREEN, "Sound cache cleared.");
234  } else if (strcasecmp(cmd, "textures") == 0) {
235  texture_reload();
236  draw_info(COLOR_GREEN, "Textures reloaded.");
237  }
238 
239  return 1;
240  } else if (string_startswith(cmd, "/droptag ") ||
241  string_startswith(cmd, "/gettag ")) {
242  char *cps[3];
243  unsigned long int loc, tag, num;
244 
245  if (string_split(strchr(cmd, ' ') + 1, cps, arraysize(cps), ' ') !=
246  arraysize(cps)) {
247  return 1;
248  }
249 
250  loc = strtoul(cps[0], NULL, 10);
251  tag = strtoul(cps[1], NULL, 10);
252  num = strtoul(cps[2], NULL, 10);
253  client_send_move(loc, tag, num);
254 
255  if (string_startswith(cmd, "/gettag ")) {
256  sound_play_effect("get.ogg", 100);
257  } else {
258  sound_play_effect("drop.ogg", 100);
259  }
260 
261  return 1;
262  } else if (string_startswith(cmd, "/talk")) {
263  char type[MAX_BUF], npc_name[MAX_BUF];
264  size_t pos;
265  uint8_t type_num;
266  packet_struct *packet;
267 
268  pos = 5;
269 
270  if (!string_get_word(cmd, &pos, ' ', type, sizeof(type), 0) || string_isempty(cmd + pos)) {
271  return 1;
272  }
273 
274  type_num = atoi(type);
275 
276  if (type_num == CMD_TALK_NPC_NAME && (!string_get_word(cmd, &pos, ' ', npc_name, sizeof(npc_name), '"') || string_isempty(cmd + pos))) {
277  return 1;
278  }
279 
280  packet = packet_new(SERVER_CMD_TALK, 64, 64);
281  packet_append_uint8(packet, type_num);
282 
283  if (type_num == CMD_TALK_NPC || type_num == CMD_TALK_NPC_NAME) {
284  if (type_num == CMD_TALK_NPC_NAME) {
285  packet_append_string_terminated(packet, npc_name);
286  }
287 
288  packet_append_string_terminated(packet, cmd + pos);
289  } else {
290  char tag[MAX_BUF];
291 
292  if (!string_get_word(cmd, &pos, ' ', tag, sizeof(tag), 0) || string_isempty(cmd + pos)) {
293  packet_free(packet);
294  return 1;
295  }
296 
297  packet_append_uint32(packet, atoi(tag));
298  packet_append_string_terminated(packet, cmd + pos);
299  }
300 
301  socket_send_packet(packet);
302 
303  return 1;
304  } else if (string_startswith(cmd, "/widget_toggle")) {
305  size_t pos;
306  char word[MAX_BUF], *cps[2];
307  int widget_id;
308 
309  pos = 14;
310 
311  while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) {
312  if (string_split(word, cps, arraysize(cps), ':') < 1) {
313  continue;
314  }
315 
316  widget_id = widget_id_from_name(cps[0]);
317 
318  /* Invalid widget ID */
319  if (widget_id == -1) {
320  continue;
321  }
322 
323  /* Redraw all or a specific one identified by its UID */
324  if (cps[1] == NULL) {
325  WIDGET_SHOW_TOGGLE_ALL(widget_id);
326  } else {
327  widgetdata *widget;
328 
329  widget = widget_find(NULL, widget_id, cps[1], NULL);
330 
331  if (widget) {
332  WIDGET_SHOW_TOGGLE(widget);
333  }
334  }
335  }
336 
337  return 1;
338  } else if (string_startswith(cmd, "/widget_focus")) {
339  size_t pos;
340  char word[MAX_BUF], *cps[2];
341  int widget_id;
342 
343  pos = 14;
344 
345  while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) {
346  if (string_split(word, cps, arraysize(cps), ':') < 1) {
347  continue;
348  }
349 
350  widget_id = widget_id_from_name(cps[0]);
351  if (widget_id == -1) {
352  /* Invalid widget ID */
353  continue;
354  }
355 
356  widget_switch_focus(widget_id, cps[1]);
357  }
358 
359  return 1;
360  } else if (string_startswith(cmd, "/ping")) {
362  return 1;
363  } else if (string_startswith(cmd, "/region_map")) {
364  region_map_open();
365  return 1;
366  }
367 
368  return 0;
369 }
370 
376 int send_command_check(const char *cmd)
377 {
378  if (!client_command_check(cmd)) {
379  send_command(cmd);
380  return 1;
381  }
382 
383  return 0;
384 }
void widgets_reset(void)
Definition: widget.c:590
int effect_start(const char *name)
Definition: effects.c:612
char s_name[NAME_LEN]
Definition: item.h:60
void draw_info(const char *color, const char *str)
Definition: textwin.c:448
void sound_play_effect(const char *filename, int volume)
Definition: sound.c:367
void menu_inventory_loadtoconsole(widgetdata *widget, widgetdata *menuitem, SDL_Event *event)
Definition: inventory.c:1143
SDL_Surface * surface
Definition: widget.h:110
void sound_resume_music(void)
Definition: sound.c:511
int client_command_check(const char *cmd)
Definition: menu.c:44
void menu_inventory_patch(widgetdata *widget, widgetdata *menuitem, SDL_Event *event)
Definition: inventory.c:1169
void sound_clear_cache(void)
Definition: sound.c:305
SDL_Surface * ScreenSurface
Definition: main.c:47
void keepalive_ping_stats(void)
Definition: main.c:148
void send_command(const char *command)
Definition: player.c:175
uint32_t tag
Definition: item.h:63
#define COLOR_RED
Definition: text.h:295
#define COLOR_GREEN
Definition: text.h:297
widgetdata * widget_find(widgetdata *where, int type, const char *id, SDL_Surface *surface)
Definition: widget.c:2091
void help_show(const char *name)
Definition: help.c:219
Client_Player cpl
Definition: client.c:50
void region_map_open(void)
Definition: region_map.c:464
widgetdata * cur_widget[TOTAL_SUBWIDGETS]
Definition: widget.c:75
struct obj * next
Definition: item.h:45
void inventory_filter_set_names(const char *filter)
Definition: inventory.c:153
void texture_reload(void)
Definition: texture.c:221
void client_send_move(tag_t loc, tag_t tag, uint32_t nrof)
Definition: player.c:156
void sound_pause_music(void)
Definition: sound.c:500
char partyjoin[MAX_BUF]
Definition: player.h:182
int send_command_check(const char *cmd)
Definition: menu.c:376
uint8_t itype
Definition: item.h:90
widgetdata * inventory_focus
Definition: player.h:200
struct obj * inv
Definition: item.h:57
uint32_t flags
Definition: item.h:87
void client_send_apply(object *op)
Definition: player.c:119
void draw_info_format(const char *color, const char *format,...)
Definition: textwin.c:429
void effect_debug(const char *type)
Definition: effects.c:654
const char * get_config_dir(void)
Definition: wrapper.c:303
void widget_switch_focus(int type, const char *id)
Definition: widget.c:2165
object * ob
Definition: player.h:111
int cmd_aliases_handle(const char *cmd)
Definition: cmd_aliases.c:317
void effect_stop(void)
Definition: effects.c:689
void screenshot_create(SDL_Surface *surface)
Definition: misc.c:132