diff --git a/documentation/docs/getting_started.md b/documentation/docs/getting_started.md index 185b387a8..f14cacbcc 100644 --- a/documentation/docs/getting_started.md +++ b/documentation/docs/getting_started.md @@ -7,12 +7,11 @@ ## Quick Start {: #quick-start } -If you want to create a match quickly without modifying anything, you must set two properties: +If you want to create a match quickly without modifying anything, you must set: -1. [`get5_check_auths 0`](../configuration/#get5_check_auths) -2. [`get5_kick_when_no_match_loaded 0`](../configuration/#get5_kick_when_no_match_loaded) +[`get5_kick_when_no_match_loaded 0`](../configuration/#get5_kick_when_no_match_loaded) -Once these are disabled, anyone can join the server and they will not be kicked for not being a part of a match. +Once this is disabled, anyone can join the server without being kicked for not being a part of a match. Once all players are connected to the server and on correct teams, just call [`get5_creatematch`](../commands/#get5_creatematch). There is also a simple menu that you can call this command from by typing [`!get5`](../commands/#get5) in the game chat. Note that you must diff --git a/scripting/get5.sp b/scripting/get5.sp index de01988d8..38d4cb02b 100644 --- a/scripting/get5.sp +++ b/scripting/get5.sp @@ -1482,9 +1482,11 @@ static Action Event_RoundStart(Event event, const char[] name, bool dontBroadcas // potentially ghost, depending on where the camera drops them. Especially important for coaches. // We do this step *before* we write the backup, so we don't have any lingering players in case of // a restore. - LOOP_CLIENTS(i) { - if (IsPlayer(i) && GetClientTeam(i) == CS_TEAM_NONE) { - CheckClientTeam(i); + if (g_CheckAuthsCvar.BoolValue) { + LOOP_CLIENTS(i) { + if (IsPlayer(i) && GetClientTeam(i) == CS_TEAM_NONE) { + CheckClientTeam(i); + } } } @@ -1730,9 +1732,9 @@ static void SetServerStateOnStartup(bool force) { // Only run on first client connect or if forced (during OnConfigsExecuted). return; } - // It shouldn't really be possible to end up here, as the server *should* reload the map anyway when first player - // joins, but as a safeguard we don't want to move a live game that's not pending a backup or map change into warmup - // on player connect. + // It shouldn't really be possible to end up here, as the server *should* reload the map anyway + // when first player joins, but as a safeguard we don't want to move a live game that's not + // pending a backup or map change into warmup on player connect. if (!force && g_GameState == Get5State_Live && !g_WaitingForRoundBackup && !g_MapChangePending) { return; } diff --git a/scripting/get5/backups.sp b/scripting/get5/backups.sp index fd8cbca73..fa952d610 100644 --- a/scripting/get5/backups.sp +++ b/scripting/get5/backups.sp @@ -448,9 +448,11 @@ bool RestoreFromBackup(const char[] path, bool restartRecording = true) { } else { // We must assign players to their teams. This is normally done inside LoadMatchConfig, but // since we need the team sides to be applied from the backup, we skip it then and do it here. - LOOP_CLIENTS(i) { - if (IsPlayer(i)) { - CheckClientTeam(i); + if (g_CheckAuthsCvar.BoolValue) { + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + CheckClientTeam(i); + } } } if (g_WaitingForRoundBackup) { @@ -486,10 +488,11 @@ bool RestoreFromBackup(const char[] path, bool restartRecording = true) { void RestoreGet5Backup(bool restartRecording = true) { // If you load a backup during a live round, the game might get stuck if there are only bots - // remaining and no players are alive. Other stuff will probably also go wrong, so we just reset - // the game before loading the backup to avoid any weird edge-cases. + // remaining and no players are alive. Other stuff will probably also go wrong, so we put the game + // into warmup. We **cannot** restart the game as that causes problems for tournaments using the + // logging system. if (!InWarmup()) { - RestartGame(); + StartWarmup(); } ExecCfg(g_LiveCfgCvar); PauseGame(Get5Team_None, Get5PauseType_Backup); @@ -537,9 +540,11 @@ static Action Timer_StartRestore(Handle timer) { static Action Timer_FinishBackup(Handle timer) { // This ensures that coaches are moved to their slots. - LOOP_CLIENTS(i) { - if (IsPlayer(i)) { - CheckClientTeam(i); + if (g_CheckAuthsCvar.BoolValue) { + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + CheckClientTeam(i); + } } } g_DoingBackupRestoreNow = false; diff --git a/scripting/get5/kniferounds.sp b/scripting/get5/kniferounds.sp index be5848144..a5b5f6d3b 100644 --- a/scripting/get5/kniferounds.sp +++ b/scripting/get5/kniferounds.sp @@ -39,15 +39,21 @@ static void PerformSideSwap(bool swap) { g_TeamSide[Get5Team_2] = g_TeamSide[Get5Team_1]; g_TeamSide[Get5Team_1] = tmp; + Get5Side currentSide; + Get5Side coachingSide; LOOP_CLIENTS(i) { - if (IsValidClient(i) && !IsClientSourceTV(i)) { - if (IsFakeClient(i)) { - // Because bots never have an assigned team, they won't be moved around by - // CheckClientTeam. We kick them to prevent one team from having too many players. They - // will rejoin if defined in the live config. - KickClient(i); - } else { - CheckClientTeam(i, false); + if (!IsPlayer(i)) { + continue; + } + currentSide = view_as(GetClientTeam(i)); + if (currentSide == Get5Side_T) { + SwitchPlayerTeam(i, Get5Side_CT, false); + } else if (currentSide == Get5Side_CT) { + SwitchPlayerTeam(i, Get5Side_T, false); + } else { + coachingSide = GetClientCoachingSide(i); + if (coachingSide != Get5Side_None) { + SetClientCoaching(i, coachingSide == Get5Side_CT ? Get5Side_T : Get5Side_CT, false); } } } diff --git a/scripting/get5/matchconfig.sp b/scripting/get5/matchconfig.sp index 4d428c851..3325d66ed 100644 --- a/scripting/get5/matchconfig.sp +++ b/scripting/get5/matchconfig.sp @@ -166,12 +166,14 @@ bool LoadMatchConfig(const char[] config, bool restoreBackup = false) { // skip team none, as players may also just be on the team selection menu when the match is // loaded, meaning they will never have a joingame hook, as it already happened, and we still // want those players placed. - LOOP_CLIENTS(i) { - if (IsPlayer(i)) { - if (GetClientTeam(i) == CS_TEAM_NONE) { - CreateTimer(1.0, Timer_PlacePlayerFromTeamNone, i, TIMER_FLAG_NO_MAPCHANGE); - } else { - CheckClientTeam(i); + if (g_CheckAuthsCvar.BoolValue) { + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + if (GetClientTeam(i) == CS_TEAM_NONE) { + CreateTimer(1.0, Timer_PlacePlayerFromTeamNone, i, TIMER_FLAG_NO_MAPCHANGE); + } else { + CheckClientTeam(i); + } } } } @@ -655,16 +657,20 @@ static void LoadTeamData(KeyValues kv, Get5Team matchTeam) { static void FormatTeamName(const Get5Team team) { char color[32]; + char teamNameFallback[MAX_CVAR_LENGTH]; if (team == Get5Team_1) { g_Team1NameColorCvar.GetString(color, sizeof(color)); + teamNameFallback = "team1"; } else if (team == Get5Team_2) { g_Team2NameColorCvar.GetString(color, sizeof(color)); + teamNameFallback = "team2"; } else if (team == Get5Team_Spec) { g_SpecNameColorCvar.GetString(color, sizeof(color)); } else { color = "{NORMAL}"; } - Format(g_FormattedTeamNames[team], MAX_CVAR_LENGTH, "%s%s{NORMAL}", color, g_TeamNames[team]); + Format(g_FormattedTeamNames[team], MAX_CVAR_LENGTH, "%s%s{NORMAL}", color, + strlen(g_TeamNames[team]) > 0 ? g_TeamNames[team] : teamNameFallback); } static void LoadDefaultMapList(ArrayList list) { diff --git a/scripting/get5/teamlogic.sp b/scripting/get5/teamlogic.sp index 2bfbf502a..24f7eb46f 100644 --- a/scripting/get5/teamlogic.sp +++ b/scripting/get5/teamlogic.sp @@ -9,12 +9,8 @@ Action Command_JoinGame(int client, const char[] command, int argc) { } } -void CheckClientTeam(int client, bool useDefaultTeamSelection = true) { - if (!g_CheckAuthsCvar.BoolValue || IsFakeClient(client)) { - // Teams are not enforced; do nothing. - return; - } - +// Assumes client IsPlayer(). +void CheckClientTeam(int client) { Get5Team correctTeam = GetClientMatchTeam(client); if (correctTeam == Get5Team_None) { RememberAndKickClient(client, "%t", "YouAreNotAPlayerInfoMessage"); @@ -44,7 +40,7 @@ void CheckClientTeam(int client, bool useDefaultTeamSelection = true) { // If player was not locked to coaching, check if their team's current size -self is less than the // max. if (CountPlayersOnTeam(correctTeam, client) < g_PlayersPerTeam) { - SwitchPlayerTeam(client, correctSide, useDefaultTeamSelection); + SwitchPlayerTeam(client, correctSide); return; } @@ -92,7 +88,7 @@ static bool IsClientCoachForTeam(int client, Get5Team team) { return GetAuth(client, clientAuth64, AUTH_LENGTH) && IsAuthOnTeamCoach(clientAuth64, team); } -void SetClientCoaching(int client, Get5Side side) { +void SetClientCoaching(int client, Get5Side side, bool broadcast = true) { if (GetClientCoachingSide(client) == side) { return; } @@ -103,6 +99,9 @@ void SetClientCoaching(int client, Get5Side side) { SetEntProp(client, Prop_Send, "m_iAccount", 0); // Ensures coaches have no money if they were to rejoin the game. + if (!broadcast) { + return; + } char formattedPlayerName[MAX_NAME_LENGTH]; Get5Team team = GetClientMatchTeam(client); FormatPlayerName(formattedPlayerName, sizeof(formattedPlayerName), client, team); @@ -110,7 +109,7 @@ void SetClientCoaching(int client, Get5Side side) { } void CoachingChangedHook(ConVar convar, const char[] oldValue, const char[] newValue) { - if (g_GameState == Get5State_None) { + if (g_GameState == Get5State_None || !g_CheckAuthsCvar.BoolValue) { return; } // If disabling coaching, make sure we swap coaches to team or kick them, as they are now regular @@ -126,7 +125,17 @@ void CoachingChangedHook(ConVar convar, const char[] oldValue, const char[] newV } Action Command_SmCoach(int client, int args) { - if (g_GameState == Get5State_None) { + if (g_GameState == Get5State_None || !IsPlayer(client)) { + return Plugin_Continue; + } + + if (!g_CheckAuthsCvar.BoolValue) { + Get5Side side = view_as(GetClientTeam(client)); + if (side == Get5Side_CT) { + FakeClientCommand(client, "coach ct"); + } else if (side == Get5Side_T) { + FakeClientCommand(client, "coach t"); + } return Plugin_Continue; } @@ -220,7 +229,7 @@ static void MoveCoachToPlayerInConfig(const int client, const Get5Team team) { } Action Command_Coach(int client, const char[] command, int argc) { - if (g_GameState == Get5State_None) { + if (g_GameState == Get5State_None || !g_CheckAuthsCvar.BoolValue) { return Plugin_Continue; } ReplyToCommand( @@ -330,7 +339,7 @@ bool IsClientCoaching(int client) { return GetClientCoachingSide(client) != Get5Side_None; } -static Get5Side GetClientCoachingSide(int client) { +Get5Side GetClientCoachingSide(int client) { if (GetClientTeam(client) != CS_TEAM_SPECTATOR) { return Get5Side_None; } diff --git a/scripting/get5/version.sp b/scripting/get5/version.sp index 8b9e2220a..9efba1d82 100644 --- a/scripting/get5/version.sp +++ b/scripting/get5/version.sp @@ -1,6 +1,6 @@ #tryinclude "manual_version.sp" #if !defined PLUGIN_VERSION -#define PLUGIN_VERSION "0.10.0-dev" +#define PLUGIN_VERSION "0.10.1-dev" #endif // This MUST be the latest version in x.y.z semver format followed by -dev.