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 }
1.5.2