Raised This Month: $13 Target: $400
 3% 

Can't safely delete a timer handle


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Sarrus
Junior Member
Join Date: May 2020
Old 06-01-2020 , 10:50   Can't safely delete a timer handle
Reply With Quote #1

Hello,

I've ran into a problem with a plugin I've made:
I have various per client timers which get deleted when a client dies. However, one of the timer is a repeating timer which, when fired, slaps the client with a certain amount of damages. Sometimes, this causes the client to die, and therefore, the timer gets deleted in the callback, which is a big no, and thus registers an error.

What I've tried so far to fix this, is to add a boolean bIsClientBeingPunished, which prevents the timer from being deleted, if it's true. The idea was that the timer would fire again, and stop itself, because the player was no longer alive. This doesn't work, and I'm not sure why.

Can somebody please help me?
Here is the script
__________________
Discord: Sarrus#9090
Steam: Link
Community Website: Tensor
Github: Link
Sarrus is offline
Sarrus
Junior Member
Join Date: May 2020
Old 06-01-2020 , 11:09   Re: Can't safely delete a timer handle
Reply With Quote #2

Here is the "interesting" part of the code

PHP Code:
//Create a reset timer function
public void ResetTimer(int client)
{
    if (!
bIsBeingPunished[client] || g_anticampdisabled)
    {
        
delete(g_hClientTimers[client]);
        
delete(g_hPunishTimers[client]);
        
delete(g_hFreqTimers[client]);
        
delete(g_hCooldownTimers[client]);
    }
}

//Reset timer when client arrives
public void OnClientPutInServer(int client)
{
    
bIsBeingPunished[client] = false;
    
ResetTimer(client);
}

//Reset timer when client disconnects
public void OnClientDisconnect(int client)
{
    
ResetTimer(client);
}

//Reset timer when client changes team
public Action OnClientChangeTeam(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(event.GetInt("userid"));
    
ResetTimer(client);
}

//Reset timer when client dies
public Action OnClientDied(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(event.GetInt("userid"));
    
ResetTimer(client);
}

//Reset timer when the round ends
public Action Event_OnRoundEnd(Event event, const char[] namebool dontBroadcast)
{
    
delete(g_AntiCampDisable);
    for(
int iClient 1iClient <= MaxClientsiClient++)
  {
        
bIsBeingPunished[iClient] = false;
        
ResetTimer(iClient);
  }
}

//Start timer when client enters a zone
public void Zone_OnClientEntry(int clientchar[] zone)
{
    if(
client || client MaxClients || !IsClientInGame(client) ||!IsPlayerAlive(client) || IsWarmup() || g_anticampdisabled)
        return;

    if((
StrContains(zone"AntiCampCT"false) == && GetClientTeam(client) == 3) || (StrContains(zone"AntiCampT"false) == && GetClientTeam(client) == 2) || (StrContains(zone"AntiCampBoth"false) == 0))
    {
        if (
g_hCooldownTimers[client] == null)
        {
            
delete(g_hClientTimers[client]);
            if (
IsFreezeTime())
            {
                
g_hClientTimers[client] = CreateTimer(GetConVarFloat(cvar_time) + GetConVarFloat(FindConVar("mp_freezetime")), Timer_EndGetClientUserId(client));
            }
            else
            {
                
g_hClientTimers[client] = CreateTimer(GetConVarFloat(cvar_time), Timer_EndGetClientUserId(client));
            }
        }
        else
        {
            
ResetTimer(client);
            
bIsBeingPunished[client] = true;
            
CPrintToChat(client"%t""Cooldown_Not_Expired");
            
SlapPlayer(clientGetConVarInt(g_SlapDamage), true);
            
g_hFreqTimers[client] = CreateTimer(GetConVarFloat(g_PunishFreq), Repeat_TimerGetClientUserId(client), TIMER_REPEAT);
        }
    }
}


