/* * Descent 3 * Copyright (C) 2024 Parallax Software * * 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 3 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, see . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/dmfc/dmfcinputcommand.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003/08/26 03:57:20 $ * $Author: kevinb $ * * Functions for Input commands (function handlers) * * $Log: dmfcinputcommand.cpp,v $ * Revision 1.1.1.1 2003/08/26 03:57:20 kevinb * initial 1.5 import * * * 26 2/08/00 4:33a Jason * Fixed memory overwrite during string parse * * 25 7/14/99 11:47a Jeff * localized text for patch fixes * * 24 7/09/99 6:18p Jeff * added $remoteadminlogout and $wait commands * * 23 7/08/99 2:39a Jeff * rough implementation of remote administration checked in. Still needs * some polishing, but should work basically. * * 22 5/07/99 12:52p Jeff * audio taunt icon is ppic if available. coop has hard max team set of 4 * * 21 4/30/99 10:53p Jeff * added $warp command * * 20 3/17/99 12:24p Jeff * converted DMFC to be COM interface * * 19 2/11/99 12:50a Jeff * changed names of exported variables * * 18 1/31/99 7:26p Matt * Renamed a bunch of functions to have HUD capitalized * * 17 1/19/99 3:55a Jeff * all strings localized out * * 16 1/06/99 12:53a Jeff * put in support for $piggyback and $observer * * 15 1/04/99 12:21p Jeff * added support for hosts.allow/deny and updates stats manager a little * * 14 12/08/98 12:17p Jeff * various changes that include an improved Team Control dialog (doesn't * switch teams until exit..) and spew/respawn players that change teams * * 13 11/16/98 5:35p Jeff * removed log functions, added support for changing team names, fixed ctf * to work better with different team names * * 12 11/11/98 7:19p Jeff * changes made so that a dedicated server's team is always -1 (team game * or not) * * 11 11/02/98 11:41a Jeff * use my parse routines, and display help if the format of the command * was wrong * * 10 11/01/98 1:59a Jeff * made a $help inputcommand for help in a dedicated server environment * * 9 10/24/98 2:35p Matt * Changed "callsign" to "name" or "player name" in the multiplayer menus * and commands. * * 8 10/20/98 12:16p Jeff * added death message filter, hud callsign filter * * 7 10/15/98 1:34p Jeff * added scrollable onscreen menu. Remove ban in dmfc. prejoin event * * 6 10/08/98 3:37p Jeff * general improvements (Netgame info things, save to registry). Changes * so it would send packets on NETSEQ_OBJECTS * * 5 10/05/98 2:50p Jeff * * 4 9/30/98 3:50p Jeff * general improvements (many) * * 3 9/23/98 4:17p Jeff * basic changes/improvements, started changing death messages * * 2 9/21/98 7:11p Jeff * made InputCommand interface API and moved existing input commands to * the interface. Changed mprintf/ASSERT so they are valid in DMFC * * $NoKeywords: $ */ #include "gamedll_header.h" #include "DMFC.h" #include "dmfcinternal.h" #include extern char **DMFCStringTable; extern int DMFCStringTableSize; extern const char *_DMFCErrorString; extern DMFCBase *basethis; const char *DMFCGetString(int d); bool StringParseWord(const char *string, char *word, int size, const char **newpos) { *newpos = string; word[0] = '\0'; // get through all the whitespace while (*string && *string == ' ') string++; if (!(*string)) { // nothing is left in the string *newpos = string; return false; } // we're at the beginning of a word while (*string && *string != ' ') { if (size > 1) { *word = *string; size--; word++; } string++; } // tack on an ending \0 *word = '\0'; *newpos = string; return true; } bool StringParseNumber(const char *string, int *number, const char **newpos) { char temp[10]; bool ret = StringParseWord(string, temp, 10, newpos); if (!ret) { *number = 0; return false; } *number = atoi(temp); return true; } // handle the client wishing to change teams // Usage: "$team " where team_name is the name of the team you want to change to void DMFCInputCommand_Team(const char *input_string) { char team[100]; // parse "$team" if (!StringParseWord(input_string, team, 100, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_TEAM); return; } // parse team name if (!StringParseWord(input_string, team, 100, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_TEAM); return; } int t = basethis->GetTeamFromString(team); int curr_team = basethis->Players[basethis->GetPlayerNum()].team; if ((t == -1) || (t == curr_team) || (curr_team == -1)) return; mprintf(0, "Attempting to change teams to %s team\n", team); DLLAddHUDMessage(DTXT_TEAMCHANGEATTEMPT, team); basethis->RequestTeamChange(t, basethis->GetPlayerNum(), true); } // handle the server wanting to change the team for a player // Usage: "$changeteam " where pnum is the playernum, and team_name is the name of the // team void DMFCInputCommand_ChangeTeam(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char team[100]; int p; // parse "$changeteam" if (!StringParseWord(input_string, team, 100, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_CHANGETEAM); return; } // parse the pnum if (!StringParseNumber(input_string, &p, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_CHANGETEAM); return; } // parse the newteam name if (!StringParseWord(input_string, team, 100, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_CHANGETEAM); return; } int t = basethis->GetTeamFromString(team); int curr_team = basethis->Players[p].team; if ((!basethis->CheckPlayerNum(p)) || (t == -1) || (t == curr_team) || (curr_team == -1)) return; mprintf(0, "Attempting to change %s to %s team\n", basethis->Players[p].callsign, team); DLLAddHUDMessage(DTXT_STEAMCHANGEATTEMPT, basethis->Players[p].callsign, team); basethis->RequestTeamChange(t, p, true); } // handle the client requesting playerinfo for a player // Usage: "$playerinfo " where pnum is the playernum void DMFCInputCommand_PlayerInfo(const char *input_string) { int p; char temp[20]; // parse "$playerinfo" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_PLAYERINFO); return; } // parse pnum if (!StringParseNumber(input_string, &p, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_PLAYERINFO); return; } SwitchPlayerInfo(p); if (basethis->CheckPlayerNum(p)) { DLLAddHUDMessage(DTXT_GETPLAYERINFO, basethis->Players[p].callsign); } if (basethis->IAmDedicatedServer()) { basethis->DisplayPlayerInfo(BAD_BITMAP_HANDLE, true); } } // handle the server requesting an autobalance of teams // Usage: "$balance" void DMFCInputCommand_Balance(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; BalanceTeams(0); DLLAddHUDMessage(DTXT_BALANCETEAMMSG); } // handle turning off/on allowing the autobalancing of teams by the server // Usage: "$autobalance " if off/on is "off" (or equivalent) it will turn it off, else turn it on void DMFCInputCommand_AutoBalance(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[20]; // parse "$autobalance" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOBALANCE); return; } // parse the off/on if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOBALANCE); return; } int on = 1; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = 0; SwitchAutoTeamSelect(on); DLLAddHUDMessage(DTXT_AUTOTEAMBALANCEMSG, (on) ? DTXT_MNUON : DTXT_MNUOFF); } // handle turning off/on allowing clients to change their team // Usage: "$allowteamchange " if off/on is "off" (or equivalent) it will turn it off, else turn it on void DMFCInputCommand_AllowTeamChange(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[20]; // parse "$allowteamchange" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_ALLOWTEAMCHANGE); return; } // parse off/on if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_ALLOWTEAMCHANGE); return; } int on = 1; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = 0; SwitchTeamChange(on); DLLAddHUDMessage(DTXT_ALLOWTEAMCHANGEMSG, (on) ? DTXT_MNUON : DTXT_MNUOFF); } // handles kicking a player from the game // Usage: "$kick " where pnum is the playernumber of the player you want to kick void DMFCInputCommand_Kick(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int p; char temp[20]; // parse "$kick" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_KICK); return; } // parse pnum if (!StringParseNumber(input_string, &p, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_KICK); return; } if (!basethis->CheckPlayerNum(p)) return; KickPlayer(p); if (p != *basethis->Player_num) DLLAddHUDMessage(DTXT_KICKMSG, basethis->Players[p].callsign); } // handles banning a player from the game // Usage: "$ban " where pnum is the playernumber of the player to ban void DMFCInputCommand_Ban(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int p; char temp[20]; // parse "$ban" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_BAN); return; } // parse pnum if (!StringParseNumber(input_string, &p, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_BAN); return; } if (!basethis->CheckPlayerNum(p)) return; BanPlayer(p); if (p != *basethis->Player_num) DLLAddHUDMessage(DTXT_BANMSG, basethis->Players[p].callsign); } // handles ending the level // Usage: "$endlevel" void DMFCInputCommand_EndLevel(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; EndMultiLevel(0); DLLAddHUDMessage(DTXT_ENDLEVELMSG); } // handles the request to see all the players in the game // Usage: "$players" void DMFCInputCommand_Players(const char *input_string) { // Dedicated server print out of all the players and their player nums DPrintf(DTXT_PLAYERLISTHEADER); for (int i = 0; i < DLLMAX_PLAYERS; i++) { if (basethis->CheckPlayerNum(i)) { DPrintf("%02d: %s\n", i, basethis->Players[i].callsign); } } } // handles a request to see the scores/stats of the game (up to the mod to display the scores on request) // Usage: "$scores" void DMFCInputCommand_Scores(const char *input_string) { int level; char temp[20]; // parse $scores if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SCORES); return; } // see if there is a level if (!StringParseNumber(input_string, &level, &input_string)) level = -1; // call the event that the user want to see the scores (dedicated server basethis->CallOnPrintScores(level); } // handles a request to turn on/off displaying callsigns on the HUD during the game. // Usage: "$hudnames " full = everyone team = only teammates none = noone // NOTE: You can only set your HUD Callsign level up to the level that the server is // So if the server is only allowing up to team, you won't be able to set to full void DMFCInputCommand_HudCallsigns(const char *input_string) { char s[20]; // parse "$hudnames" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_HUDNAME); return; } // parse the level if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_HUDNAME); return; } uint8_t level = HUD_CALLSIGN_LEVEL_NONE; if (!stricmp(s, DTXT_OSM_FULL)) level = HUD_CALLSIGN_LEVEL_FULL; else if (!stricmp(s, DTXT_IC_TEAM)) level = HUD_CALLSIGN_LEVEL_TEAM; basethis->SwitchShowHudCallsignLevel(level); } // handles a request from the server to set the max HUD Callsign level // Usage: "$serverhudnames " same as $hudname but sets the max level for the server void DMFCInputCommand_ServerHudCallsigns(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[20]; // parse "$serverhudnames" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SERVERHUDNAMES); return; } // parse the level if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SERVERHUDNAMES); return; } uint8_t level = HUD_CALLSIGN_LEVEL_NONE; if (!stricmp(s, DTXT_OSM_FULL)) level = HUD_CALLSIGN_LEVEL_FULL; else if (!stricmp(s, DTXT_IC_TEAM)) level = HUD_CALLSIGN_LEVEL_TEAM; basethis->SwitchServerHudCallsignLevel(level); } // handles a request to save the game stats to file // Usage: "$savestats" void DMFCInputCommand_SaveStats(const char *input_string) { SaveStatsToFile(0); } // handles a request to enable/disable statistical messages // Usage: "$statmsgs on/off" void DMFCInputCommand_StatMsgs(const char *input_string) { char s[20]; // parse "$statmsgs" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_STATMSGS); return; } // parse the level if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_STATMSGS); return; } bool on = true; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = false; basethis->EnableStatisticalMessages(on); DLLAddHUDMessage(DTXT_STATSMSGSET, (on) ? DTXT_MNUON : DTXT_MNUOFF); } // handles a request to enable/disable the autosaving of the game stats on level end // Usage: "$autosavelevel on/off" void DMFCInputCommand_AutoSaveLevel(const char *input_string) { char s[20]; // parse "$autosavelevel" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOSAVELEVEL); return; } // parse the on/off if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOSAVELEVEL); return; } bool on = true; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = false; basethis->EnableAutoSaveLevelEnd(on); DLLAddHUDMessage(DTXT_AUTOSAVELEVELMSG, (on) ? DTXT_MNUON : DTXT_MNUOFF); } // handles a request to enable/disable the autosaving of the game stats if we disconnect // Usage: "$autosavedisconnect on/off" void DMFCInputCommand_AutoSaveDisconnect(const char *input_string) { char s[20]; // parse the "$autosavedisconnect" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOSAVEDISC); return; } if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_AUTOSAVEDISC); return; } bool on = true; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = false; basethis->EnableAutoSaveDisconnect(on); DLLAddHUDMessage(DTXT_AUTOSAVEDISCMSG, (on) ? DTXT_MNUON : DTXT_MNUOFF); } // handles changing the level time limit of a netgame on the fly // Usage: "$settimelimit " where minutes is the number of minutes void DMFCInputCommand_SetTimeLimit(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; // parse "$settimelimit" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETTIMELIMIT); return; } // parse the amount if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETTIMELIMIT); return; } if (d < 0) d = 0; basethis->Netgame->timelimit = d; if (d == 0) { basethis->Netgame->flags &= ~NF_TIMER; } else { basethis->Netgame->flags |= NF_TIMER; } if (basethis->Netgame->flags & NF_TIMER) DLLAddHUDMessage(DTXT_TIMELIMITSETMSG, d); else DLLAddHUDMessage(DTXT_TIMELIMITOFFMSG); basethis->SendNetGameInfoSync(); } // handles changing the level goal limit of a netgame on the fly // Usage: "$setgoallimit " where goal is the number of points void DMFCInputCommand_SetGoalLimit(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; // parse "$setgoallimit" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETGOALLIMIT); return; } if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETGOALLIMIT); return; } if (d < 0) d = 0; basethis->Netgame->killgoal = d; if (d == 0) { basethis->Netgame->flags &= ~NF_KILLGOAL; } else { basethis->Netgame->flags |= NF_KILLGOAL; } if (basethis->Netgame->flags & NF_KILLGOAL) DLLAddHUDMessage(DTXT_GOALLIMITSETMSG, d); else DLLAddHUDMessage(DTXT_GOALLIMITOFFMSG); basethis->SendNetGameInfoSync(); } // handles changing the number of max players in a netgame // Usage: "$setmaxplayers " where max is the maximum players void DMFCInputCommand_SetMaxPlayers(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; // parse "$setmaxplayers" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETMAXPLAYERS); return; } // parse the number if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETMAXPLAYERS); return; } // get the number of players in the game currently int curr_count = 0; for (int i = 0; i < DLLMAX_PLAYERS; i++) { if (basethis->CheckPlayerNum(i)) curr_count++; } if (d < curr_count) d = curr_count; if (d > basethis->Hard_max_players) d = basethis->Hard_max_players; basethis->Netgame->max_players = d; DLLAddHUDMessage(DTXT_MAXPLAYERSSETMSG, d); basethis->SendNetGameInfoSync(); } // handles changing the respawn time of the powerups in a level of a netgame // Usage: "$setrespawntime " where seconds is the time in seconds void DMFCInputCommand_SetRespawnTime(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; // parse "$setrespawntime" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETRESPAWNTIME); return; } // parse the value if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETRESPAWNTIME); return; } if (d < 1) d = 1; basethis->Netgame->respawn_time = d; DLLAddHUDMessage(DTXT_RESPAWNTIMEMSG, d); basethis->SendNetGameInfoSync(); } // handle the client requesting netgame info // Usage: "$netgameinfo" void DMFCInputCommand_NetGameInfo(const char *input_string) { bool display = !basethis->IsDisplayingNetGameInfo(); basethis->SwitchNetGameInfoDisplay((display) ? 1 : 0); // always display this on this input command for the dedicated server basethis->DisplayNetGameInfo(-1, true); } // handle the server changing the pps threshold of the game // Usage: "$setpps " where pps is the Packets Per Second void DMFCInputCommand_SetPPS(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; //"$setpps" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETPPS); return; } // parse value if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETPPS); return; } if (d < 1) d = 1; if (d > 20) d = 20; basethis->Netgame->packets_per_second = d; DLLAddHUDMessage(DTXT_PPSSETMSG, d); basethis->SendNetGameInfoSync(); } // handles listing the ban list on a dedicated server (so if you want to remove a player from it) // Usage: "$banlist" void DMFCInputCommand_BanList(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int size = basethis->GetNumBannedPlayers(); char buffer[100]; for (int i = 0; i < size; i++) { char *ptr = basethis->GetBannedPlayerCallsign(i); if (ptr) { snprintf(buffer, sizeof(buffer), "[%d]%s\n", i, ptr); DPrintf(buffer); } } } // handles removing a ban from a player, given the ban index num (see $banlist) // Usage: "$removeban " where bannum is the number corresponding to that given during a $banlist void DMFCInputCommand_RemoveBan(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; int d; char temp[20]; //"$removeban" if (!StringParseWord(input_string, temp, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOVEBAN); return; } // value if (!StringParseNumber(input_string, &d, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOVEBAN); return; } if (basethis->RemoveBan(d)) { DLLAddHUDMessage(DTXT_BANREMOVEDMSG); DPrintf(DTXT_BANREMOVEDMSG); } else { DLLAddHUDMessage(DTXT_BANNOTREMOVEDMSG); DPrintf(DTXT_BANNOTREMOVEDMSG); } } // handles changing the filter for death messages // Usage: "$killmsgfilter " void DMFCInputCommand_KillMsgFilter(const char *input_string) { char s[20]; //"$killmsgfilter" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_KILLMSGFILTER); return; } // parse level if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_KILLMSGFILTER); return; } uint8_t level = DM_FILTER_FULL; if (!stricmp(s, DTXT_PLAIN_NONE)) level = DM_FILTER_NONE; else if (!stricmp(s, DTXT_OSM_SIMPLE)) level = DM_FILTER_SIMPLE; basethis->SetDeathMessageFilter(level); } // handles the server changing a team's name // Usage: "$setteamname void DMFCInputCommand_SetTeamName(const char *input_string) { char s[20]; int team; // parse "$setteamname" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETTEAMNAME); return; } // parse team_num if (!StringParseNumber(input_string, &team, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETTEAMNAME); return; } if (team < 0 || team > DLLMAX_TEAMS) { DLLAddHUDMessage(DTXT_INVALIDTEAM, DLLMAX_TEAMS - 1); basethis->DisplayInputCommandHelp(DTXT_IC_SETTEAMNAME); return; } // parse team_name if (!StringParseWord(input_string, s, std::min(MAX_TEAMNAME_LEN, 20), &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_SETTEAMNAME); return; } basethis->SetTeamName(team, s, true); } // handles a request for help to see a list of commands, dedicated server only // Usage: "$help [command]" void DMFCInputCommand_Help(const char *input_string) { char s[20]; // parse "$help" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_HELP); return; } // see if there is another command if (!StringParseWord(input_string, s, 20, &input_string)) { s[0] = '\0'; } basethis->DisplayInputCommandHelp(s); } // handles a request to rehash the hosts.allow/deny // Usage: "$rehash" void DMFCInputCommand_Rehash(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; RehashAllowDenyLists(0); } // handles a request to enter/leave observer mode // Usage: "$observer " void DMFCInputCommand_Observer(const char *input_string) { if (basethis->IAmDedicatedServer()) { DPrintf(DTXT_NOTINDEDICATED); return; } char s[20]; bool turn_on = true; object *pobj; int pnum = basethis->GetPlayerNum(); pobj = &basethis->Objects[basethis->Players[pnum].objnum]; // parse "$observer" StringParseWord(input_string, s, 20, &input_string); // see if there is another command if (StringParseWord(input_string, s, 20, &input_string)) { if (stricmp(s, DTXT_MNUON)) turn_on = false; } else { if (pobj->type == OBJ_OBSERVER) { turn_on = false; } else { turn_on = true; } } if (!basethis->CallOnAllowObserverChange(turn_on)) { DLLAddHUDMessage(DTXT_OBSERVERDENIED); return; } mprintf(0, "SwitchObserverMode %s [%d]\n", (turn_on) ? "On" : "Off", pnum); DLLMultiSendRequestToObserve(OBSERVER_MODE_ROAM, (turn_on) ? 1 : 0, 0); } // handles a request to piggyback a player // Usage: "$piggyback " void DMFCInputCommand_Piggyback(const char *input_string) { if (basethis->IAmDedicatedServer()) { DPrintf(DTXT_NOTINDEDICATED); return; } char s[20]; bool turn_on = true; object *pobj; int pnum = basethis->GetPlayerNum(); pobj = &basethis->Objects[basethis->Players[pnum].objnum]; int topnum = -1; // parse "$piggyback" StringParseWord(input_string, s, 20, &input_string); if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_PIGGYBACK); return; } char *ptr = s; while (*ptr) { if (!isdigit(*ptr)) { basethis->DisplayInputCommandHelp(DTXT_IC_PIGGYBACK); return; } ptr++; } topnum = atoi(s); if (!basethis->CheckPlayerNum(topnum)) { DLLAddHUDMessage(DTXT_INVALIDPNUM); return; } if (pobj->type == OBJ_OBSERVER) { if (basethis->CallOnAllowObserverChange(false)) DLLMultiSendRequestToObserve(OBSERVER_MODE_ROAM, 0, 0); } if (pnum == basethis->GetPlayerNum()) { mprintf(0, "Returning to self\n"); return; } if (basethis->CallOnAllowObserverChange(true)) { mprintf(0, "Switching to piggyback for player %d\n", topnum); DLLMultiSendRequestToObserve(OBSERVER_MODE_PIGGYBACK, 1, basethis->Players[topnum].objnum); } } // handles a request to warp to another level // Usage: "$warp " void DMFCInputCommand_Warp(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[20]; int level; // parse "$warp" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_WARP); return; } // parse levelnum if (!StringParseNumber(input_string, &level, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_WARP); return; } basethis->WarpToLevel(level); } // handles enable/disable remote administration // Usage: "$remoteadmin " extern bool Use_remote_admin; void DMFCInputCommand_RemoteAdmin(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[20]; // parse "$remoteadmin" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOTEADMIN); return; } // parse the off/on if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOTEADMIN); return; } int on = 1; if (!strnicmp(s, DTXT_MNUOFF, strlen(DTXT_MNUOFF))) on = 0; Remote_Enable((bool)(on != 0)); if (on && !Use_remote_admin) { // no password set DLLAddHUDMessage(DTXT_UNABLETOREMOTE); } else { DLLAddHUDMessage(DTXT_REMOTEADMINENABLE, (Use_remote_admin) ? DTXT_MNUON : DTXT_MNUOFF); } } // handles setting/changing the remote administration password // Usage: "$remoteadminpass " void DMFCInputCommand_RemoteAdminPass(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[64]; // parse "$remoteadminpass" if (!StringParseWord(input_string, s, 20, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOTEADMINPASS); return; } // parse the password if (!StringParseWord(input_string, s, 64, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOTEADMINPASS); return; } Remote_SetPassword(s); DLLAddHUDMessage(DTXT_REMOTEADMINPASS); } // handles seeing who is logged in, and allows the server to log them out // If no parameter is given it lists all the players logged in. // To log out a player give the login-id as a parameter // Usage: "$remoteadminlogout [login-id]" void DMFCInputCommand_RemoteAdminLogout(const char *input_string) { if (basethis->GetLocalRole() != LR_SERVER) return; char s[64]; // parse "$remoteadminlogout" if (!StringParseWord(input_string, s, 64, &input_string)) { basethis->DisplayInputCommandHelp(DTXT_IC_REMOTEADMINLOGOUT); return; } // see if there is another command if (!StringParseWord(input_string, s, 64, &input_string)) { // list who is logged in Remote_ListLogins(); return; } // logout int prec = atoi(s); Remote_Logout(prec); } // handles a remote admin command // Usage: "$remote