src/lib/player/dispatch.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  dispatch.c: Actually execute the command given
00029  * 
00030  *  Known contributors to this file:
00031  *     Dave Pare, 1994
00032  *     Steve McClure, 1998
00033  *     Markus Armbruster, 2007
00034  */
00035 
00036 #include <config.h>
00037 
00038 #include "com.h"
00039 #include "empio.h"
00040 #include "file.h"
00041 #include "match.h"
00042 #include "misc.h"
00043 #include "nat.h"
00044 #include "optlist.h"
00045 #include "player.h"
00046 #include "proto.h"
00047 #include "prototypes.h"
00048 #include "server.h"
00049 
00050 /*
00051  * Execute command named by player->argp[0].
00052  * BUF is the raw UTF-8 command line.  It should have been passed to
00053  * parse() to set up player->argp.
00054  * If REDIR is not null, it's the command's redirection, in UTF-8.
00055  * Return -1 if the command is not unique or doesn't exist, else 0.
00056  */
00057 int
00058 dispatch(char *buf, char *redir)
00059 {
00060     struct natstr *np;
00061     struct cmndstr *command;
00062     int cmd;
00063 
00064     cmd = comtch(player->argp[0], player_coms, player->nstat);
00065     if (cmd < 0) {
00066         if (cmd == M_NOTUNIQUE)
00067             pr("Command \"%s\" is ambiguous -- ", player->argp[0]);
00068         else if (cmd == M_IGNORE)
00069             return 0;
00070         else
00071             pr("\"%s\" is not a legal command\n", player->argp[0]);
00072         return -1;
00073     }
00074     command = &player_coms[cmd];
00075     np = getnatp(player->cnum);
00076     if (np->nat_btu < command->c_cost && command->c_cost > 0) {
00077         if (player->god || opt_BLITZ)
00078             np->nat_btu = max_btus;
00079         else {
00080             pr("You don't have the BTU's, bozo\n");
00081             return 0;
00082         }
00083     }
00084     if (command->c_addr == 0) {
00085         pr("Command not implemented\n");
00086         return 0;
00087     }
00088     /*
00089      * Rwlocks can hand out read locks while a write lock is wanted.
00090      * Unfair to writers, but possible.  This lets commands run with
00091      * !player->aborted, which can then block on input and thus delay
00092      * the update indefinitely.  We could avoid that by setting
00093      * player->aborted here, but spinning until the update is done is
00094      * nicer to players.
00095      */
00096     while (play_wrlock_wanted)
00097         empth_yield();
00098     player->command = command;
00099     empth_rwlock_rdlock(play_lock);
00100     if (redir) {
00101         prredir(redir);
00102         uprnf(buf);
00103         pr("\n");
00104     }
00105     switch (command->c_addr()) {
00106     case RET_OK:
00107         player->btused += command->c_cost;
00108         break;
00109     case RET_FAIL:
00110         pr("command failed\n");
00111         player->btused += command->c_cost;
00112         break;
00113     case RET_SYN:
00114         pr("Usage: %s\n", command->c_form);
00115         break;
00116     case RET_SYS:
00117         logerror("System error, command failed: %s", command->c_form);
00118         break;
00119     default:
00120         CANT_REACH();
00121         break;
00122     }
00123     empth_rwlock_unlock(play_lock);
00124     player->command = NULL;
00125     return 0;
00126 }

Generated on Fri Mar 28 11:01:14 2008 for empserver by  doxygen 1.5.2