Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring in check to not allow users the ability to unpause admin pauses. #767

Merged
merged 12 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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