System GetLatency

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:

////////////////////////////////////////
//      
//  GetLatency ~v1.0.0~
//      by kingking
//
//  =====================
//  What is GetLatency?
//  =====================
//  ~ GetLatency will let you know the delay
//    between 2 players.
//  ~ It is very useful because host can know
//    which player is lagging.
//
//  ====================
//  How does it works?
//  ====================
//  ~ Create a timer.
//  ~ Every several period, it will get 
//    the timer's value and store it.
//  ~ Each player has his/her slot to store.
//  ~ The value is stored in gamecache.
//  ~ It is synced to other players later.
//
//  =====================
//  Function provided :
//  =====================
//  GetLatency(player,player) -> integer
//                               (milliseconds)
//
//  
//  Requires : Latest Jasshelper
////////////////////////////////////////
library GetLatency initializer Init
    
    globals
        private constant real PERIOD = .03125
        //Update period.
    endglobals
    
    globals
        private gamecache gc
        private string array Number
        private timer GameTimer
    endglobals
    
    private function Modules takes real r returns integer
        if r < 0. then
            return R2I(-r)
        endif
        return R2I(r)
        //=.="
    endfunction
    
    function GetLatency takes player source, player object returns integer //(ms)
        if GetPlayerController(source) == MAP_CONTROL_USER and GetPlayerSlotState(source) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(object) == MAP_CONTROL_USER and GetPlayerSlotState(object) == PLAYER_SLOT_STATE_PLAYING then
        //Does not work on leaved players or computer players.
            return Modules((GetStoredReal(gc,"Test",Number[GetPlayerId(source)]) - GetStoredReal(gc,"Test",Number[GetPlayerId(object)])) * 1000.)
        endif
        return 0
        //return 0 for leaved players / computer players.
    endfunction
    
    private function Update takes nothing returns nothing
        local integer i = GetPlayerId(GetLocalPlayer())
        //Magic! Does not desync!
        call StoreReal(gc,&quot;Test&quot;,Number<i>,TimerGetRemaining(GameTimer))
        //Store the value of timer.
        call SyncStoredReal(gc,&quot;Test&quot;,Number<i>)
        //Sync the value to other players&#039; gamecache.
    endfunction
    
    private function Init takes nothing returns nothing
        set Number[0] = &quot;Player 1&quot;
        set Number[1] = &quot;Player 2&quot;
        set Number[2] = &quot;Player 3&quot;
        set Number[3] = &quot;Player 4&quot;
        set Number[4] = &quot;Player 5&quot;
        set Number[5] = &quot;Player 6&quot;
        set Number[6] = &quot;Player 7&quot;
        set Number[7] = &quot;Player 8&quot;
        set Number[8] = &quot;Player 9&quot;
        set Number[9] = &quot;Player 10&quot;
        set Number[10] = &quot;Player 11&quot;
        set Number[11] = &quot;Player 12&quot;
        //Data slot for players.
        
        set GameTimer = CreateTimer()
        call TimerStart(GameTimer,1000000000.,false,null)
        //Game timer, used to measure the latency.
        
        call FlushGameCache(InitGameCache(&quot;GetLatency&quot;))
        set gc = InitGameCache(&quot;GetLatency&quot;)
        //Clear and init the gamecache.
                
        call TimerStart(CreateTimer(),PERIOD,true,function Update)
        //Updater.
    endfunction
    
endlibrary
</i></i>


Extra : Tested with BlackRose, it works! The latency was around 400-600. :p Thanks to BlackRose for testing it.
 

Attachments

  • GetLatency.w3x
    40.7 KB · Views: 246
  • GetLatency.w3g
    8 KB · Views: 254

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
And isn't there delay checker thingy already done?
:confused:

Thanks to BlackRose for doing my tester.
doh.gif
English is not my native language. I was laughing at it.
 

Nherwyziant

Be better than you were yesterday :D
Reaction score
96
Well, have you already proved that this system works fine? Well, this could be useful on some guys who will join the game board contest. I'm so gonna use this.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Well, have you already proved that this system works fine?
Yep. You can try it, why not?
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
Demo script please.

