Raised This Month: $32 Target: $400
 8% 

Solved Invalid Timer Handle


Post New Thread Reply   
 
Thread Tools Display Modes
condolent
AlliedModders Donor
Join Date: Jan 2016
Location: gc_sLocation;
Old 10-05-2017 , 15:57   Re: Invalid Timer Handle
Reply With Quote #11

So here's the error when the timer finishes for the first time:
Code:
L 10/05/2017 - 21:51:59: [SM] Plugin "myplugin.smx" encountered error 23: Native detected error
L 10/05/2017 - 21:51:59: [SM] Invalid timer handle 17600d9 (error 3) during timer end, displayed function is timer callback, not the stack trace
And this error occurs when I'm trying to create the timer once again:
Code:
L 10/05/2017 - 21:51:59: [SM] Unable to call function "SmokeCheckTimer" due to above error(s).
L 10/05/2017 - 21:52:36: [SM] Exception reported: Handle 17600d9 is invalid (error 1)
L 10/05/2017 - 21:52:36: [SM] Blaming: myplugin.smx
L 10/05/2017 - 21:52:36: [SM] Call stack trace:
L 10/05/2017 - 21:52:36: [SM]   [0] CloseHandle
L 10/05/2017 - 21:52:36: [SM]   [1] Line 41, myplugin/smoke.sp::_Smoke_OnRoundStart
L 10/05/2017 - 21:52:36: [SM]   [2] Line 55, myplugin/smoke.sp::_Smoke_OnPlayerDeath
L 10/05/2017 - 21:52:36: [SM]   [3] Line 60, myplugin/deaths.sp::OnTakeDamageAlive
This is the code where it gets created:
PHP Code:
Handle myTimer null;