//Stop timer when client leaves a zone
public void Zone_OnClientLeave(int clientchar[] zone)
{
    if(
client || client MaxClients || !IsClientInGame(client) || !IsPlayerAlive(client) || IsWarmup() || g_anticampdisabled)
        return;

    if((
StrContains(zone"AntiCampCT"false) == && GetClientTeam(client) == 3) || (StrContains(zone"AntiCampT"false) == && GetClientTeam(client) == 2) || (StrContains(zone"AntiCampBoth"false) == 0))
    {
        
bIsBeingPunished[client] = false;
        
ResetTimer(client);
        if ((
GetConVarInt(g_CooldownDelay) != 0) && ((g_hPunishTimers[client] != null) || (g_hFreqTimers[client] != null)))
        {
            
g_hCooldownTimers[client] = CreateTimer(GetConVarFloat(g_CooldownDelay), Cooldown_EndGetClientUserId(client));
        }
    }
}


//What to do when the cooldown ends
public Action Cooldown_End(Handle timerint UserId)
{
    
int client GetClientOfUserId(UserId);
    if(!
client)
    {
        return;
    }
    
CPrintToChat(client"%t""Cooldown_Expired");
    
g_hCooldownTimers[client] = null;
}

//What do to when the main timer ends
public Action Timer_End(Handle timerint UserId)
{
    
int client GetClientOfUserId(UserId);
    if(!
client)
    {
        return;
    }
    
g_hClientTimers[client] = null;
    if ( 
client && IsClientInGame(client) && IsPlayerAlive(client))
    {
        
delete(g_hPunishTimers[client]);
        
g_hPunishTimers[client] = CreateTimer(GetConVarFloat(g_PunishDelay), Punish_TimerGetClientUserId(client));
        
PrintCenterText(client"%t""Camp_Message_Warning"GetConVarInt(g_PunishDelay) );
    }
}

//What to do when the punish timer ends
public Action Punish_Timer(Handle timerint UserId)
{
    
int client GetClientOfUserId(UserId);
    if(!
client)
    {
        return;
    }
    
g_hPunishTimers[client] = null;
    if (
IsClientInGame(client) && IsPlayerAlive(client))
    {
            
CPrintToChatAll("%t""Camp_Message_All"client);
            
SlapPlayer(clientGetConVarInt(g_SlapDamage), true);
            
delete(g_hFreqTimers[client]);
            
bIsBeingPunished[client] = true;
            
g_hFreqTimers[client] = CreateTimer(GetConVarFloat(g_PunishFreq), Repeat_TimerGetClientUserId(client), TIMER_REPEAT);
    }
}

public 
Action Repeat_Timer(Handle timerint UserId)
{
    
int client GetClientOfUserId(UserId);
    if(!
client) {
        return 
Plugin_Stop// Stop early, invalid client index.
    
}
    if (!
IsClientInGame(client) || !IsPlayerAlive(client))
        {
            
bIsBeingPunished[client] = false;
            
g_hFreqTimers[client] = null;
            return 
Plugin_Stop;
    }
    
CPrintToChat(client"%t""Camp_Message_Self");
    
SlapPlayer(clientGetConVarInt(g_SlapDamage), true);
    return 
Plugin_Continue;
}

public 
Action AntiCamp_Disable(Handle timer)
{
    
g_anticampdisabled true;
    
CPrintToChatAll("%t""AntiCamp_Disabled");
    for(
int iClient 1iClient <= MaxClientsiClient++)
  {
        
ResetTimer(iClient);
  }
    
g_AntiCampDisable null;
}

bool IsWarmup()
{
    return (
GameRules_GetProp("m_bWarmupPeriod") == 1);
}

bool IsFreezeTime()
{
    return(
GameRules_GetProp("m_bFreezePeriod") == 1);

__________________
Discord: Sarrus#9090
Steam: Link
Community Website: Tensor
Github: Link
Sarrus is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 05:13.


Powered by vBulletin®
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Theme made by Freecode