1 | /* |
1 | /* |
2 | * static char *rcsid_commands_c = |
2 | * static char *rcsid_commands_c = |
3 | * "$Id: commands.c,v 1.1.1.2 2006/02/22 18:03:20 elmex Exp $"; |
3 | * "$Id: commands.c,v 1.9 2006/08/13 17:16:04 elmex dead $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
52 | {"party", command_party, 0.0}, |
52 | {"party", command_party, 0.0}, |
53 | {"gsay", command_gsay, 1.0}, |
53 | {"gsay", command_gsay, 1.0}, |
54 | |
54 | |
55 | #ifdef DEBUG |
55 | #ifdef DEBUG |
56 | {"sstable", command_sstable, 0.0}, |
56 | {"sstable", command_sstable, 0.0}, |
57 | #endif |
|
|
58 | #ifdef DEBUG_MALLOC_LEVEL |
|
|
59 | {"verify", command_malloc_verify,0.0}, |
|
|
60 | #endif |
57 | #endif |
61 | {"apply", command_apply, 1.0}, /* should be variable */ |
58 | {"apply", command_apply, 1.0}, /* should be variable */ |
62 | {"applymode", command_applymode, 1.0}, /* should be variable */ |
59 | {"applymode", command_applymode, 1.0}, /* should be variable */ |
63 | {"archs", command_archs, 0.0}, |
60 | {"archs", command_archs, 0.0}, |
64 | {"body", command_body, 0.0}, |
61 | {"body", command_body, 0.0}, |
… | |
… | |
79 | {"inventory", command_inventory,0.0}, |
76 | {"inventory", command_inventory,0.0}, |
80 | {"invoke", command_invoke, 1.0}, |
77 | {"invoke", command_invoke, 1.0}, |
81 | {"killpets", command_kill_pets,0.0}, |
78 | {"killpets", command_kill_pets,0.0}, |
82 | {"listen", command_listen, 0.0}, |
79 | {"listen", command_listen, 0.0}, |
83 | {"logs", command_logs, 0.0}, |
80 | {"logs", command_logs, 0.0}, |
84 | {"malloc", command_malloc, 0.0}, |
|
|
85 | {"maps", command_maps, 0.0}, |
81 | {"maps", command_maps, 0.0}, |
86 | {"mapinfo", command_mapinfo, 0.0}, |
82 | {"mapinfo", command_mapinfo, 0.0}, |
87 | {"mark", command_mark, 0.0}, |
83 | {"mark", command_mark, 0.0}, |
88 | {"motd", command_motd, 0.0}, |
84 | {"motd", command_motd, 0.0}, |
89 | {"output-sync", command_output_sync, 0.0}, |
85 | {"output-sync", command_output_sync, 0.0}, |
90 | {"output-count", command_output_count,0.0}, |
86 | {"output-count", command_output_count,0.0}, |
91 | {"peaceful", command_peaceful,0.0}, |
87 | {"peaceful", command_peaceful,0.0}, |
92 | {"pickup", command_pickup, 1.0}, |
88 | {"pickup", command_pickup, 1.0}, |
93 | {"players", command_players, 0.0}, |
|
|
94 | {"prepare", command_prepare, 1.0}, |
89 | {"prepare", command_prepare, 1.0}, |
95 | {"quit", command_quit, 0.0}, |
90 | {"quit", command_quit, 0.0}, |
|
|
91 | {"quit_character", command_real_quit, 0.0}, |
96 | {"rename", command_rename_item, 0.0}, |
92 | {"rename", command_rename_item, 0.0}, |
97 | {"resistances", command_resistances, 0.0}, |
93 | {"resistances", command_resistances, 0.0}, |
98 | {"rotateshoottype", command_rotateshoottype, 0.0}, |
94 | {"rotateshoottype", command_rotateshoottype, 0.0}, |
99 | {"shutdown", command_shutdown, 0.0}, |
|
|
100 | {"skills", command_skills, 0.0}, /* shows player list of skills */ |
95 | {"skills", command_skills, 0.0}, /* shows player list of skills */ |
101 | {"use_skill", command_uskill, 1.0}, |
96 | {"use_skill", command_uskill, 1.0}, |
102 | {"quests", command_quests, 0.0}, |
97 | {"quests", command_quests, 0.0}, |
103 | {"ready_skill", command_rskill, 1.0}, |
98 | {"ready_skill", command_rskill, 1.0}, |
104 | {"search",command_search, 1.0}, |
99 | {"search",command_search, 1.0}, |
… | |
… | |
239 | {"insert_into", command_insert_into,0.0}, |
234 | {"insert_into", command_insert_into,0.0}, |
240 | {"invisible", command_invisible,0.0}, |
235 | {"invisible", command_invisible,0.0}, |
241 | {"kick", command_kick, 0.0}, |
236 | {"kick", command_kick, 0.0}, |
242 | {"learn_special_prayer", command_learn_special_prayer, 0.0}, |
237 | {"learn_special_prayer", command_learn_special_prayer, 0.0}, |
243 | {"learn_spell", command_learn_spell, 0.0}, |
238 | {"learn_spell", command_learn_spell, 0.0}, |
|
|
239 | #ifdef DEBUG_MALLOC_LEVEL |
|
|
240 | {"verify", command_malloc_verify,0.0}, |
|
|
241 | #endif |
|
|
242 | {"malloc", command_malloc,0.0}, |
|
|
243 | {"players", command_players, 0.0}, |
244 | {"plugin",command_loadplugin,0.0}, |
244 | {"plugin",command_loadplugin,0.0}, |
245 | {"pluglist",command_listplugins,0.0}, |
245 | {"pluglist",command_listplugins,0.0}, |
246 | {"plugout",command_unloadplugin,0.0}, |
246 | {"plugout",command_unloadplugin,0.0}, |
247 | {"nodm", command_nowiz,0.0}, |
247 | {"nodm", command_nowiz,0.0}, |
248 | {"nowiz", command_nowiz,0.0}, |
248 | {"nowiz", command_nowiz,0.0}, |
249 | {"patch", command_patch,0.0}, |
249 | {"patch", command_patch,0.0}, |
250 | {"remove", command_remove,0.0}, |
250 | {"remove", command_remove,0.0}, |
251 | {"reset", command_reset,0.0}, |
251 | {"reset", command_reset,0.0}, |
252 | {"set_god", command_setgod, 0.0}, |
252 | {"set_god", command_setgod, 0.0}, |
253 | {"server_speed", command_speed,0.0}, |
253 | {"server_speed", command_speed,0.0}, |
|
|
254 | {"shutdown", command_shutdown, 0.0}, |
254 | {"ssdumptable", command_ssdumptable,0.0}, |
255 | {"ssdumptable", command_ssdumptable,0.0}, |
255 | {"stack_clear", command_stack_clear, 0.0 }, |
256 | {"stack_clear", command_stack_clear, 0.0 }, |
256 | {"stack_list", command_stack_list, 0.0}, |
257 | {"stack_list", command_stack_list, 0.0}, |
257 | {"stack_pop", command_stack_pop, 0.0 }, |
258 | {"stack_pop", command_stack_pop, 0.0 }, |
258 | {"stack_push", command_stack_push, 0.0 }, |
259 | {"stack_push", command_stack_push, 0.0 }, |
… | |
… | |
352 | sizeof(CommArray_s), compare_A); |
353 | sizeof(CommArray_s), compare_A); |
353 | if (asp) |
354 | if (asp) |
354 | return asp->func; |
355 | return asp->func; |
355 | return NULL; |
356 | return NULL; |
356 | } |
357 | } |
357 | |
|
|
358 | static CommFunc find_command(char *cmd) |
|
|
359 | { |
|
|
360 | CommArray_s *asp, dummy; |
|
|
361 | char *cp; |
|
|
362 | |
|
|
363 | for (cp=cmd; *cp; cp++) |
|
|
364 | *cp =tolower(*cp); |
|
|
365 | |
|
|
366 | dummy.name =cmd; |
|
|
367 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
368 | (void *)Commands, CommandsSize, |
|
|
369 | sizeof(CommArray_s), compare_A); |
|
|
370 | LOG(llevDebug, "Getting asp for command string %s\n", cmd); |
|
|
371 | if (asp) |
|
|
372 | return asp->func; |
|
|
373 | else |
|
|
374 | { |
|
|
375 | LOG(llevDebug, "Now we are here\n"); |
|
|
376 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
377 | (void *)CommunicationCommands, CommunicationCommandSize, |
|
|
378 | sizeof(CommArray_s), compare_A); |
|
|
379 | if (asp) |
|
|
380 | return asp->func; |
|
|
381 | else |
|
|
382 | return NULL; |
|
|
383 | }; |
|
|
384 | } |
|
|
385 | |
|
|
386 | static CommFunc find_wizcommand(char *cmd) |
|
|
387 | { |
|
|
388 | CommArray_s *asp, dummy; |
|
|
389 | char *cp; |
|
|
390 | |
|
|
391 | for (cp=cmd; *cp; cp++) |
|
|
392 | *cp =tolower(*cp); |
|
|
393 | |
|
|
394 | dummy.name =cmd; |
|
|
395 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
396 | (void *)WizCommands, WizCommandsSize, |
|
|
397 | sizeof(CommArray_s), compare_A); |
|
|
398 | if (asp) |
|
|
399 | return asp->func; |
|
|
400 | return NULL; |
|
|
401 | } |
|
|
402 | |
|
|
403 | |
|
|
404 | /* |
|
|
405 | * parse_string may be called from a player in the game or from a socket |
|
|
406 | * (op is NULL if it's a socket). |
|
|
407 | * It returnes 1 if it recognized the command, otherwise 0. |
|
|
408 | * Actually return value is used as can-repeat -flag |
|
|
409 | */ |
|
|
410 | |
|
|
411 | int parse_string(object *op, char *str) |
|
|
412 | { |
|
|
413 | CommFunc f; |
|
|
414 | char *cp; |
|
|
415 | CommArray_s *asp; |
|
|
416 | |
|
|
417 | #ifdef INPUT_DEBUG |
|
|
418 | LOG(llevDebug, "Command: '%s'\n", str); |
|
|
419 | #endif |
|
|
420 | /* |
|
|
421 | * remove trailing spaces |
|
|
422 | */ |
|
|
423 | cp = str+strlen(str)-1; |
|
|
424 | while ( (cp>=str) && (*cp==' ')){ |
|
|
425 | *cp='\0'; |
|
|
426 | cp--; |
|
|
427 | } |
|
|
428 | /* |
|
|
429 | * No arguments? |
|
|
430 | */ |
|
|
431 | if (!(cp=strchr(str, ' '))) { |
|
|
432 | /* GROS - If we are here, then maybe this is a plugin-provided command ? */ |
|
|
433 | asp = find_plugin_command(str, op); |
|
|
434 | if (asp) |
|
|
435 | return asp->func(op, NULL); |
|
|
436 | |
|
|
437 | if ((f=find_command(str))) |
|
|
438 | return f(op, NULL); |
|
|
439 | if (QUERY_FLAG(op,FLAG_WIZ) && (f=find_wizcommand(str))) |
|
|
440 | return f(op, NULL); |
|
|
441 | |
|
|
442 | if(op) { |
|
|
443 | new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help."); |
|
|
444 | } |
|
|
445 | return 0; |
|
|
446 | } |
|
|
447 | |
|
|
448 | /* |
|
|
449 | * Command with some arguments |
|
|
450 | */ |
|
|
451 | |
|
|
452 | *(cp++) ='\0'; |
|
|
453 | /* Clear all spaces from the start of the optional argument */ |
|
|
454 | while (*cp==' ') cp++; |
|
|
455 | |
|
|
456 | asp = find_plugin_command(str,op); |
|
|
457 | if (asp) return asp->func(op,cp); |
|
|
458 | |
|
|
459 | if ((f=find_command(str))) |
|
|
460 | return f(op, cp); |
|
|
461 | if (QUERY_FLAG(op, FLAG_WIZ) && (f=find_wizcommand(str))) |
|
|
462 | return f(op, cp); |
|
|
463 | |
|
|
464 | if(op) { |
|
|
465 | new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help."); |
|
|
466 | } |
|
|
467 | return 0; |
|
|
468 | } |
|
|
469 | |
|
|
470 | |
|
|
471 | /* this function handles splitting up a ; separated |
|
|
472 | * compound command into sub-commands: it is recursive. |
|
|
473 | */ |
|
|
474 | int parse_command(object *op, char *str) { |
|
|
475 | char *tmp,*tmp2; |
|
|
476 | int i; |
|
|
477 | /* if it's a keybinding command, ignore semicolons */ |
|
|
478 | if(strstr(str,"bind")) return parse_string(op,str); |
|
|
479 | LOG(llevDebug, "parsin command '%s'\n", str); |
|
|
480 | /* If on a socket, you can not do complex commands. */ |
|
|
481 | if(op && (tmp=strchr(str,';'))!=NULL) /* we've found a ';' do the 1st and recurse */ |
|
|
482 | { |
|
|
483 | char buf[MAX_BUF]; |
|
|
484 | /* copy 1st command into buf */ |
|
|
485 | /* Even if tmp2 points the the input_buf, this should still |
|
|
486 | * be safe operation. |
|
|
487 | */ |
|
|
488 | for(i=0,tmp2=str;tmp2!=tmp;i++,tmp2++) |
|
|
489 | buf[i]= (*tmp2); |
|
|
490 | buf[i]='\0'; /* null terminate the copy*/ |
|
|
491 | strncpy(op->contr->input_buf,tmp2+1, MAX_BUF); |
|
|
492 | op->contr->input_buf[MAX_BUF-1]=0; |
|
|
493 | parse_string(op,buf); |
|
|
494 | } |
|
|
495 | else { |
|
|
496 | /* We need to set the input_buf to 0 so clear any complex keybinding |
|
|
497 | * there might be. However, str can be a pointer to input_buf in |
|
|
498 | * the case of a complex keybinding. So first we process the command, |
|
|
499 | * clear the buffer, and then return the value. |
|
|
500 | */ |
|
|
501 | i=parse_string(op,str); |
|
|
502 | if (op) op->contr->input_buf[0]=0; |
|
|
503 | return i; |
|
|
504 | } |
|
|
505 | return 0; |
|
|
506 | } |
|
|