The *real* way to determine latency tiers

Started by brew, August 06, 2010, 02:00:10 AM

Previous topic - Next topic

brew

A lot of people wonder how exactly the 'lag bars' in Starcraft are determined - there are arguments of the precise range, in particular (i.e., is it 300-400, or is it 300-399, is it 299-399, etc). As a result, people would typically code a function to get the lag bar icon like this:

int GetPingIcon(uint32_t ping, uint32_t flags) {
    if (flags & 0x10)
        return ICON_LAG_PLUG;
    else if (ping == 0xFFFFFFFF)
        return ICON_LAG_NEG1;
    else if (ping == 0)
        return ICON_LAG_0;
    else if (ping <= 200)
        return ICON_LAG_1G;
    else if (ping <= 300)
        return ICON_LAG_2G;
    else if (ping <= 400)
        return ICON_LAG_3Y;
    else if (ping <= 500)
        return ICON_LAG_4Y;
    else if (ping <= 600)
        return ICON_LAG_5R;
    else
        return ICON_LAG_6R;
}


At the behest of Myst, I dug this up from Starcraft's battle.snp:


...
    v4 = GetDlgItem(dword_19045640, 1003);
    lpResult = sub_1902E200(v3, v5, *(_DWORD *)v2);
    if ( lpResult == -1 ) {
      v6 = *(_DWORD *)v2;
      if ( sub_1902E0B0(v3, *(_DWORD *)v2) )
        *(_DWORD *)(v2 + 8) |= 0x20u;
      ping = *(_DWORD *)(v2 + 12);
      if ( ping >= 10 ) {
        pingstep = ping / 100;
        if ( ping / 100 < 6 ) {
          if ( !pingstep )
            pingstep = 1;
        } else {
          pingstep = 6;
        }
      } else {
        pingstep = 0;
      }
      sprintf(&lParam, "%s\t%d %d\t%s", v6, *(_DWORD *)(v2 + 8), pingstep, *(_DWORD *)(v2 + 4));
      SendMessageA(v4, ((*(_DWORD *)(v2 + 8) & 0xF) != 0) + 384, 0, (LPARAM)&lParam);
...

(1.16.1, battle!19030420)

So as you can see, Starcraft doesn't assign any icon to latencies that are below 10, and for anything else, takes the quotient of the ping value after integer division by 100.

Knowing this, a better and more correct way to code the same GetPingIcon function above would be like so (this is, of course, assuming that the ping icons are consecutive in nature):

int GetPingIcon(uint32_t ping, uint32_t flags) {
    if (flags & 0x10)
        return ICON_LAG_PLUG;
    if (ping < 10)
        return ICON_LAG_0;
    return ICON_LAG_1G + ((ping < 600) ? (ping / 100) : 6);
}


That is all.