splewis / get5

CS:GO Sourcemod plugin for competitive matches/scrims
GNU General Public License v3.0
558 stars 176 forks source link

Fix "CTs win" callout before knife round + Prevent connecting users from joining teams too early #909

Closed nickdnk closed 1 year ago

nickdnk commented 1 year ago

A hard-to-reproduce bug has been in Get5 for a while. What happens is this:

  1. Match config is loaded
  2. Players join the server
  3. Players run around for x amount of seconds in warmup
  4. 10-second round-end warning music starts playing randomly (?)
  5. Players ready up
  6. Warmup counter starts to count down to knife
  7. "Counter Terrorists win!" panel + sound callout
  8. "Match restarts in 3..2..1"
  9. All players get sent back to warmup/arena
  10. Announce "Knife!" in chat
  11. Players stuck in warmup forever

I've been working with OmegaSkid and the SCL league in trying to narrow down exactly why and when this problem occurs, as I have been entirely unable to reproduce it on my own server. I suspect it may be related to hibernation or servers sitting in idle for too long.

I've tried to fix it here by adding two more calls to RestartGame in attempt to reset the game state once a player is on the server or when a match config is loaded. I don't know if this works, but we'll test it tomorrow across 20 matches that have been struggling a lot with this bug. If this fixes it, I will merge it.

nickdnk commented 1 year ago

So adding restarts did not help.

This attempt instead changes the warmup code so mp_warmup_begin is always performed when StartWarmup is called, which resets the warmup state. This also lets us get rid of EndWarmup entirely as it was only used to end warmup pre-knife.

nickdnk commented 1 year ago

It seems this has been resolved (test in 50+ matches on SCL) by changing this:

Get5_MessageToAll("%t", "KnifeIn5SecInfoMessage");
if (InWarmup()) {
  EndWarmup(5);
} else {
  RestartGame(5);
}

and

stock void StartWarmup(int warmupTime = 0) {
  ServerCommand("mp_do_warmup_period 1");
  ServerCommand("mp_warmuptime_all_players_connected 0");
  if (!InWarmup()) {
    ServerCommand("mp_warmup_start");
  }
  ...
}

to this:

Get5_MessageToAll("%t", "KnifeIn5SecInfoMessage");
StartWarmup(5);

and this:

stock void StartWarmup(int warmupTime = 0) {
  ServerCommand("mp_do_warmup_period 1");
  ServerCommand("mp_warmuptime_all_players_connected 0");
  ServerCommand("mp_warmup_start");
  ...
}

Long story short; we get rid of the !InWarmup() check and always force the warmup to restart with a 5 second countdown, instead of changing the countdown to 5 for an "existing warmup". This gets rid of the "CTs win!" callout and the knife round starts normally.

nickdnk commented 1 year ago

This also fixes a problem where connecting players would be put on a team "too early", as they would trigger multiple instances of the round_start event, which forces unteamed players to join a team. The result was weird spawns. We now only place players on round start if they have been marked as "pending team join" if they connect during halftime.