public 
void _Smoke_OnRoundStart() {
    if(
myTimer != null)
        
delete myTimer;
    if(
myTimer == null)
        
myTimer CreateTimer(gc_iSmokeTimer.FloatValueSmokeCheckTimer);

And this is the timers' code:
PHP Code:
public Action SmokeCheckTimer(Handle timer) {
    
ExecSmoke();
    
    
delete timer;

__________________
condolent is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-05-2017 , 16:09   Re: Invalid Timer Handle
Reply With Quote #12

Could you tell us, what you are trying to achieve ? What is idea with this smokes and timer ?
Tell step by step
__________________
Do not Private Message @me
Bacardi is offline
condolent
AlliedModders Donor
Join Date: Jan 2016
Location: gc_sLocation;
Old 10-05-2017 , 16:23   Re: Invalid Timer Handle
Reply With Quote #13

Quote:
Originally Posted by Bacardi View Post
Could you tell us, what you are trying to achieve ? What is idea with this smokes and timer ?
Tell step by step
Of course!

So the purpose is for after x seconds ExecSmoke() is supposed to be called starting from the start of the round (the SmokeCheckTimer timer). If the player kills somebody during the countdown, the countdown is reset back to its original state and starts counting down once again.

When the timer hits 0, it executes ExecSmoke(), which in that function creates a new repeatable timer which spawns smoke on the player each 0.5 seconds until the player dies or he/she kills someone.
This timer has no issues. It's the first one that I talked about that is bugging out.

The first problem I encountered was that the first timer was created several times, one after each round start if it had not been fired yet. So if the timer was still counting down and the round ended, another one was created without it actually being cancelled from the previous round.

I tried explaining it as well as I could, if there's any questions then please let me know and I'll try to clarify to the best of my ability!
__________________
condolent is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-05-2017 , 16:36   Re: Invalid Timer Handle
Reply With Quote #14

ok, now I understand. I make a sample now...
__________________
Do not Private Message @me
Bacardi is offline
Timocop
AlliedModders Donor
Join Date: Mar 2013
Location: Germany
Old 10-05-2017 , 16:43   Re: Invalid Timer Handle
Reply With Quote #15

Deleting timer doesnt set myTimer to null.

PHP Code:
public Action SmokeCheckTimer(Handle timer) { 
    
ExecSmoke(); 
     
    
myTimer null;
    
//return Plugin_Stop; //Stopping the timer when using TIMER_REPEAT

and delete ignores if a handle is null. And dont use delete/CloseHandle() in timer callbacks to close/stop them.
Use return Plugin_Stop; instead. See SourceMod Docs.

PHP Code:
public void _Smoke_OnRoundStart() { 
    
delete myTimer

    if(
myTimer == null
        
myTimer CreateTimer(gc_iSmokeTimer.FloatValueSmokeCheckTimer); 


Last edited by Timocop; 10-05-2017 at 16:46.
Timocop is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-05-2017 , 17:23   Re: Invalid Timer Handle
Reply With Quote #16

Here my example...

Two Handle to handle two timers.

Warmup timer start on round start, and if this timer is still active while player kill another player, timer reset.
If warmuptimer still active when round start, timer reset.
When warmup timer time reach end, it create repeated smoketimer.

If smoketimer is active, it stop on round start.


PHP Code:
Handle hWarmuptimer;
Handle hSmoketimer;

public 
void OnPluginStart()
{

    
HookEventEx("round_start"round_start);
    
HookEventEx("player_death"player_death);
}


public 
void round_start(Event event, const char[] namebool dontBroadcast)
{
    
// SmokeTimer currently running, active!
    // Lets clear this repeated timer Handle, it will stop itself :D
    
if(hSmoketimer != nullhSmoketimer null;



    
// If Warmuptimer still running, active!
    // Kill timer
    
if(hWarmuptimer != nullKillTimer(hWarmuptimer);

    
hWarmuptimer CreateTimer(20.0warmuptimer_cb); // create new on round start
}

public 
void player_death(Event event, const char[] namebool dontBroadcast)
{
    
int victim GetClientOfUserId(event.GetInt("userid"));
    
int attacker GetClientOfUserId(event.GetInt("attacker"));

    
// killer not world or player suicide (no teamkill check here now)
    
if(attacker == || attacker == victim) return;


    
// Timer is currently running, active! We will reset timer.
    
if(hWarmuptimer != null)
    {
        
KillTimer(hWarmuptimer); // Remove current timer
        
hWarmuptimer CreateTimer(20.0warmuptimer_cb); // Create new timer in this same Handle
    
}
}

public 
Action warmuptimer_cb(Handle timer)
{
    
// Ok, this timer reach end and callback has triggered.
    // Lets also clear (null) this timer Handle to make sure that this timer is not active anymore. Like as message to othe code blocks.
    
hWarmuptimer null;

    
    
// There is no way, smoketimer supposed to runnig in this point. But double check.
    
if(hSmoketimer != nullKillTimer(hSmoketimer);

    
// Create repeated smoke timer
    
hSmoketimer CreateTimer(0.5smoketimer_cb_TIMER_REPEAT);

    return 
Plugin_Continue;
}

public 
Action smoketimer_cb(Handle timer)
{
    
// Check Handle is it null, stop timer if it is.
    
if(hSmoketimer == null) return Plugin_Stop


    
// Do your smoke exec() here!
    // for example, print chat message smoke alive players
    
for(int i 1<= MaxClientsi++)
    {
        if(!
IsClientInGame(i) || !IsPlayerAlive(i)) continue;

        
PrintToChat(i"smoke!");
    }




    
// Let timer continue
    
return Plugin_Continue;

*edit
I skipped this part. I made example to loop all alive players and print chat message "smoke" :/
Quote:
When the timer hits 0, it executes ExecSmoke(), which in that function creates a new repeatable timer which spawns smoke on the player each 0.5 seconds until the player dies or he/she kills someone.
This timer has no issues. It's the first one that I talked about that is bugging out.
__________________
Do not Private Message @me

Last edited by Bacardi; 10-05-2017 at 17:27.
Bacardi is offline
condolent
AlliedModders Donor
Join Date: Jan 2016
Location: gc_sLocation;
Old 10-06-2017 , 02:13   Re: Invalid Timer Handle
Reply With Quote #17

Quote:
Originally Posted by Bacardi View Post
Here my example...

Two Handle to handle two timers.

Warmup timer start on round start, and if this timer is still active while player kill another player, timer reset.
If warmuptimer still active when round start, timer reset.
When warmup timer time reach end, it create repeated smoketimer.

If smoketimer is active, it stop on round start.


PHP Code:
Handle hWarmuptimer;
Handle hSmoketimer;

public 
void OnPluginStart()
{

    
HookEventEx("round_start"round_start);
    
HookEventEx("player_death"player_death);
}


public 
void round_start(Event event, const char[] namebool dontBroadcast)
{
    
// SmokeTimer currently running, active!
    // Lets clear this repeated timer Handle, it will stop itself :D
    
if(hSmoketimer != nullhSmoketimer null;



    
// If Warmuptimer still running, active!
    // Kill timer
    
if(hWarmuptimer != nullKillTimer(hWarmuptimer);

    
hWarmuptimer CreateTimer(20.0warmuptimer_cb); // create new on round start
}

public 
void player_death(Event event, const char[] namebool dontBroadcast)
{
    
int victim GetClientOfUserId(event.GetInt("userid"));
    
int attacker GetClientOfUserId(event.GetInt("attacker"));

    
// killer not world or player suicide (no teamkill check here now)
    
if(attacker == || attacker == victim) return;


    
// Timer is currently running, active! We will reset timer.
    
if(hWarmuptimer != null)
    {
        
KillTimer(hWarmuptimer); // Remove current timer
        
hWarmuptimer CreateTimer(20.0warmuptimer_cb); // Create new timer in this same Handle
    
}
}

public 
Action warmuptimer_cb(Handle timer)
{
    
// Ok, this timer reach end and callback has triggered.
    // Lets also clear (null) this timer Handle to make sure that this timer is not active anymore. Like as message to othe code blocks.
    
hWarmuptimer null;

    
    
// There is no way, smoketimer supposed to runnig in this point. But double check.
    
if(hSmoketimer != nullKillTimer(hSmoketimer);

    
// Create repeated smoke timer
    
hSmoketimer CreateTimer(0.5smoketimer_cb_TIMER_REPEAT);

    return 
Plugin_Continue;
}

public 
Action smoketimer_cb(Handle timer)
{
    
// Check Handle is it null, stop timer if it is.
    
if(hSmoketimer == null) return Plugin_Stop


    
// Do your smoke exec() here!
    // for example, print chat message smoke alive players
    
for(int i 1<= MaxClientsi++)
    {
        if(!
IsClientInGame(i) || !IsPlayerAlive(i)) continue;

        
PrintToChat(i"smoke!");
    }




    
// Let timer continue
    
return Plugin_Continue;

*edit
I skipped this part. I made example to loop all alive players and print chat message "smoke" :/
Thank you for this! I will try it all tonight after work
__________________
condolent is offline
WildCard65
Veteran Member
Join Date: Aug 2013
Location: Canada
Old 10-06-2017 , 07:13   Re: Invalid Timer Handle
Reply With Quote #18

I'm going to mention something that I'm surprised no one else picked up, the error the plugin is encountering is HandleError 1 (HandleError_Changed, which stands for the Handle has been freed and reassigned)

It should be noted that upon a SM plugin timer's completion, it destroys it's own handle rendering it invalid to delete manually (hence the error), to fix the error, set the variable holding the timer to null BEFORE returning Plugin_Stop (or Plugin_Handled?)
__________________
WildCard65 is offline
condolent
AlliedModders Donor
Join Date: Jan 2016
Location: gc_sLocation;
Old 10-06-2017 , 10:49   Re: Invalid Timer Handle
Reply With Quote #19

Works great now!
__________________
condolent 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 04:41.


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