Also, did you test using a ping checking tool too? It's important to know how accurate this is.
 

Jesus4Lyf

Good Idea™
Reaction score
397
It's important to know how accurate this is.
JASS:
return Modules((GetStoredReal(gc,&quot;Test&quot;,Number[GetPlayerId(source)]) - GetStoredReal(gc,&quot;Test&quot;,Number[GetPlayerId(object)])) * 100.)

Especially considering 1 millisecond is 1/1000 seconds, not 1/100 as per your code.

Mm, this is kinda clever though, I like it. I think you need to test with two people of very different latencies and make sure there is a variation. Upload the demo map used and a replay, perhaps, so we know this really works. :thup:
 

Nestharus

o-o
Reaction score
84
>And isn't there delay checker thingy already done?

There was already a Delay checker thing made that works off of unit selection

http://www.thehelper.net/forums/showthread.php?t=132963

I mean sure, could have multiple ones, but I believe that the other one's method of unit selection works much better than game cache given that host checking via game cache isn't totally accurate, but Azlier's implementation using the methods from GetDelay seems to be 100% accurate.


but that's just my own petty observation
 

Azlier

Old World Ghost
Reaction score
461
Both can be broken by Alt+Tabbing, sadly.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
I'm going to try with array later. If it is succeed to pass the test, this stuff is going to be very fast. :p

Mm, this is kinda clever though, I like it. I think you need to test with two people of very different latencies and make sure there is a variation. Upload the demo map used and a replay, perhaps, so we know this really works.
I'm going to make it.

I mean sure, could have multiple ones, but I believe that the other one's method of unit selection works much better than game cache given that host checking via game cache isn't totally accurate, but Azlier's implementation using the methods from GetDelay seems to be 100% accurate.
GetDelay is heavier than this. :banghead:

Also, did you test using a ping checking tool too? It's important to know how accurate this is.
My ping checking tools requires me to press it manually and it is not real time. Hmm, is there anyone willing to help me to compare this one with GetDelay?
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
We don't care about speed in a system like this. We want accuracy.
 

saw792

Is known to say things. That is all.
Reaction score
280
>function Modules
I think you mean Modulo... just for readability.

Shouldn't the gamecache value return 0 for players that have left anyway, without the slot state check? Although it might return -(host delay).
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Shouldn't the gamecache value return 0 for players that have left anyway
Yep, it is 0.
Host - empty player = <some value>, :p.
300 - 0 = 300. :)
 

saw792

Is known to say things. That is all.
Reaction score
280
I think he actually means "Abs".

Well no, he is both truncating and taking the absolute value. Which is nothing to do with modulo either way, so I was certainly wrong about that. It's still a terrible function name.
 

Jesus4Lyf

Good Idea™
Reaction score
397
First thought: You can't get the ping from one player to another by subtracting the difference in game time...
Second thought: Maybe you can.
More careful third thought: Wait, what the heck?

Do you even know what values you are subtracting from each other?
You're suggesting that if two players are both behind by 0.3 seconds in game time, that their latency to each other is 0. Now, if those values are how far they are behind the host (and we have no idea what they are, it could be how fast gamecache executes on their pc) then they could be either in the same location (both 0.3 sec behind) or on opposite sides of the host (both 0.3 sec behind) which would mean their latency to eachother should be 0.6.

