1 | /* |
1 | /* |
2 | * static char *rcsid_commands_c = |
2 | * static char *rcsid_commands_c = |
3 | * "$Id: commands.c,v 1.7 2006/05/17 21:45:33 pippijn Exp $"; |
3 | * "$Id: commands.c,v 1.8 2006/07/02 11:18:03 pippijn Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
353 | sizeof(CommArray_s), compare_A); |
353 | sizeof(CommArray_s), compare_A); |
354 | if (asp) |
354 | if (asp) |
355 | return asp->func; |
355 | return asp->func; |
356 | return NULL; |
356 | return NULL; |
357 | } |
357 | } |
358 | |
|
|
359 | static CommFunc find_command(char *cmd) |
|
|
360 | { |
|
|
361 | CommArray_s *asp, dummy; |
|
|
362 | char *cp; |
|
|
363 | |
|
|
364 | dummy.name =cmd; |
|
|
365 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
366 | (void *)Commands, CommandsSize, |
|
|
367 | sizeof(CommArray_s), compare_A); |
|
|
368 | LOG(llevDebug, "Getting asp for command string %s\n", cmd); |
|
|
369 | if (asp) |
|
|
370 | return asp->func; |
|
|
371 | else |
|
|
372 | { |
|
|
373 | LOG(llevDebug, "Now we are here\n"); |
|
|
374 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
375 | (void *)CommunicationCommands, CommunicationCommandSize, |
|
|
376 | sizeof(CommArray_s), compare_A); |
|
|
377 | if (asp) |
|
|
378 | return asp->func; |
|
|
379 | else |
|
|
380 | return NULL; |
|
|
381 | }; |
|
|
382 | } |
|
|
383 | |
|
|
384 | static CommFunc find_wizcommand(char *cmd) |
|
|
385 | { |
|
|
386 | CommArray_s *asp, dummy; |
|
|
387 | char *cp; |
|
|
388 | |
|
|
389 | dummy.name =cmd; |
|
|
390 | asp =(CommArray_s *)bsearch((void *)&dummy, |
|
|
391 | (void *)WizCommands, WizCommandsSize, |
|
|
392 | sizeof(CommArray_s), compare_A); |
|
|
393 | if (asp) |
|
|
394 | return asp->func; |
|
|
395 | return NULL; |
|
|
396 | } |
|
|
397 | |
|
|
398 | |
|
|
399 | /* |
|
|
400 | * parse_string may be called from a player in the game or from a socket |
|
|
401 | * (op is NULL if it's a socket). |
|
|
402 | * It returnes 1 if it recognized the command, otherwise 0. |
|
|
403 | * Actually return value is used as can-repeat -flag |
|
|
404 | */ |
|
|
405 | |
|
|
406 | int parse_string(object *op, char *str) |
|
|
407 | { |
|
|
408 | CommFunc f; |
|
|
409 | char *cp; |
|
|
410 | CommArray_s *asp; |
|
|
411 | |
|
|
412 | #ifdef INPUT_DEBUG |
|
|
413 | LOG(llevDebug, "Command: '%s'\n", str); |
|
|
414 | #endif |
|
|
415 | /* |
|
|
416 | * remove trailing spaces |
|
|
417 | */ |
|
|
418 | cp = str+strlen(str)-1; |
|
|
419 | while ( (cp>=str) && (*cp==' ')){ |
|
|
420 | *cp='\0'; |
|
|
421 | cp--; |
|
|
422 | } |
|
|
423 | /* |
|
|
424 | * No arguments? |
|
|
425 | */ |
|
|
426 | if (!(cp=strchr(str, ' '))) { |
|
|
427 | /* GROS - If we are here, then maybe this is a plugin-provided command ? */ |
|
|
428 | asp = find_plugin_command(str, op); |
|
|
429 | if (asp) |
|
|
430 | return asp->func(op, NULL); |
|
|
431 | |
|
|
432 | if ((f=find_command(str))) |
|
|
433 | return f(op, NULL); |
|
|
434 | if (QUERY_FLAG(op,FLAG_WIZ) && (f=find_wizcommand(str))) |
|
|
435 | return f(op, NULL); |
|
|
436 | |
|
|
437 | if(op) { |
|
|
438 | new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help."); |
|
|
439 | } |
|
|
440 | return 0; |
|
|
441 | } |
|
|
442 | |
|
|
443 | /* |
|
|
444 | * Command with some arguments |
|
|
445 | */ |
|
|
446 | |
|
|
447 | *(cp++) ='\0'; |
|
|
448 | /* Clear all spaces from the start of the optional argument */ |
|
|
449 | while (*cp==' ') cp++; |
|
|
450 | |
|
|
451 | asp = find_plugin_command(str,op); |
|
|
452 | if (asp) return asp->func(op,cp); |
|
|
453 | |
|
|
454 | if ((f=find_command(str))) |
|
|
455 | return f(op, cp); |
|
|
456 | if (QUERY_FLAG(op, FLAG_WIZ) && (f=find_wizcommand(str))) |
|
|
457 | return f(op, cp); |
|
|
458 | |
|
|
459 | if(op) { |
|
|
460 | new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help."); |
|
|
461 | } |
|
|
462 | return 0; |
|
|
463 | } |
|
|
464 | |
|
|
465 | |
|
|
466 | /* this function handles splitting up a ; separated |
|
|
467 | * compound command into sub-commands: it is recursive. |
|
|
468 | */ |
|
|
469 | int parse_command(object *op, char *str) { |
|
|
470 | char *tmp,*tmp2; |
|
|
471 | int i; |
|
|
472 | /* if it's a keybinding command, ignore semicolons */ |
|
|
473 | if(strstr(str,"bind")) return parse_string(op,str); |
|
|
474 | LOG(llevDebug, "parsin command '%s'\n", str); |
|
|
475 | /* If on a socket, you can not do complex commands. */ |
|
|
476 | if(op && (tmp=strchr(str,';'))!=NULL) /* we've found a ';' do the 1st and recurse */ |
|
|
477 | { |
|
|
478 | char buf[MAX_BUF]; |
|
|
479 | /* copy 1st command into buf */ |
|
|
480 | /* Even if tmp2 points the the input_buf, this should still |
|
|
481 | * be safe operation. |
|
|
482 | */ |
|
|
483 | for(i=0,tmp2=str;tmp2!=tmp;i++,tmp2++) |
|
|
484 | buf[i]= (*tmp2); |
|
|
485 | buf[i]='\0'; /* null terminate the copy*/ |
|
|
486 | strncpy(op->contr->input_buf,tmp2+1, MAX_BUF); |
|
|
487 | op->contr->input_buf[MAX_BUF-1]=0; |
|
|
488 | parse_string(op,buf); |
|
|
489 | } |
|
|
490 | else { |
|
|
491 | /* We need to set the input_buf to 0 so clear any complex keybinding |
|
|
492 | * there might be. However, str can be a pointer to input_buf in |
|
|
493 | * the case of a complex keybinding. So first we process the command, |
|
|
494 | * clear the buffer, and then return the value. |
|
|
495 | */ |
|
|
496 | i=parse_string(op,str); |
|
|
497 | if (op) op->contr->input_buf[0]=0; |
|
|
498 | return i; |
|
|
499 | } |
|
|
500 | return 0; |
|
|
501 | } |
|
|