[3.3.3a][mac/windows] Finding current player ping/latency - help please menu

User Tag List

Results 1 to 4 of 4
  1. #1
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [3.3.3a][mac/windows] Finding current player ping/latency - help please

    So I was able to locate the lua_GetNetStats and NetClient__GetNetStats on OS X (function prototype is identical for windows, obviously offsets are different).

    Can someone give me some help on making sense of actually how to calculate the latency? I'm a bit confused by what is going on.

    I've provided the Windows information since it's the same on mac, just trying to get help:
    Code:
    006B82C0    NetClient__GetNetStats
    007125B0    lua_GetNetStats
    The actual lua function:
    Code:
    signed int __cdecl lua_GetNetStats(int a1)
    {
      int v2; // eax@1
      unsigned int v3; // [sp+10h] [bp-Ch]@1
      float v4; // [sp+14h] [bp-8h]@1
      float v5; // [sp+18h] [bp-4h]@1
    
      v2 = sub_61F9D0();
      NetClient__GetNetStats(v2, (int)&v5, (int)&v4, (int)&v3);
      FrameScript_PushNumber(a1, v5);
      FrameScript_PushNumber(a1, v4);
      FrameScript_PushNumber(a1, (double)v3);
      return 3;
    }
    Code:
    int __thiscall NetClient__GetNetStats(int this, int a2, int a3, int a4)
    {
      unsigned int v4; // eax@1
      int v5; // edx@1
      unsigned int v6; // ecx@1
      struct _RTL_CRITICAL_SECTION *v7; // ebx@1
      unsigned int v8; // edi@1
      int v9; // esi@1
      double v10; // st7@1
      int v11; // eax@6
    
      v9 = this;
      v7 = (struct _RTL_CRITICAL_SECTION *)(this + 11912);
      sub_55F450((LPCRITICAL_SECTION)(this + 11912));
      v10 = (double)(unsigned int)(sub_473610() - *(_DWORD *)(v9 + 11908)) * 0.001000000047497451;
      *(float *)a2 = (double)*(unsigned int *)(v9 + 11904) * 0.0009765625 / v10;
      v8 = 0;
      *(float *)a3 = 0.0009765625 * (double)*(unsigned int *)(v9 + 11900) / v10;
      v6 = *(_DWORD *)(v9 + 11892);
      v5 = *(_DWORD *)(v9 + 11896);
      v4 = 0;
      if ( v6 == v5 )
        goto LABEL_11;
      do
      {
        if ( v6 >= 0x10 )
        {
          v6 = 0;
          if ( !v5 )
            break;
        }
        v4 += *(_DWORD *)(v9 + 4 * v6++ + 11828);
        ++v8;
      }
      while ( v6 != v5 );
      if ( v8 )
        v11 = v4 / v8;
      else
    LABEL_11:
        v11 = 0;
      *(_DWORD *)a4 = v11;
      return sub_55F460(v7);
    }
    Obviously the lag variable is the 3rd FrameScript_PushNumber variable (v3). I think my biggest issue is understanding what "this" is. Because if I can't understand this I can't actually implement the 3rd part of NetClient__GetNetStats where v11 is calculated.

    Edit: Also, anyone know if it's possible to get "real" latency vs. once every 30 seconds? I realize the lua function is only updated once every 30 seconds, ideally I'd like something a little more real time if possible?

    Thanks in advance!!
    Last edited by Tanaris4; 03-30-2010 at 03:30 PM.
    https://tanaris4.com

    [3.3.3a][mac/windows] Finding current player ping/latency - help please
  2. #2
    barthen's Avatar Contributor Authenticator enabled
    Reputation
    84
    Join Date
    Apr 2007
    Posts
    111
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Tanaris4 View Post
    Code:
    signed int __cdecl lua_GetNetStats(int a1)
    {
      int v2; // eax@1
      unsigned int v3; // [sp+10h] [bp-Ch]@1
      float v4; // [sp+14h] [bp-8h]@1
      float v5; // [sp+18h] [bp-4h]@1
    
      v2 = sub_61F9D0();
      NetClient__GetNetStats(v2, (int)&v5, (int)&v4, (int)&v3);
      FrameScript_PushNumber(a1, v5);
      FrameScript_PushNumber(a1, v4);
      FrameScript_PushNumber(a1, (double)v3);
      return 3;
    }
    "this" is a pointer to an object (an instance of a class). Wow is programmed in C++ but your decompiler shows you the code in C. A better decompilation would be:

    Code:
    signed int __cdecl lua_GetNetStats(int a1)
    {
      NetClient * v2; // eax@1        // v2 is a pointer to a NetClient object
      unsigned int v3; // [sp+10h] [bp-Ch]@1
      float v4; // [sp+14h] [bp-8h]@1
      float v5; // [sp+18h] [bp-4h]@1
    
      v2 = sub_61F9D0();           // this function returns a pointer to a NetClient object, probably a global, look into it
    
      v2->GetNetStats((int)&v5, (int)&v4, (int)&v3);   //here you call the GetNetStats member function on the object you retrieved
    
      FrameScript_PushNumber(a1, v5);
      FrameScript_PushNumber(a1, v4);
      FrameScript_PushNumber(a1, (double)v3);
      return 3;
    }
    I don't have IDA here, but I think you should take a look into the sub_61F9D0 function. Maybe it returns a global pointer and from there you can extract the info.

  3. #3
    Apoc's Avatar Angry Penguin
    Reputation
    1387
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    void __thiscall NetClient__GetNetStats(CClientConnection *this, float *pIncomingInKbS, float *pOutgoingInKbS, float *pLagInMs)
    {
      unsigned int v4; // eax@1
      DWORD v5; // edx@1
      unsigned int v6; // ecx@1
      struct _RTL_CRITICAL_SECTION *lock; // ebx@1
      unsigned int v8; // edi@1
      CClientConnection *_this; // esi@1
      double kbSDiv; // st7@1
      float lag; // eax@6
    
      _this = this;
      lock = &this->lpcrLock;
      SCritSect__Enter(&this->lpcrLock);
      kbSDiv = (double)(PerformanceCounter() - _this->dwKbSecUsage) * 0.001000000047497451;
      *pIncomingInKbS = (double)_this->dwDownUsage * 0.0009765625 / kbSDiv;
      v8 = 0;
      *pOutgoingInKbS = 0.0009765625 * (double)_this->dwUpUsage / kbSDiv;
      v6 = _this->dword_2E74;
      v5 = _this->dword_2E78;
      v4 = 0;
      if ( v6 == v5 )
        goto LABEL_11;
      do
      {
        if ( v6 >= 16 )
        {
          v6 = 0;
          if ( !v5 )
            break;
        }
        v4 += _this->Unk1[v6++ + 2625];
        ++v8;
      }
      while ( v6 != v5 );
      if ( v8 )
        LODWORD(lag) = v4 / v8;
      else
    LABEL_11:
        LODWORD(lag) = 0;
      *(_DWORD *)pLagInMs = LODWORD(lag);
      SCritSect__Leave(lock);
    }
    Annnnnnnnnd

    Code:
    signed int __cdecl lua_GetNetStats(int a1)
    {
      CClientConnection *v2; // eax@1
      float lag; // [sp+10h] [bp-Ch]@1
      float outgoing; // [sp+14h] [bp-8h]@1
      float incoming; // [sp+18h] [bp-4h]@1
    
      v2 = ClientServices_GetCurrent();
      NetClient__GetNetStats(v2, &incoming, &outgoing, &lag);
      FrameScript_PushNumber(a1, incoming);
      FrameScript_PushNumber(a1, outgoing);
      FrameScript_PushNumber(a1, (double)LODWORD(lag));
      return 3;
    }
    Should clear up a few things at least.

  4. #4
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Apoc - thanks for the detail, helped me make a bit more sense out of it.

    Edit 2: Got it working! Here it is for mac:

    Code:
    // 3.3.3a: 0xC9241C ClientServices_GetCurrent
    - (float)getPing{
    	
    	MemoryAccess *memory = [self wowMemoryAccess];
    	int totalPings = 0, v5 = 0, v6 = 0, samples = 0, ping = 0;
    	UInt32 gCurrentClientServices = 0;
    	[memory loadDataForObject: self atAddress: 0xC9241C Buffer: (Byte*)&gCurrentClientServices BufLength: sizeof(gCurrentClientServices)];
    	[memory loadDataForObject: self atAddress: gCurrentClientServices + 0x2E74 Buffer: (Byte*)&v6 BufLength: sizeof(v6)];
    	[memory loadDataForObject: self atAddress: gCurrentClientServices + 0x2E78 Buffer: (Byte*)&v5 BufLength: sizeof(v5)];
    	
    	if ( v6 == v5 ){
    		return 0.0f;
    	}
    	
    	do
    	{
    		if ( v6 >= 16 ){
    			v6 = 0;
    			if ( !v5 )
    				break;
    		}
    		
    		// 0xA41 might need to be *4
    		[memory loadDataForObject: self atAddress: gCurrentClientServices + 0x2E34 + (v6 * 4) Buffer: (Byte*)&ping BufLength: sizeof(ping)];
    		v6++;
    		PGLog(@"read %d", ping);
    		totalPings += ping;
    		
    		//v4 += _this->Unk1[v6++ + 2625];
    		++samples;
    	}
    	while ( v6 != v5 );
    	
    	if ( samples > 0 ){
    		float ping = (float)totalPings / (float)samples;
    		
    		return ping;
    	}
    
    	return 0.0f;
    }
    In other news, have you posted your pdb Apoc? would you be willing to? For a donation? Would love to get a peak @ that when I'm reversing the mac binary.
    Last edited by Tanaris4; 03-31-2010 at 08:33 AM.
    https://tanaris4.com

Similar Threads

  1. [Question] Finding the player base pointer
    By ddebug in forum WoW Memory Editing
    Replies: 8
    Last Post: 02-24-2012, 12:15 AM
  2. [Guide] Downgrade to 3.3.5 [Mac & Windows] (USA)
    By Jinfreakz in forum World of Warcraft Guides
    Replies: 23
    Last Post: 09-08-2011, 12:05 AM
  3. [mac] Trying to find "Current Time"
    By Tanaris4 in forum WoW Memory Editing
    Replies: 1
    Last Post: 10-14-2010, 03:38 PM
  4. when i start DButilEx it says "Crittical error cant find file players.save"
    By Foxmandan in forum World of Warcraft Emulator Servers
    Replies: 0
    Last Post: 01-11-2008, 03:11 PM
All times are GMT -5. The time now is 12:39 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search