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

Timers are improperly iterarated in RemoveMapChangeTimers #704

Open
Poggicek opened this issue Dec 8, 2024 · 0 comments
Open

Timers are improperly iterarated in RemoveMapChangeTimers #704

Poggicek opened this issue Dec 8, 2024 · 0 comments
Labels
untriaged New issue has not been triaged

Comments

@Poggicek
Copy link
Contributor

Poggicek commented Dec 8, 2024

RemoveMapChangeTimers is iterating a vector while possibly removing from said vector, the current code does not shift the iterator correctly when an entry is removed and the iteration can skip entries. I would suggest to rewrite the entire function to use std::erase_if to kill all the active timers instead of manually iterating and calling KillTimer, this both fixes the issue and improves performance as you don't have to shift the entire vector every iteration.

https://github.com/roflmuffin/CounterStrikeSharp/blob/6349c11d07af8ba95d280e4a0f994ccb46053ef5/src/core/timer_system.cpp#L173C5-L179C6

Test plugin:
Run a dedicated server with the plugin loaded, load any map and then run start_timer_test

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Timers;

public class TestTimers : BasePlugin
{
    public override string ModuleName => "Timer Tests";
    public override string ModuleDescription => "";
    public override string ModuleAuthor => "Poggu";
    public override string ModuleVersion => "0.0.1";
    public bool MapChangeStarted = false;
    public bool MapChanged = false;

    public void TimerHandler(int timerNum)
    {
        Console.WriteLine($"Timer{timerNum} Tick");

        if (MapChanged)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("[!] Test Failed!");
            Console.ResetColor();
            MapChanged = false;
        }
    }
    
    public override void Load(bool hotReload)
    {
        Console.WriteLine($"{ModuleName} loaded successfully!");
        
        AddCommand("start_timer_test", "", (player, info) =>
        {
            /* Test Preamble */
            Console.WriteLine("\n\n\n\n----------------------------------------------------------------------");
            Console.WriteLine("Starting 5 timers, disabling server hibernation and ALL LOG CHANNELS");
            Server.ExecuteCommand("log_verbosity Console off; log_verbosity - off; sv_hibernate_when_empty 0;");
            
            Console.WriteLine("Changing map in 10 seconds, no timers **should** run after map change.\n----------------------------------------------------------------------\n\n\n");
            AddTimer(15.0f, () =>
            {
                Console.WriteLine("\n\n---------\nChanging map\n---------\n\n\n");
                Server.ExecuteCommand("map de_dust2");
                MapChangeStarted = true;
            });
            
            /* Test Timers */
            AddTimer(3.0f, () =>
            {
                TimerHandler(1);
            }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
            AddTimer(3.0f, () =>
            {
                TimerHandler(2);
            }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
            AddTimer(3.0f, () =>
            {
                TimerHandler(3);
            }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
            AddTimer(3.0f, () =>
            {
                TimerHandler(4);
            }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
            AddTimer(3.0f, () =>
            {
                TimerHandler(5);
            }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
        });
        
        RegisterListener<Listeners.OnMapStart>(mapName =>
        {
            Console.WriteLine($"Map {mapName} loaded!");

            if (MapChangeStarted)
                MapChanged = true;
        });
    }
}
@github-actions github-actions bot added the untriaged New issue has not been triaged label Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
untriaged New issue has not been triaged
Projects
None yet
Development

No branches or pull requests

1 participant