X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcommand%2Fsv_cmd.qc;h=bb6074517ebe517aa4d926fd84a237ffcb47430b;hb=aaf1761cd58aef0700bf02f094dfc11b68d0091e;hp=47e9f922abe4daf27b5f8e696b05ff87b908d654;hpb=219f56360ab1d5207d3275deaf110c10e61e9436;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 47e9f922a..bb6074517 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -21,8 +21,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -89,6 +91,11 @@ void GameCommand_adminmsg(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } entity client; float accepted; @@ -141,7 +148,7 @@ void GameCommand_adminmsg(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd adminmsg \"\" []"); @@ -161,7 +168,18 @@ void GameCommand_allready(int request) { case CMD_REQUEST_COMMAND: { - ReadyRestart(); + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } + if(warmup_stage) + { + ReadyRestart(true); + } + else + LOG_INFO("Not in warmup."); + return; } @@ -181,10 +199,15 @@ void GameCommand_allspec(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } string reason = argv(1); int n = 0; FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { - PutObserverInServer(it, true); + PutObserverInServer(it, true, true); ++n; }); if (n) bprint(strcat("Successfully forced all (", ftos(n), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n")); @@ -209,6 +232,11 @@ void GameCommand_anticheat(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } entity client = GetIndexedEntity(argc, 1); float accepted = VerifyClientEntity(client, false, false); @@ -224,7 +252,7 @@ void GameCommand_anticheat(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd anticheat "); @@ -313,6 +341,11 @@ void GameCommand_bot_cmd(int request, int argc, string command) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } entity bot; if (argv(1) == "reset") @@ -326,9 +359,9 @@ void GameCommand_bot_cmd(int request, int argc, string command) cvar_settemp("minplayers", "0"); cvar_settemp("minplayers_per_team", "0"); cvar_settemp("bot_number", "0"); - bot_fixcount(); + bot_fixcount(false); // Kill all bots. cvar_settemp("bot_number", argv(2)); - if (!bot_fixcount()) LOG_INFO("Sorry, could not set requested bot count"); + if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count"); return; } else if (argv(1) == "load" && argc == 3) @@ -359,9 +392,9 @@ void GameCommand_bot_cmd(int request, int argc, string command) cvar_settemp("minplayers", "0"); cvar_settemp("minplayers_per_team", "0"); cvar_settemp("bot_number", "0"); - bot_fixcount(); + bot_fixcount(false); // Kill all bots. cvar_settemp("bot_number", argv(3)); - if (!bot_fixcount()) LOG_INFO("Sorry, could not set requested bot count"); + if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count"); } else { @@ -426,14 +459,14 @@ void GameCommand_bot_cmd(int request, int argc, string command) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd bot_cmd []"); LOG_HELP(" can be either the name of the bot or a progressive number (not the entity number!)"); LOG_HELP(" can also be '*' or 'all' to allow sending the command to all the bots"); LOG_HELP(" For full list of commands, see bot_cmd help []."); - LOG_HELP("Examples: sv_cmd bot_cmd 1 cc \"say something\""); + LOG_HELP("Examples: sv_cmd bot_cmd 1 cc say something"); LOG_HELP(" sv_cmd bot_cmd 1 presskey jump"); LOG_HELP(" sv_cmd bot_cmd * pause"); return; @@ -447,6 +480,11 @@ void GameCommand_cointoss(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } string result1 = (argv(2) ? strcat("^7", argv(1)) : "^1HEADS"); string result2 = (argv(2) ? strcat("^7", argv(2)) : "^4TAILS"); string choice = ((random() > 0.5) ? result1 : result2); @@ -496,7 +534,7 @@ void GameCommand_database(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd database "); @@ -514,6 +552,11 @@ void GameCommand_defer_clear(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } entity client; float accepted; @@ -534,7 +577,7 @@ void GameCommand_defer_clear(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd defer_clear "); @@ -551,6 +594,11 @@ void GameCommand_defer_clear_all(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } int n = 0; int argc; @@ -589,7 +637,7 @@ void GameCommand_delrec(int request, int argc) // perhaps merge later with reco } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd delrec []"); @@ -693,6 +741,11 @@ void GameCommand_extendmatchtime(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } changematchtime(autocvar_timelimit_increment * 60, autocvar_timelimit_min * 60, autocvar_timelimit_max * 60); return; } @@ -716,43 +769,29 @@ void GameCommand_gametype(int request, int argc) { if (!world_initialized) { - LOG_INFOF("This command works only when the server is running."); + LOG_HELPF("This command works only when the server is running."); return; } if (argv(1) != "") { string s = argv(1); - Gametype t = MapInfo_Type_FromString(s, false), tsave = MapInfo_CurrentGametype(); + Gametype t = MapInfo_Type_FromString(s, false, false); if (t) { - MapInfo_SwitchGameType(t); - MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); - if (MapInfo_count > 0) - { - // update lsmaps in case the gametype changed, this way people can easily list maps for it - if (lsmaps_reply != "") strunzone(lsmaps_reply); - lsmaps_reply = strzone(getlsmaps()); - bprint("Game type successfully switched to ", s, "\n"); - } - else - { - bprint("Cannot use this game type: no map for it found\n"); - MapInfo_SwitchGameType(tsave); - MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); - } + // don't execute gametype hooks because they can change active + // gametype rules if executed during the game + GameTypeVote_SetGametype(t, "", false); } else - { bprint("Failed to switch to ", s, ": this game type does not exist!\n"); - } return; } } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd gametype "); @@ -817,7 +856,7 @@ void GameCommand_gettaginfo(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd gettaginfo [] []"); @@ -876,7 +915,7 @@ void GameCommand_animbench(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd animbench "); @@ -894,7 +933,7 @@ void GameCommand_gotomap(int request, int argc) { if (!world_initialized) { - LOG_INFOF("This command works only when the server is running."); + LOG_HELPF("This command works only when the server is running."); return; } if (argv(1)) @@ -905,7 +944,7 @@ void GameCommand_gotomap(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd gotomap "); @@ -922,6 +961,11 @@ void GameCommand_lockteams(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } if (teamplay) { lockteams = 1; @@ -977,6 +1021,11 @@ void GameCommand_moveplayer(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } float accepted; entity client; @@ -998,6 +1047,7 @@ void GameCommand_moveplayer(int request, int argc) // Check to see if the player is a valid target client = GetFilteredEntity(t); accepted = VerifyClientEntity(client, false, false); + string client_num_str = ftos(etof(client)); if (accepted <= 0) { @@ -1006,15 +1056,15 @@ void GameCommand_moveplayer(int request, int argc) else if (destination == "spectator") { string pl_name = playername(client.netname, client.team, false); - if (!IS_SPEC(client) && !IS_OBSERVER(client)) + if (!(IS_SPEC(client) || IS_OBSERVER(client)) || INGAME(client)) { - PutObserverInServer(client, true); + PutObserverInServer(client, true, true); successful = strcat(successful, (successful ? ", " : ""), pl_name); } else { - LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", pl_name, ") is already spectating."); + LOG_INFO("Player #", client_num_str, " (", pl_name, ") is already spectating."); } } else @@ -1029,7 +1079,7 @@ void GameCommand_moveplayer(int request, int argc) if (IS_SPEC(client) || IS_OBSERVER(client)) { // well technically we could, but should we allow that? :P - LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", pl_name, ") is not in the game."); + LOG_INFO("Player #", client_num_str, " (", pl_name, ") is not in the game."); continue; } @@ -1043,7 +1093,8 @@ void GameCommand_moveplayer(int request, int argc) if (team_num == client.team) // already on the destination team { // keep the forcing undone - LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", pl_name, ") is already on the ", Team_ColoredFullName(team_num), "."); + LOG_INFO("Player #", client_num_str, " (", pl_name, ") is already on the ", + Team_ColoredFullName(team_num), "."); continue; } else if (team_num == 0) // auto team @@ -1061,16 +1112,23 @@ void GameCommand_moveplayer(int request, int argc) int team_id = Team_TeamToIndex(team_num); if (team_id == -1) { - LOG_INFO("Sorry, can't move player here if team ", destination, " doesn't exist."); + LOG_INFO("Can't move player to ", destination, " team because it doesn't exist."); TeamBalance_Destroy(balance); return; } - if (!TeamBalance_IsTeamAllowed(balance, team_id)) + if (!IsTeamAvailable(team_num)) { - LOG_INFOF("Sorry, can't move player to %s team if it doesn't exist.", destination); + LOG_INFO("Can't move player to ", destination, " team because it isn't available."); TeamBalance_Destroy(balance); return; } + if (!TeamBalance_IsTeamAllowed(balance, team_id)) + { + LOG_INFO("Player #", client_num_str, " (", pl_name, ") is not allowed to join the ", + Team_ColoredFullName(team_num), "."); + TeamBalance_Destroy(balance); + continue; + } TeamBalance_Destroy(balance); // If so, lets continue and finally move the player @@ -1078,11 +1136,12 @@ void GameCommand_moveplayer(int request, int argc) if (MoveToTeam(client, team_id, 6)) { successful = strcat(successful, (successful ? ", " : ""), pl_name); - LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", pl_name, ") has been moved to the ", Team_ColoredFullName(team_num), "^7."); + LOG_INFO("Player #", client_num_str, " (", pl_name, ") has been moved to the ", + Team_ColoredFullName(team_num), "."); } else { - LOG_INFO("Unable to move player ", ftos(GetFilteredNumber(t)), " (", pl_name, ")"); + LOG_INFO("Unable to move player #", client_num_str, " (", pl_name, ")"); } } } // loop end @@ -1095,7 +1154,7 @@ void GameCommand_moveplayer(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd moveplayer "); @@ -1116,14 +1175,16 @@ void GameCommand_nospectators(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } blockSpectators = 1; // give every spectator seconds time to become a player - FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !it.caplayer, { - if(!it.caplayer) - { - CS(it).spectatortime = time; - Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); - } + FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !INGAME(it), { + CS(it).spectatortime = time; + Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); }); bprint(strcat("^7All spectators will be automatically kicked when not joining the game after ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds!\n")); return; @@ -1145,6 +1206,11 @@ void GameCommand_printstats(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } DumpStats(false); LOG_INFO("stats dumped."); return; @@ -1170,7 +1236,7 @@ void GameCommand_radarmap(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd radarmap [--force] [--loop] [--quit] [--block | --trace | --sample | --lineblock] [--sharpen N] [--res W H] [--qual Q]"); @@ -1188,6 +1254,11 @@ void GameCommand_reducematchtime(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } changematchtime(autocvar_timelimit_decrement * -60, autocvar_timelimit_min * 60, autocvar_timelimit_max * 60); return; } @@ -1214,13 +1285,13 @@ void GameCommand_setbots(int request, int argc) cvar_settemp("minplayers", "0"); cvar_settemp("minplayers_per_team", "0"); cvar_settemp("bot_number", argv(1)); - bot_fixcount(); + bot_fixcount(true); return; } } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd setbots "); @@ -1239,7 +1310,7 @@ void shuffleteams() return; } - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { if (Player_HasRealForcedTeam(it)) { // we could theoretically assign forced players to their teams // and shuffle the rest to fill the empty spots but in practise @@ -1261,7 +1332,7 @@ void shuffleteams() TeamBalance_Destroy(balance); int team_index = 0; - FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || INGAME(it), { int target_team_index = team_index + 1; if (Entity_GetTeamIndex(it) != target_team_index) { @@ -1279,6 +1350,11 @@ void GameCommand_shuffleteams(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } if (shuffleteams_on_reset_map) { bprint("Players will be shuffled when this round is over.\n"); @@ -1300,6 +1376,31 @@ void GameCommand_shuffleteams(int request) } } +void GameCommand_resetmatch(int request) +{ + switch (request) + { + case CMD_REQUEST_COMMAND: + { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } + ReadyRestart(false); + return; + } + + default: + case CMD_REQUEST_USAGE: + { + LOG_HELP("Usage:^3 sv_cmd resetmatch"); + LOG_HELP(" No arguments required."); + return; + } + } +} + void GameCommand_stuffto(int request, int argc) { // This... is a fairly dangerous and powerful command... - It allows any arguments to be sent to a client via rcon. @@ -1311,6 +1412,11 @@ void GameCommand_stuffto(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } if (argv(2)) { entity client = GetIndexedEntity(argc, 1); @@ -1331,7 +1437,7 @@ void GameCommand_stuffto(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd stuffto \"\""); @@ -1512,7 +1618,7 @@ void GameCommand_trace(int request, int argc) } default: - LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0)); + LOG_HELPF("Incorrect parameters for ^2%s^7", argv(0)); case CMD_REQUEST_USAGE: { LOG_HELP("Usage:^3 sv_cmd trace [ ] []"); @@ -1531,6 +1637,11 @@ void GameCommand_unlockteams(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } if (teamplay) { lockteams = 0; @@ -1560,6 +1671,11 @@ void GameCommand_warp(int request, int argc) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } if (autocvar_g_campaign) { if (argc >= 2) @@ -1599,6 +1715,11 @@ void GameCommand_(int request) { case CMD_REQUEST_COMMAND: { + if (!world_initialized) + { + LOG_HELPF("This command works only when the server is running."); + return; + } return; } @@ -1621,7 +1742,7 @@ void GameCommand_(int request) // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;) SERVER_COMMAND(adminmsg, "Send an admin message to a client directly") { GameCommand_adminmsg(request, arguments); } -SERVER_COMMAND(allready, "Restart the server and reset the players") { GameCommand_allready(request); } +SERVER_COMMAND(allready, "Ends warmup and starts the match") { GameCommand_allready(request); } SERVER_COMMAND(allspec, "Force all players to spectate") { GameCommand_allspec(request, arguments); } SERVER_COMMAND(anticheat, "Create an anticheat report for a client") { GameCommand_anticheat(request, arguments); } SERVER_COMMAND(animbench, "Benchmark model animation (LAGS)") { GameCommand_animbench(request, arguments); } @@ -1644,6 +1765,7 @@ SERVER_COMMAND(nospectators, "Automatically remove spectators from a match") { G SERVER_COMMAND(printstats, "Dump eventlog player stats and other score information") { GameCommand_printstats(request); } SERVER_COMMAND(radarmap, "Generate a radar image of the map") { GameCommand_radarmap(request, arguments); } SERVER_COMMAND(reducematchtime, "Decrease the timelimit value incrementally") { GameCommand_reducematchtime(request); } +SERVER_COMMAND(resetmatch, "Soft restart the game without changing teams; goes back to warmup if enabled") { GameCommand_resetmatch(request); } SERVER_COMMAND(setbots, "Adjust how many bots are in the match") { GameCommand_setbots(request, arguments); } SERVER_COMMAND(shuffleteams, "Randomly move players to different teams") { GameCommand_shuffleteams(request); } SERVER_COMMAND(stuffto, "Send a command to be executed on a client") { GameCommand_stuffto(request, arguments); }