/* * XPilot NG, a multiplayer space war game. * * Copyright (C) 2000-2004 by * * Uoti Urpala * Erik Andersson * Kristian Söderblom * * Copyright (C) 1991-2001 by * * Bjørn Stabell * Ken Ronny Schouten * Bert Gijsbers * Dick Balaska * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "xpserver.h" /* * Look if any player's name is exactly 'str', * If not, look if any player's name contains 'str'. * The matching is case insensitive. If there is an * error (no matches or several matches) NULL is returned * and the error code is stored in 'error' if that is not NULL * and a string describing the error is stored in * 'errorstr_p' if that is not NULL. */ player_t *Get_player_by_name(const char *str, int *error_p, const char **errorstr_p) { int i, id; player_t *found_pl = NULL, *pl; size_t len; if (str == NULL || (len = strlen(str)) == 0) goto match_none; /* Get player by id */ id = atoi(str); if (id > 0) { found_pl = Player_by_id(id); if (!found_pl) goto match_none; return found_pl; } /* Look for an exact match on player nickname. */ for (i = 0; i < NumPlayers; i++) { pl = Player_by_index(i); if (!strcasecmp(pl->name, str)) return pl; } /* Look if 'str' matches beginning of only one nick. */ for (i = 0; i < NumPlayers; i++) { pl = Player_by_index(i); if (!strncasecmp(pl->name, str, len)) { if (found_pl) goto match_several; found_pl = pl; continue; } } if (found_pl) return found_pl; /* * Check what players' name 'str' is a substring of (case insensitively). */ for (i = 0; i < NumPlayers; i++) { int j; pl = Player_by_index(i); for (j = 0; j < 1 + (int)strlen(pl->name) - (int)len; j++) { if (!strncasecmp(pl->name + j, str, len)) { if (found_pl) goto match_several; found_pl = pl; break; } } } if (found_pl) return found_pl; match_none: if (error_p != NULL) *error_p = -1; if (errorstr_p != NULL) *errorstr_p = "Name does not match any player."; return NULL; match_several: if (error_p != NULL) *error_p = -2; if (errorstr_p != NULL) *errorstr_p = "Name matches several players."; return NULL; } static void Send_info_about_player(player_t *pl) { int i; for (i = 0; i < spectatorStart + NumSpectators; i++) { player_t *pl_i; if (i == NumPlayers) { i = spectatorStart - 1; continue; } pl_i = Player_by_index(i); if (pl_i->conn != NULL) { Send_team(pl_i->conn, pl->id, pl->team); /*if we do either, we do both... but is either necessary?*/ updateScores = true; pl->update_score = true; if (pl->home_base != NULL) Send_base(pl_i->conn, pl->id, pl->home_base->ind); } } } static void Set_swapper_state(player_t *pl) { if (BIT(pl->have, HAS_BALL)) Detach_ball(pl, NULL); if (BIT(world->rules->mode, LIMITED_LIVES)) { int i; for (i = 0; i < NumPlayers; i++) { player_t *pl_i = Player_by_index(i); if (!Players_are_teammates(pl, pl_i) && !Player_is_paused(pl_i)) { /* put team swapping player waiting mode. */ /* kps - there used to be a if (pl->mychar == ' ') here, * not sure what that was good for. */ Player_set_state(pl, PL_STATE_WAITING); Player_self_destruct(pl, false); pl->pause_count = 0; pl->recovery_count = 0; break; } } } } #define CMD_RESULT_SUCCESS 0 #define CMD_RESULT_ERROR (-1) #define CMD_RESULT_NOT_OPERATOR (-2) #define CMD_RESULT_NO_NAME (-3) static int Cmd_addr(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_advance(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_ally(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_get(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_help(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_kick(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_lock(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_maxturnsps(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_mute(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_op(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_password(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_pause(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_plinfo(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_queue(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_reset(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_set(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_shutdown(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_stats(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_team(char *arg, player_t *pl, bool oper, char *msg, size_t size); static int Cmd_version(char *arg, player_t *pl, bool oper, char *msg, size_t size); typedef struct { const char *name; const char *abbrev; const char *help; bool oper_only; int (*cmd)(char *arg, player_t *pl, bool oper, char *msg, size_t size); } Command_info; /* * A list of all the commands sorted alphabetically. */ static Command_info commands[] = { { "addr", "addr", "/addr . Show IP-address of player. " "(operator)", true, Cmd_addr }, { "advance", "ad", "/advance . " "Move the player to the front of the queue. (operator)", true, Cmd_advance }, { "ally", "al", "/ally {invite|cancel|refuse|accept|leave|list} []. " "Manages alliances and invitations for them.", false, Cmd_ally }, { "get", "g", "/get