Skip to content

Commit

Permalink
Clean up pause time counter logic:
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
Only allow pause in live mode, except for admin pause
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
  • Loading branch information
nickdnk committed Jul 26, 2022
1 parent 14b19ba commit 3b49042
Show file tree
Hide file tree
Showing 19 changed files with 573 additions and 530 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 @@ -304,10 +306,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 @@ -358,7 +360,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 @@ -516,6 +518,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 @@ -774,12 +778,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 @@ -1038,6 +1040,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 @@ -1048,6 +1051,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 @@ -1310,6 +1319,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 @@ -1503,13 +1519,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 3b49042

Please sign in to comment.