Raised This Month: $51 Target: $400
 12% 

Why is GameFrame called when IsServerProcessing returns false?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
fakuivan
Senior Member
Join Date: Nov 2015
Old 09-11-2016 , 16:06   Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #1

I built sourcemod from this pr (it does the same thing when compiled from this commit tho)

Code:
sm version
 SourceMod Version Information:
    SourceMod Version: 1.9.0.5958
    SourcePawn Engine: 1.9.0.5958, jit-x86 (build 1.9.0.5958)
    SourcePawn API: v1 = 4, v2 = 11
    Compiled on: Sep 11 2016 14:57:46
    Built from: https://github.com/alliedmodders/sourcemod/commit/de5b93a
    Build ID: 5958:de5b93a
    http://www.sourcemod.net/
This is the test plugin that I am using to comfirm this:

PHP Code:
#include <sourcemod>

public Plugin myinfo 
{
    
name "[TESTSUITE] ",
    
author "fakuivan",
    
description "Tests for RequestFrame hooking Think or GameFrame",
    
version "1.0",
    
url "https://forums.alliedmods.net/member.php?u=264797"
};

int  gi_called;
int  gi_divisor;
bool gb_calling;

public 
void OnPluginStart()
{
    
gi_divisor 10
    RegAdminCmd
("sm_test_set_divisor"Command_SetDivisorADMFLAG_RCON"Sets gi_divisor on plugin.");
    
RegAdminCmd("sm_test_set_calling"Command_SetCallingADMFLAG_RCON"Sets gb_calling on plugin.");
    
RegAdminCmd("sm_test_is_processing"Command_IsProcessingADMFLAG_RCON"Is GameFrame being called?");
    
RegAdminCmd("sm_test_hook_think"Command_AddHookADMFLAG_RCON"Tests for RequestFrame hooking Think or GameFrame");
}

public 
Action Command_IsProcessing(int i_clientint i_args)
{
    
ReplyToCommand(i_client"[SM-TEST] The server %s processing frames"IsServerProcessing() ? "is" "is not")
}

public 
Action Command_SetDivisor(int i_clientint i_args)
{
    if (
i_args != 1)
    {
        
ReplyToCommand(i_client"[SM-TEST] usage \"command <divisior>\"");
        return 
Plugin_Handled;
    }
    
gi_divisor GetCmdArgInt(1);
    
gi_called 0;
    
ReplyToCommand(i_client"[SM-TEST] Setted gi_divisor to %d and gi_called to 0"gi_divisor);
    return 
Plugin_Handled;
}

public 
Action Command_SetCalling(int i_clientint i_args)
{
    if (
i_args != 1)
    {
        
ReplyToCommand(i_client"[SM-TEST] usage \"command <1/0>\"");
        return 
Plugin_Handled;
    }
    
gb_calling view_as<bool>(GetCmdArgInt(1));
    
ReplyToCommand(i_client"[SM-TEST] Setted gb_calling to %s"gb_calling "true" "false");
    return 
Plugin_Handled;
}

