バフ/デバフの効果時間について

2020/03/02 追記
development版, stable版共に本件は修正されました。
Update bufftime offset by Nifim · Pull Request #1837 · Windower/Lua · GitHub
Dev > Live merge by z16 · Pull Request #1839 · Windower/Lua · GitHub

プレイヤーのバフ/デバフの効果時間は、incomingの0x063(Order=0x09)パケットで取得できます。


このパケットの定義をlibs/packets/fields.luaから抜粋すると以下になります。

-- libs/packets/fields.lua
local time
local utime
do
    local now = os.time()
    local h, m = (os.difftime(now, os.time(os.date('!*t', now))) / 3600):modf()

    local timezone = '%+.2d:%.2d':format(h, 60 * m)

    local fn = function(ts)
        return os.date('%Y-%m-%dT%H:%M:%S' .. timezone, ts)
    end

    time = function(ts)
        return fn(os.time() - ts)
    end

    utime = function(ts)
        return fn(ts)
    end

    bufftime = function(ts)
        return fn((ts / 60) + 501079520 + 1009810800)
    end
end

local function buff(val)
    return val ~= 0xFF and res.buffs[val].name or '-'
end

func.incoming[0x063][0x09] = L{
    {ctype='unsigned short',    label='_unknown1',          const=0x00C4},      -- 06
    {ctype='unsigned short[32]',label='Buffs',              fn=buff},           -- 08
    {ctype='unsigned int[32]',  label='Time',               fn=bufftime},       -- 48
}

プレイヤーのバフ/デバフは最大32個まで表示されるので、長さが32の配列になっています。
"{ctype='unsigned short[32]',label='Buffs',fn=buff}"には、バフ/デバフのIDが入っています。
"{ctype='unsigned int[32]', label='Time',fn=bufftime}"には、バフ/デバフの効果時間を示す数値が入っていますが、少し特殊で60分の1秒の単位で入っています。
さらにこの数値は"あるUNIX時間"から経過した時間でバフ/デバフの効果終了の時間を示しています。
"あるUNIX時間"とは、501079520 + 1009810800 = 1510890320で、時刻に変換すると2017-11-17 12:45:20(JST)になります。
例えば、Time = 0x50000000の場合、 0x50000000/60 + 501079520 + 1009810800 = 1533259941になり、2018-08-03 10:32:21(JST)にバフ/デバフの効果が終了することになります。
バフ/デバフの効果時間(Time)のサイズはunsigned intで32bitです。
ここでTimeの最大値の0xFFFFFFFFを考えてみます。これを時刻に変換すると2020-02-24 00:51:48(JST) (0xFFFFFFFF/60 + 501079520 + 1009810800 = 1582473108)になり、最近この時間のカウンタが1周したことになります。
基準となる時刻がハードコーディングされているため、カウンタが一周するとこのままの計算ではバフ/デバフの終了時刻が正しく取得できなくなります。
例えば、カウンタが一周して0x00000001になると2017-11-17 12:45:20(JST)となり、過去の時刻を示し、効果時間が負の値となってしまいます。
実際に自身の環境では2020年2月24日以降、Windower上でバフ/デバフの効果時間が正しく取得できなくなりました。(もちろん、FF11のクライアント上では問題ありません)
GearSwapでは、上記のパケットを使用してバフ/デバフの効果時間を取得しているので、player.buff_detailsのtimeやdurationの値がおかしくなりました。(2020/02/26の時点ではまだ修正されていないようです。)
PacketViewerでもlibs/packets/filelds.luaを使用しているので、incoming 0x063(Order=0x09)のパケットの表示がおかしなります。
GearSwapなどが公式に修正されるまでは、基準の時刻がカウンタが一周した時刻の2020-02-24 00:51:48(JST)になるように0xFFFFFFFF/60 = 71582788を上記の計算式に加算しておくととりあえずは動作するようになります。

-- libs/packets/fields.lua
    bufftime = function(ts)
        return fn((ts / 60) + 501079520 + 1009810800 + 71582788)
    end

GearSwapでは、

-- packet_parsing.lua 459行目付近
                local t = data:unpack('I',i*4+0x45)/60+501079520+1009810800+71582788

次回、このカウンタが一周するのは、2022-06-01 12:58:16(JST)(0xFFFFFFFF/60 + 501079520 + 1009810800 + 71582788 = 1654055896)のようです。