Can you please figure out what this is measuring? :(
I understand you need a point of reference, and you don't know who the host is: perhaps you can subtract it from the latest game time a player has? That should give you the latency to the "host", or at least how far they are back in time from where the game is at. ;)

Edit:
(Then your function only takes one player, as well.)
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:
////////////////////////////////////////
//      
//  GetLatency ~v1.0.1~
//      by kingking
//
//  =====================
//  What is GetLatency?
//  =====================
//  ~ GetLatency will let you know the delay
//    between 2 players.
//  ~ It is very useful because host can know
//    which player is lagging.
//
//  ====================
//  How does it works?
//  ====================
//  ~ Create a timer.
//  ~ Every several period, it will get 
//    the timer&#039;s value and store it.
//  ~ Each player has his/her slot to store.
//  ~ The value is stored in gamecache.
//  ~ It is synced to other players later.
//
//  =====================
//  Functions provided :
//  =====================
//  GetLatency(player) -&gt; integer
//                            (milliseconds)
//
//  GetHost() -&gt; player
//  
//  Requires : Latest Jasshelper
////////////////////////////////////////
library GetLatency initializer Init
    
    globals
        private constant real PERIOD = .03125
        //Update period.
    endglobals
    
    globals
        private gamecache gc = null
        private string array Number
        private timer GameTimer = null
        private integer HostId = 0
        private player Host = null
    endglobals
    
    private function Modules takes real r returns integer
        if r &lt; 0. then
            return R2I(-r)
        endif
        return R2I(r)
        //=.=&quot;
    endfunction
    
    function GetLatency takes player object returns integer //(ms)
        if GetPlayerController(object) == MAP_CONTROL_USER and GetPlayerSlotState(object) == PLAYER_SLOT_STATE_PLAYING then
        //Does not work on leaved players or computer players.
            return Modules((GetStoredReal(gc,&quot;Test&quot;,Number[HostId]) - GetStoredReal(gc,&quot;Test&quot;,Number[GetPlayerId(object)])) * 1000.)
        endif
        return 0
        //return 0 for leaved players / computer players.
    endfunction
    
    function GetHost takes nothing returns player
        return Host
    endfunction
    
    private function Update takes nothing returns nothing
        local integer i = GetPlayerId(GetLocalPlayer())
        //Magic! Does not desync!
        call StoreReal(gc,&quot;Test&quot;,Number<i>,TimerGetElapsed(GameTimer))
        //Store the value of timer.
        call SyncStoredReal(gc,&quot;Test&quot;,Number<i>)
        //Sync the value to other players&#039; gamecache.
    endfunction
    
    private function Init takes nothing returns nothing
        set Number[0] = &quot;Player 1&quot;
        set Number[1] = &quot;Player 2&quot;
        set Number[2] = &quot;Player 3&quot;
        set Number[3] = &quot;Player 4&quot;
        set Number[4] = &quot;Player 5&quot;
        set Number[5] = &quot;Player 6&quot;
        set Number[6] = &quot;Player 7&quot;
        set Number[7] = &quot;Player 8&quot;
        set Number[8] = &quot;Player 9&quot;
        set Number[9] = &quot;Player 10&quot;
        set Number[10] = &quot;Player 11&quot;
        set Number[11] = &quot;Player 12&quot;
        //Data slot for players.
        
        set GameTimer = CreateTimer()
        call TimerStart(GameTimer,1000000000.,false,null)
        //Game timer, used to measure the latency.
        
        call FlushGameCache(InitGameCache(&quot;GetLatency&quot;))
        set gc = InitGameCache(&quot;GetLatency&quot;)
        //Clear and init the gamecache.
        
        if HaveStoredInteger(gc,&quot;Host&quot;,&quot;Id&quot;) then
            set HostId = GetStoredInteger(gc,&quot;Host&quot;,&quot;Id&quot;)
        else
        // 0 = Player 1, =.=
            set HostId = GetPlayerId(GetLocalPlayer())
            call StoreInteger(gc,&quot;Host&quot;,&quot;Id&quot;,HostId)
            call SyncStoredInteger(gc,&quot;Host&quot;,&quot;Id&quot;) 
        endif
        
        set Host = Player(HostId) 
        
        call TimerStart(CreateTimer(),PERIOD,true,function Update)
        //Updater.
    endfunction
    
endlibrary
</i></i>


Is there any volunteer can help me to test this? I want to check whether the GetHost is working or not.
 

Jesus4Lyf

Good Idea™
Reaction score
397
I understand you need a point of reference, and you don't know who the host is: perhaps you can subtract it from the latest game time a player has?
There is no such thing as a reliable method to get the host, as far as I know (especially because of minimising Warcraft III). Why don't you implement what I suggested? Surely, it would just be tacked on the end (or start) of the Update function... or something.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top