Skip to content

Commit

Permalink
Clean up pause time counter logic: (#784)
Browse files Browse the repository at this point in the history
Remove g_PauseTimeUsed
Only fire necessary timers
Ensure fixed pause configuration takes precedence over combined max pause time
Redirect sm_tech to admin pause if used in console
Prevent direct calls to mp_pause_match and mp_unpause_match, force sm_pause/sm_unpause
Remove g_TeamGivenTechPauseCommand array
Add g_PausingTeam and g_PauseType to debug output
Prevent multiple pauses from being triggered at the same time
Prevent spectators and team none from ever calling pause or unpause
Renamed g_MaxTechPauseTime to g_MaxTechPauseDurationCvar for consistency
Renamed g_MaxPausesCvar to g_MaxTacticalPausesCvar for consistency
Renamed g_TechPausedTimeOverride to g_TechnicalPauseTimeUsed, as that's what it is
Renamed g_TeamPauseTimeUsed to g_TacticalPauseTimeUsed
Renamed g_TechPauseTimeUsed to g_TechnicalPauseTimeUsed
Renamed g_TeamPausesUsed to g_TacticalPausesUsed
Renamed g_TeamTechPausesUsed to g_TechnicalPausesUsed
Add print-to-all localized hints for all pauses, ditched the in-game pause state as it's buggy
Add util function for converting seconds to minutes:seconds
Ensure unpausing when loading a match
Refactored translations and removed redundant chat-text
Allow admin to pause even if pausing is disabled
Add team name to max pause/pause time used.
Add backup pause type hint
Add stop command not enabled translation
Don't allow stop command during admin pause
Automatically unpause if max pauses get set to a lower value than already consumed while a pause is active
Adjust danish translations
Adjust game state pause permissions
  • Loading branch information
nickdnk committed Jul 31, 2022
1 parent f971859 commit ce1bc19
Show file tree
Hide file tree
Showing 19 changed files with 533 additions and 529 deletions.
13 changes: 9 additions & 4 deletions documentation/docs/event_schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,11 @@ paths:
schema:
title: Get5MatchPausedEvent
allOf:
- "$ref": "#/components/schemas/Get5MapTeamEvent"
- "$ref": "#/components/schemas/Get5MatchPauseEvent"
properties:
event:
enum:
- game_paused
pause_type:
$ref: "#/components/schemas/Get5PauseType"
responses: { }
"/Get5_OnMatchUnpaused":
post:
Expand All @@ -196,7 +194,7 @@ paths:
schema:
title: Get5MatchUnpausedEvent
allOf:
- "$ref": "#/components/schemas/Get5MapTeamEvent"
- "$ref": "#/components/schemas/Get5MatchPauseEvent"
properties:
event:
enum:
Expand Down Expand Up @@ -969,6 +967,13 @@ components:
- technical
- admin
- backup
Get5MatchPauseEvent:
allOf:
- "$ref": "#/components/schemas/Get5MapTeamEvent"
- type: object
properties:
pause_type:
$ref: "#/components/schemas/Get5PauseType"
Get5Player:
type: object
properties:
Expand Down
65 changes: 38 additions & 27 deletions scripting/get5.sp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@

/** ConVar handles **/
ConVar g_AllowTechPauseCvar;
ConVar g_MaxTechPauseTime;
ConVar g_MaxTechPauseCvar;
ConVar g_MaxTechPauseDurationCvar;
ConVar g_MaxTechPausesCvar;
ConVar g_AutoLoadConfigCvar;
ConVar g_AutoReadyActivePlayersCvar;
ConVar g_BackupSystemEnabledCvar;
Expand All @@ -70,7 +70,7 @@ ConVar g_KickClientsWithNoMatchCvar;
ConVar g_LiveCfgCvar;
ConVar g_LiveCountdownTimeCvar;
ConVar g_MaxBackupAgeCvar;
ConVar g_MaxPausesCvar;
ConVar g_MaxTacticalPausesCvar;
ConVar g_MaxPauseTimeCvar;
ConVar g_MessagePrefixCvar;
ConVar g_PauseOnVetoCvar;
Expand Down Expand Up @@ -135,6 +135,17 @@ ArrayList g_CvarValues = null;
bool g_InScrimMode = false;
bool g_HasKnifeRoundStarted = false;

/** Pausing **/
bool g_IsChangingPauseState = false; // Used to prevent mp_pause_match and mp_unpause_match from being called directly.
Get5Team g_PausingTeam = Get5Team_None; // The team that last called for a pause.
Get5PauseType g_PauseType = Get5PauseType_None; // The type of pause last initiated.
int g_LatestPauseDuration = 0;
bool g_TeamReadyForUnpause[MATCHTEAM_COUNT];
bool g_TeamGivenStopCommand[MATCHTEAM_COUNT];
int g_TacticalPauseTimeUsed[MATCHTEAM_COUNT];
int g_TacticalPausesUsed[MATCHTEAM_COUNT];
int g_TechnicalPausesUsed[MATCHTEAM_COUNT];

/** Other state **/
Get5State g_GameState = Get5State_None;
ArrayList g_MapsToPlay = null;
Expand Down Expand Up @@ -182,15 +193,6 @@ bool g_TeamReadyOverride[MATCHTEAM_COUNT]; // Whether a team has been voluntari
bool g_ClientReady[MAXPLAYERS + 1]; // Whether clients are marked ready.
int g_TeamSide[MATCHTEAM_COUNT]; // Current CS_TEAM_* side for the team.
int g_TeamStartingSide[MATCHTEAM_COUNT];
bool g_TeamReadyForUnpause[MATCHTEAM_COUNT];
bool g_TeamGivenStopCommand[MATCHTEAM_COUNT];
Get5PauseType g_PauseType = Get5PauseType_None;
int g_TeamPauseTimeUsed[MATCHTEAM_COUNT];
int g_TeamPausesUsed[MATCHTEAM_COUNT];
int g_TeamTechPausesUsed[MATCHTEAM_COUNT];
int g_TechPausedTimeOverride[MATCHTEAM_COUNT];
int g_TeamGivenTechPauseCommand[MATCHTEAM_COUNT];
int g_PauseTimeUsed = 0;
int g_ReadyTimeWaitingUsed = 0;
char g_DefaultTeamColors[][] = {
TEAM1_COLOR,
Expand Down Expand Up @@ -312,10 +314,10 @@ public void OnPluginStart() {
/** ConVars **/
g_AllowTechPauseCvar = CreateConVar("get5_allow_technical_pause", "1",
"Whether or not technical pauses are allowed");
g_MaxTechPauseTime = CreateConVar(
g_MaxTechPauseDurationCvar = CreateConVar(
"get5_tech_pause_time", "0",
"Number of seconds before anyone can call unpause on a technical timeout, 0=unlimited");
g_MaxTechPauseCvar =
g_MaxTechPausesCvar =
CreateConVar("get5_max_tech_pauses", "0",
"Number of technical pauses a team is allowed to have, 0=unlimited");
g_AutoLoadConfigCvar =
Expand Down Expand Up @@ -366,7 +368,7 @@ public void OnPluginStart() {
g_MaxBackupAgeCvar =
CreateConVar("get5_max_backup_age", "160000",
"Number of seconds before a backup file is automatically deleted, 0 to disable");
g_MaxPausesCvar =
g_MaxTacticalPausesCvar =
CreateConVar("get5_max_pauses", "0", "Maximum number of pauses a team can use, 0=unlimited");
g_MaxPauseTimeCvar =
CreateConVar("get5_max_pause_time", "300",
Expand Down Expand Up @@ -524,6 +526,8 @@ public void OnPluginStart() {
AddCommandListener(Command_Coach, "coach");
AddCommandListener(Command_JoinTeam, "jointeam");
AddCommandListener(Command_JoinGame, "joingame");
AddCommandListener(Command_PauseOrUnpauseMatch, "mp_pause_match");
AddCommandListener(Command_PauseOrUnpauseMatch, "mp_unpause_match");

/** Setup data structures **/
g_MapPoolList = new ArrayList(PLATFORM_MAX_PATH);
Expand Down Expand Up @@ -773,12 +777,10 @@ public void OnMapStart() {
LOOP_TEAMS(team) {
g_TeamGivenStopCommand[team] = false;
g_TeamReadyForUnpause[team] = false;
g_TeamPauseTimeUsed[team] = 0;
g_TeamPausesUsed[team] = 0;
g_TacticalPauseTimeUsed[team] = 0;
g_TacticalPausesUsed[team] = 0;
g_ReadyTimeWaitingUsed = 0;
g_TeamTechPausesUsed[team] = 0;
g_TechPausedTimeOverride[team] = 0;
g_TeamGivenTechPauseCommand[team] = false;
g_TechnicalPausesUsed[team] = 0;
}

if (g_WaitingForRoundBackup) {
Expand Down Expand Up @@ -1037,6 +1039,7 @@ public Action Command_DumpStats(int client, int args) {

public Action Command_Stop(int client, int args) {
if (!g_StopCommandEnabledCvar.BoolValue) {
Get5_MessageToAll("%t", "StopCommandNotEnabled");
return Plugin_Handled;
}

Expand All @@ -1047,6 +1050,12 @@ public Action Command_Stop(int client, int args) {
// Let the server/rcon always force restore.
if (client == 0) {
RestoreLastRound(client);
return Plugin_Handled;
}

if (g_PauseType == Get5PauseType_Admin) {
// Don't let teams restore backups while an admin has paused the game.
return Plugin_Handled;
}

Get5Team team = GetClientMatchTeam(client);
Expand Down Expand Up @@ -1309,6 +1318,13 @@ public Action Event_RoundPreStart(Event event, const char[] name, bool dontBroad

public Action Event_FreezeEnd(Event event, const char[] name, bool dontBroadcast) {
LogDebug("Event_FreezeEnd");

// If someone changes the map while in a pause, we have to make sure we reset this state, as the UnpauseGame function
// will not be called to do it. FreezeTimeEnd is always called when the map initially loads.
g_LatestPauseDuration = 0;
g_PauseType = Get5PauseType_None;
g_PausingTeam = Get5Team_None;

// We always want this to be correct, regardless of game state.
g_RoundStartedTime = GetEngineTime();
if (g_GameState == Get5State_Live) {
Expand Down Expand Up @@ -1502,13 +1518,8 @@ public void SwapSides() {

if (g_ResetPausesEachHalfCvar.BoolValue) {
LOOP_TEAMS(team) {
g_TeamPauseTimeUsed[team] = 0;
g_TeamPausesUsed[team] = 0;
}
// Reset the built-in timeout counter of the game
if (g_MaxPausesCvar.IntValue > 0) {
GameRules_SetProp("m_nTerroristTimeOuts", g_MaxPausesCvar.IntValue);
GameRules_SetProp("m_nCTTimeOuts", g_MaxPausesCvar.IntValue);
g_TacticalPauseTimeUsed[team] = 0;
g_TacticalPausesUsed[team] = 0;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions scripting/get5/backups.sp
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public void RestoreGet5Backup() {
EndWarmup();
EndWarmup();
ServerCommand("mp_restartgame 5");
PauseGame(Get5Team_None, Get5PauseType_Backup, 1);
PauseGame(Get5Team_None, Get5PauseType_Backup);
if (g_CoachingEnabledCvar.BoolValue) {
CreateTimer(6.0, Timer_SwapCoaches);
}
Expand All @@ -377,7 +377,7 @@ public Action Timer_SwapCoaches(Handle timer) {
}

public Action Time_StartRestore(Handle timer) {
PauseGame(Get5Team_None, Get5PauseType_Backup, 1);
PauseGame(Get5Team_None, Get5PauseType_Backup);

char tempValveBackup[PLATFORM_MAX_PATH];
GetTempFilePath(tempValveBackup, sizeof(tempValveBackup), TEMP_VALVE_BACKUP_PATTERN);
Expand Down
13 changes: 8 additions & 5 deletions scripting/get5/debug.sp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ static void AddGlobalStateInfo(File f) {
f.WriteLine("g_SavedValveBackup = %d", g_SavedValveBackup);
f.WriteLine("g_DoingBackupRestoreNow = %d", g_DoingBackupRestoreNow);
f.WriteLine("g_ReadyTimeWaitingUsed = %d", g_ReadyTimeWaitingUsed);
f.WriteLine("g_PausingTeam = %d", g_PausingTeam);
f.WriteLine("g_PauseType = %d", g_PauseType);
f.WriteLine("g_LatestPauseDuration = %d", g_LatestPauseDuration);

LOOP_TEAMS(team) {
GetTeamString(team, buffer, sizeof(buffer));
Expand All @@ -134,11 +137,9 @@ static void AddGlobalStateInfo(File f) {
f.WriteLine("g_TeamSeriesScores = %d", g_TeamSeriesScores[team]);
f.WriteLine("g_TeamReadyOverride = %d", g_TeamReadyOverride[team]);
f.WriteLine("g_TeamStartingSide = %d", g_TeamStartingSide[team]);
f.WriteLine("g_TeamPauseTimeUsed = %d", g_TeamPauseTimeUsed[team]);
f.WriteLine("g_TechPausedTimeOverride = %d", g_TechPausedTimeOverride[team]);
f.WriteLine("g_TeamPausesUsed = %d", g_TeamPausesUsed[team]);
f.WriteLine("g_TeamTechPausesUsed = %d", g_TeamTechPausesUsed[team]);
f.WriteLine("g_TeamGivenTechPauseCommand = %d", g_TeamGivenTechPauseCommand[team]);
f.WriteLine("g_TacticalPauseTimeUsed = %d", g_TacticalPauseTimeUsed[team]);
f.WriteLine("g_TacticalPausesUsed = %d", g_TacticalPausesUsed[team]);
f.WriteLine("g_TechnicalPausesUsed = %d", g_TechnicalPausesUsed[team]);
f.WriteLine("g_TeamGivenStopCommand = %d", g_TeamGivenStopCommand[team]);
WriteArrayList(f, "g_TeamCoaches", g_TeamCoaches[team]);
}
Expand All @@ -153,8 +154,10 @@ static void AddInterestingCvars(File f) {
WriteCvarString(f, "get5_fixed_pause_time");
WriteCvarString(f, "get5_kick_when_no_match_loaded");
WriteCvarString(f, "get5_live_cfg");
WriteCvarString(f, "get5_tech_pause_time");
WriteCvarString(f, "get5_max_pause_time");
WriteCvarString(f, "get5_max_pauses");
WriteCvarString(f, "get5_max_tech_pauses");
WriteCvarString(f, "get5_pause_on_veto");
WriteCvarString(f, "get5_pausing_enabled");
WriteCvarString(f, "get5_print_damage");
Expand Down
10 changes: 1 addition & 9 deletions scripting/get5/goinglive.sp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ public Action MatchLive(Handle timer) {
SetMatchTeamCvars();
ExecuteMatchConfigCvars();

// If there is a set amount of timeouts available update the built-in convar and game rule
// properties to show the correct amount of timeouts remaining in gsi and in-game
if (g_MaxPausesCvar.IntValue > 0) {
ServerCommand("mp_team_timeout_max %d", g_MaxPausesCvar.IntValue);
GameRules_SetProp("m_nTerroristTimeOuts", g_MaxPausesCvar.IntValue);
GameRules_SetProp("m_nCTTimeOuts", g_MaxPausesCvar.IntValue);
}

// We force the match end-delay to extend for the duration of the GOTV broadcast here.
g_PendingSideSwap = false;
SetMatchRestartDelay();
Expand All @@ -76,4 +68,4 @@ public void SetMatchRestartDelay() {
ConVar mp_match_restart_delay = FindConVar("mp_match_restart_delay");
int delay = GetTvDelay() + MATCH_END_DELAY_AFTER_TV + 5;
SetConVarInt(mp_match_restart_delay, delay);
}
}
8 changes: 2 additions & 6 deletions scripting/get5/mapveto.sp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ public void CreateVeto() {
g_VetoCaptains[Get5Team_2] = GetTeamCaptain(Get5Team_2);
ResetReadyStatus();
if (g_PauseOnVetoCvar.BoolValue) {
if (g_PausingEnabledCvar.BoolValue) {
PauseGame(Get5Team_None, Get5PauseType_Admin, 1);
} else {
ServerCommand("mp_pause_match");
}
PauseGame(Get5Team_None, Get5PauseType_Admin);
}
CreateTimer(1.0, Timer_VetoCountdown, _, TIMER_REPEAT);
}
Expand Down Expand Up @@ -50,7 +46,7 @@ public void VetoFinished() {
Get5_MessageToAll("%t", "MapDecidedInfoMessage");

if (IsPaused()) {
ServerCommand("mp_unpause_match");
UnpauseGame(Get5Team_None);
}

// Use total series score as starting point, to not print skipped maps
Expand Down
12 changes: 7 additions & 5 deletions scripting/get5/matchconfig.sp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) {
// During restore we want to keep our
// current pauses used.
if (!restoreBackup) {
g_TeamPauseTimeUsed[team] = 0;
g_TeamPausesUsed[team] = 0;
g_TeamTechPausesUsed[team] = 0;
g_TacticalPauseTimeUsed[team] = 0;
g_TacticalPausesUsed[team] = 0;
g_TechnicalPausesUsed[team] = 0;
}
g_TechPausedTimeOverride[team] = 0;
g_TeamGivenTechPauseCommand[team] = false;
ClearArray(GetTeamCoaches(team));
ClearArray(GetTeamAuths(team));
}
Expand Down Expand Up @@ -122,6 +120,10 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) {
ExecuteMatchConfigCvars();
LoadPlayerNames();
EnsureIndefiniteWarmup();
if (IsPaused()) {
LogDebug("Match was paused when loading match config. Unpausing.");
UnpauseGame(Get5Team_None);
}

Stats_InitSeries();

Expand Down
Loading

0 comments on commit ce1bc19

Please sign in to comment.