public 
void OnGameFrame()
{
    if (!
gb_calling) { return; }
    if (
gi_called gi_divisor
    {
        
gi_called++;
        return;
    }
    
gi_called 0;
    
PrintToServer("[SM-TEST] GameFrame called %d times after the last print"gi_divisor);
}

public 
Action Command_AddHook(int i_clientint i_args)
{
    if (
i_args != 2)
    {
        
ReplyToCommand(i_client"[SM-TEST] usage \"command <data> <1/0>\"");
        return 
Plugin_Handled;
    }
    
int i_data GetCmdArgInt(1);
    
bool b_hook_think view_as<bool>(GetCmdArgInt(2));
    
ReplyToCommand(i_client"[SM-TEST] Calling RequestFrame, HookThink set to %d, data: %d"b_hook_thinki_data);
    
RequestFrame(Callback_Hooki_datab_hook_think);
    return 
Plugin_Handled;
}

void Callback_Hook(any data)
{
    
PrintToServer("[SM-TEST] Someone called us, data: %d"data);
}

stock int GetCmdArgInt(int argnumint length 12int base 10)
{
    
char[] s_buffer = new char[length];
    
GetCmdArg(argnums_bufferlength);
    return 
StringToInt(s_bufferbase);

Console output:

Code:
sv_pausable 1
sm_test_is_processing
[SM-TEST] The server is processing frames
sm_test_set_divisor 60 //~1 prints/sec
sm_test_set_calling 1
[SM-TEST] Setted gb_calling to true
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
sm_test_set_calling 0
[SM-TEST] Setted gb_calling to false
setpause //on the client
sm_test_is_processing
[SM-TEST] The server is not processing frames
sm_test_set_calling 1
[SM-TEST] Setted gb_calling to true
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
sm_test_set_calling 0
sm_test_is_processing //just to confirm
[SM-TEST] The server is not processing frames
The same thing happens on map start

Code:
map pl_upward
/.. ../ usual map start bs
status
hostname: Team Fortress
version : 3591277/24 3593021 secure
udp/ip  : 192.168.110.101:27080  (public ip: 186.138.154.133)
steamid : [A:1:688189447:7383] (90103702979145735)
account : not logged in  (No account specified)
map     : pl_upward at: 0 x, 0 y, 0 z
tags    : increased_maxplayers,payload
players : 0 humans, 0 bots (32 max)
edicts  : 998 used of 2048 max
         Spawns Points Kills Deaths Assists
Scout         5      0     0      1       0
Sniper        0      0     0      0       0
Soldier       8      0     0      0       0
Demoman       5      0     0      4       0
Medic         0      0     0      0       0
Heavy         0      0     0      0       0
Pyro          1      0     0      0       0
Spy           0      0     0      0       0
Engineer      0      0     0      0       0

# userid name                uniqueid            connected ping loss state  adr
sm_test_is_processing
[SM-TEST] The server is not processing frames
sm_test_set_calling 1
[SM-TEST] Setted gb_calling to true
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
[SM-TEST] GameFrame called 60 times after the last print
sm_test_set_calling 0
Any Ideas on why this is happening?
fakuivan is offline
Wilczek
AlliedModders Donor
Join Date: Oct 2012
Location: Poland
Old 09-12-2016 , 00:47   Re: Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #2

Quote:
IsServerProcessing Function

Returns whether or not the server is processing frames or not.

The server does not process frames until at least one client joins the game. Once the first player has in, even if that player, leaves, the server's timers and entities will work.
Did you add players first?
__________________
Wilczek is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 09-12-2016 , 01:19   Re: Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #3

Quote:
Originally Posted by Wilczek View Post
Did you add players first?
Nope
fakuivan is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 09-12-2016 , 01:47   Re: Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #4

This is so weird to me, I plugged the lastest sm tree into a code analyzer program -to look at a butterfly graph- and it turns out (as expected) that the m_pOnGameFrame forward is only being executed by TimerSystem::GameFrame, which in turn is hooked to IServerGameDLL::GameFrame. Unless this function is being called via a different identifier outside of TimerSystem.cpp, I don't know what to say about it :/

Attached Thumbnails
Click image for larger version

Name:	CalledBy-RunFrameHooks.png
Views:	347
Size:	2.7 KB
ID:	157378  
fakuivan is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 09-12-2016 , 05:32   Re: Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #5

The internal GameFrame function on IServerGameDLL takes a boolean param called "simulating", that is what is referred to here - the function is still called, and thus the OnGameFrame forward is still fired. It is a completely different mechanism from the hibernation is other branches.
__________________
asherkin is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 09-12-2016 , 10:41   Re: Why is GameFrame called when IsServerProcessing returns false?
Reply With Quote #6

Oh, I see. That's why timers don't fire when simulating == true, but the call to m_pOnGameFrame::Execute ignores that argument altogether. When is GameFrame skipped then?

Last edited by fakuivan; 09-12-2016 at 12:27. Reason: ...
fakuivan is offline
Reply



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 22:35.


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