Skip to content

Commit

Permalink
Bring in check to not allow users the ability to unpause admin pauses. (
Browse files Browse the repository at this point in the history
#767)

Bring in check to not allow users the ability to unpause admin pauses.
Remove amibiguous extended pause and introduce new enums for pause types.
Remove duplicate ServerCommand since it appears in both clauses of if statement.
Reset state in tech pauses in case an admin unpauses.
Add small documentation note in commands about pausing as an admin.
  • Loading branch information
PhlexPlexico authored Jul 7, 2022
1 parent 62bb039 commit 9250c82
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.zip
*.tar.gz
builds
.vscode/
14 changes: 10 additions & 4 deletions documentation/docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ Please note that these are meant to be used by *admins* in console.
- `get5_listbackups <matchid>`: Lists backup files for the current matchid or a given matchid if not provided.
- `get5_ringer <player>`: Adds/removes a ringer to/from the home scrim team.
- `sm_ringer <player>`: Same as `get5_ringer`.
- `get5_debuginfo <file>`: Dumps debug info to a file (`addons/sourcemod/logs/get5_debuginfo.txt` by default, if no file
provided).
- `get5_test`: Runs get5 tests. **This should not be used on a live match server since it will reload a match config to
test**.
- `get5_debuginfo <file>`: Dumps debug info to a file (addons/sourcemod/logs/get5_debuginfo.txt by default, if no file provided).
- `get5_test`: Runs get5 tests. **This should not be used on a live match server since it will reload a match config to test**.


### Pause Commands

A small note on pause commands. As a server admin, you should not be calling pauses using `mp_pause_match` is **not** recommended.
This is due to the way Get5 handles pausing in game. It is recommended you either use `!pause` in chat as a player, or `sm_pause`
in the console, since this will track all details and configurations related to pausing in the system. There is currently no hook
into `mp_pause_match`, so it must be hooked using an `sm` call.
2 changes: 1 addition & 1 deletion scripting/get5.sp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ int g_TeamSide[MATCHTEAM_COUNT]; // Current CS_TEAM_* side for the te
int g_TeamStartingSide[MATCHTEAM_COUNT];
bool g_TeamReadyForUnpause[MATCHTEAM_COUNT];
bool g_TeamGivenStopCommand[MATCHTEAM_COUNT];
bool g_InExtendedPause;
PauseType g_PauseType = PauseType_None;
int g_TeamPauseTimeUsed[MATCHTEAM_COUNT];
int g_TeamPausesUsed[MATCHTEAM_COUNT];
int g_TeamTechPausesUsed[MATCHTEAM_COUNT];
Expand Down
4 changes: 2 additions & 2 deletions scripting/get5/backups.sp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ public void RestoreGet5Backup() {
EndWarmup();
EndWarmup();
ServerCommand("mp_restartgame 5");
Pause();
Pause(PauseType_Tech);
} else {
EnsurePausedWarmup();
}
Expand All @@ -360,7 +360,7 @@ public void RestoreGet5Backup() {
}

public Action Time_StartRestore(Handle timer) {
Pause();
Pause(PauseType_Tech);

char tempValveBackup[PLATFORM_MAX_PATH];
GetTempFilePath(tempValveBackup, sizeof(tempValveBackup), TEMP_VALVE_BACKUP_PATTERN);
Expand Down
2 changes: 1 addition & 1 deletion scripting/get5/mapveto.sp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void CreateVeto() {
ResetReadyStatus();
if (g_PauseOnVetoCvar.BoolValue) {
if (g_PausingEnabledCvar.BoolValue){
Pause();
Pause(PauseType_Admin);
}
else {
ServerCommand("mp_pause_match");
Expand Down
74 changes: 44 additions & 30 deletions scripting/get5/pausing.sp
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,37 @@ public Action Command_TechPause(int client, int args) {
return Plugin_Handled;
}

g_InExtendedPause = true;

if (client == 0) {
Pause();
EventLogger_PauseCommand(MatchTeam_TeamNone, PauseType_Tech);
Pause(PauseType_Admin);
EventLogger_PauseCommand(MatchTeam_TeamNone, PauseType_Admin);
LogDebug("Calling Get5_OnMatchPaused(team=%d, pauseReason=%d)", MatchTeam_TeamNone,
PauseType_Tech);
PauseType_Admin);
Call_StartForward(g_OnMatchPaused);
Call_PushCell(MatchTeam_TeamNone);
Call_PushCell(PauseType_Tech);
Call_PushCell(PauseType_Admin);
Call_Finish();
Get5_MessageToAll("%t", "AdminForceTechPauseInfoMessage");
return Plugin_Handled;
}

MatchTeam team = GetClientMatchTeam(client);
int maxTechPauses = g_MaxTechPauseCvar.IntValue;
int maxTechPauseTime = g_MaxTechPauseTime.IntValue;

g_TeamReadyForUnpause[MatchTeam_Team1] = false;
g_TeamReadyForUnpause[MatchTeam_Team2] = false;

// Only set these if we are a non-zero value.
if (maxTechPauses > 0 || g_MaxTechPauseTime.IntValue > 0) {
int timeLeft = g_MaxTechPauseTime.IntValue - g_TechPausedTimeOverride[team];
if (maxTechPauses > 0 || maxTechPauseTime > 0) {
int timeLeft = maxTechPauseTime - g_TechPausedTimeOverride[team];
// Don't allow more than one tech pause per time.
if (g_TeamGivenTechPauseCommand[MatchTeam_Team1] || g_TeamGivenTechPauseCommand[MatchTeam_Team2]) {
return Plugin_Handled;
}
if (maxTechPauses > 0 && g_TeamTechPausesUsed[team] >= maxTechPauses) {
Get5_MessageToAll("%t", "TechPauseNoTimeRemaining", g_FormattedTeamNames[team]);
return Plugin_Handled;
} else if (g_MaxTechPauseTime.IntValue > 0 && timeLeft <= 0) {
} else if (maxTechPauseTime > 0 && timeLeft <= 0) {
Get5_MessageToAll("%t", "TechPauseNoTimeRemaining", g_FormattedTeamNames[team]);
return Plugin_Handled;
} else {
Expand All @@ -54,7 +53,7 @@ public Action Command_TechPause(int client, int args) {
}
}

Pause();
Pause(PauseType_Tech);
EventLogger_PauseCommand(team, PauseType_Tech);
LogDebug("Calling Get5_OnMatchPaused(team=%d, pauseReason=%d)", team, PauseType_Tech);
Call_StartForward(g_OnMatchPaused);
Expand All @@ -71,18 +70,15 @@ public Action Command_Pause(int client, int args) {
return Plugin_Handled;
}

g_InExtendedPause = false;

if (client == 0) {
g_InExtendedPause = true;

Pause();
EventLogger_PauseCommand(MatchTeam_TeamNone, PauseType_Tactical);
Pause(PauseType_Admin);
EventLogger_PauseCommand(MatchTeam_TeamNone, PauseType_Admin);
LogDebug("Calling Get5_OnMatchPaused(team=%d, pauseReason=%d)", MatchTeam_TeamNone,
PauseType_Tactical);
PauseType_Admin);
Call_StartForward(g_OnMatchPaused);
Call_PushCell(MatchTeam_TeamNone);
Call_PushCell(PauseType_Tactical);
Call_PushCell(PauseType_Admin);
Call_Finish();
Get5_MessageToAll("%t", "AdminForcePauseInfoMessage");
return Plugin_Handled;
Expand Down Expand Up @@ -117,7 +113,7 @@ public Action Command_Pause(int client, int args) {
}

// If the pause will need explicit resuming, we will create a timer to poll the pause status.
bool need_resume = Pause(g_FixedPauseTimeCvar.IntValue, MatchTeamToCSTeam(team));
bool need_resume = Pause(PauseType_Tactical, g_FixedPauseTimeCvar.IntValue, MatchTeamToCSTeam(team));
EventLogger_PauseCommand(team, PauseType_Tactical);
LogDebug("Calling Get5_OnMatchPaused(team=%d, pauseReason=%d)", team, PauseType_Tactical);
Call_StartForward(g_OnMatchPaused);
Expand Down Expand Up @@ -161,14 +157,15 @@ public Action Command_Pause(int client, int args) {

public Action Timer_TechPauseOverrideCheck(Handle timer, int data) {
MatchTeam team = view_as<MatchTeam>(data);
int maxTechPauseTime = g_MaxTechPauseTime.IntValue;
if (!Pauseable()) {
g_TechPausedTimeOverride[team] = 0;
g_TeamGivenTechPauseCommand[team] = false;
return Plugin_Stop;
}

// Unlimited Tech Pause so no one can unpause unless both teams agree.
if (g_MaxTechPauseTime.IntValue <= 0) {
if (maxTechPauseTime <= 0) {
g_TechPausedTimeOverride[team] = 0;
return Plugin_Stop;
}
Expand All @@ -179,9 +176,11 @@ public Action Timer_TechPauseOverrideCheck(Handle timer, int data) {
return Plugin_Stop;
}

int timeLeft = g_MaxTechPauseTime.IntValue - g_TechPausedTimeOverride[team];
int timeLeft = maxTechPauseTime - g_TechPausedTimeOverride[team];

if (InFreezeTime() && g_TeamGivenTechPauseCommand[team] && g_InExtendedPause && !g_TeamReadyForUnpause[team]) {
// Only count down if we're still frozen, fit the right pause type
// and the team who paused has not given the go ahead.
if (InFreezeTime() && g_TeamGivenTechPauseCommand[team] && g_PauseType == PauseType_Tech && !g_TeamReadyForUnpause[team]) {
LogDebug("Adding tech time used. Current time = %d", g_TechPausedTimeOverride[team]);
g_TechPausedTimeOverride[team]++;

Expand Down Expand Up @@ -246,9 +245,9 @@ public Action Timer_PauseTimeCheck(Handle timer, int data) {
if (!Pauseable() || !IsPaused() || g_FixedPauseTimeCvar.BoolValue) {
return Plugin_Stop;
}

int maxPauseTime = g_MaxPauseTimeCvar.IntValue;
// Unlimited pause time.
if (g_MaxPauseTimeCvar.IntValue <= 0) {
if (maxPauseTime <= 0) {
return Plugin_Stop;
}

Expand All @@ -258,7 +257,7 @@ public Action Timer_PauseTimeCheck(Handle timer, int data) {
}

MatchTeam team = view_as<MatchTeam>(data);
int timeLeft = g_MaxPauseTimeCvar.IntValue - g_TeamPauseTimeUsed[team];
int timeLeft = maxPauseTime - g_TeamPauseTimeUsed[team];
// Only count against the team's pause time if we're actually in the freezetime
// pause and they haven't requested an unpause yet.
if (InFreezeTime() && !g_TeamReadyForUnpause[team]) {
Expand All @@ -284,8 +283,23 @@ public Action Command_Unpause(int client, int args) {
if (!IsPaused())
return Plugin_Handled;

if (g_PauseType == PauseType_Admin && client != 0) {
Get5_MessageToAll("%t", "UserCannotUnpauseAdmin");
return Plugin_Handled;
}

// Let console force unpause
if (client == 0) {
// Remove any techpause conditions if an admin unpauses.
if (g_PauseType == PauseType_Tech) {
LOOP_TEAMS(team) {
if (team != MatchTeam_TeamNone) {
g_TeamGivenTechPauseCommand[team] = false;
g_TechPausedTimeOverride[team] = 0;
}
}
}

Unpause();
EventLogger_UnpauseCommand(MatchTeam_TeamNone);
LogDebug("Calling Get5_OnMatchUnpaused(team=%d)", MatchTeam_TeamNone);
Expand All @@ -296,13 +310,15 @@ public Action Command_Unpause(int client, int args) {
return Plugin_Handled;
}

if (g_FixedPauseTimeCvar.BoolValue && !g_InExtendedPause) {
if (g_FixedPauseTimeCvar.BoolValue && g_PauseType != PauseType_Tech) {
return Plugin_Handled;
}

MatchTeam team = GetClientMatchTeam(client);
g_TeamReadyForUnpause[team] = true;

int maxTechPauseTime = g_MaxTechPauseTime.IntValue;

// Get which team is currently tech paused.
MatchTeam pausedTeam = MatchTeam_TeamNone;
if (g_TeamGivenTechPauseCommand[MatchTeam_Team1]) {
Expand All @@ -311,8 +327,8 @@ public Action Command_Unpause(int client, int args) {
pausedTeam = MatchTeam_Team2;
}

if (g_InExtendedPause && g_MaxTechPauseTime.IntValue > 0) {
if (g_TechPausedTimeOverride[pausedTeam] >= g_MaxTechPauseTime.IntValue) {
if (g_PauseType == PauseType_Tech && maxTechPauseTime > 0) {
if (g_TechPausedTimeOverride[pausedTeam] >= maxTechPauseTime) {
Unpause();
EventLogger_UnpauseCommand(team);
LogDebug("Calling Get5_OnMatchUnpaused(team=%d)", team);
Expand All @@ -326,7 +342,6 @@ public Action Command_Unpause(int client, int args) {
g_TeamGivenTechPauseCommand[pausedTeam] = false;
g_TechPausedTimeOverride[pausedTeam] = 0;
}
g_InExtendedPause = false;
return Plugin_Handled;
}
}
Expand All @@ -338,7 +353,6 @@ public Action Command_Unpause(int client, int args) {
Call_StartForward(g_OnMatchUnpaused);
Call_PushCell(team);
Call_Finish();
g_InExtendedPause = false;
if (pausedTeam != MatchTeam_TeamNone) {
g_TeamGivenTechPauseCommand[pausedTeam] = false;
g_TechPausedTimeOverride[pausedTeam] = 0;
Expand Down
13 changes: 10 additions & 3 deletions scripting/get5/util.sp
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,18 @@ stock bool IsPaused() {
}

// Pauses and returns if the match will automatically unpause after the duration ends.
stock bool Pause(int pauseTime = 0, int csTeam = CS_TEAM_NONE, int pausesLeft = 1) {
stock bool Pause(PauseType pauseType, int pauseTime = 0, int csTeam = CS_TEAM_NONE, int pausesLeft = 1) {
if (pauseType == PauseType_None) {
LogMessage("Pause() called with PauseType_None. Please call Unpause() instead.");
Unpause();
return false;
}

g_PauseType = pauseType;
ServerCommand("mp_pause_match");
if (pauseTime == 0 || csTeam == CS_TEAM_SPECTATOR || csTeam == CS_TEAM_NONE) {
ServerCommand("mp_pause_match");
return false;
} else {
ServerCommand("mp_pause_match");
if (csTeam == CS_TEAM_T) {
GameRules_SetProp("m_bTerroristTimeOutActive", true);
GameRules_SetPropFloat("m_flTerroristTimeOutRemaining", float(pauseTime));
Expand All @@ -229,6 +235,7 @@ stock bool Pause(int pauseTime = 0, int csTeam = CS_TEAM_NONE, int pausesLeft =
}

stock void Unpause() {
g_PauseType = PauseType_None;
ServerCommand("mp_unpause_match");
}

Expand Down
2 changes: 2 additions & 0 deletions scripting/include/get5.inc
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ enum SideChoice {
};

enum PauseType {
PauseType_None,
PauseType_Tech, // Technical pause
PauseType_Tactical, // Tactical Pause
PauseType_Admin // Admin/RCON Pause
};

// Called each get5-event with JSON formatted event text.
Expand Down
4 changes: 4 additions & 0 deletions translations/get5.phrases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
{
"en" "An admin has called for a technical pause."
}
"UserCannotUnpauseAdmin"
{
"en" "As an admin has called for this pause, it must also be unpaused by an admin."
}
"PauseTimeExpiration10SecInfoMessage"
{
"#format" "{1:s}"
Expand Down

0 comments on commit 9250c82

Please sign in to comment.