Johnny C. Lam [08-10-13 - 18:40]
diff --git a/Ovale.toc b/Ovale.toc
index f5975d5..264835d 100644
--- a/Ovale.toc
+++ b/Ovale.toc
@@ -34,6 +34,7 @@ OvaleActionBar.lua
OvaleEnemies.lua
OvaleEquipement.lua
OvaleGUID.lua
+OvaleLatency.lua
OvalePool.lua
OvalePoolGC.lua
OvaleQueue.lua
@@ -41,21 +42,22 @@ OvaleRecount.lua
OvaleSkada.lua
OvaleStance.lua
#
+OvaleDamageTaken.lua
OvalePaperDoll.lua
#
OvaleData.lua
OvaleScripts.lua
defaut\Chaman.lua
defaut\Chasseur.lua
+defaut\Chevalier.lua
defaut\Demoniste.lua
defaut\Druide.lua
defaut\Guerrier.lua
defaut\Mage.lua
+defaut\Moine.lua
defaut\Paladin.lua
defaut\Pretre.lua
defaut\Voleur.lua
-defaut\Moine.lua
-defaut\Chevalier.lua
OvaleSpellDamage.lua
OvaleSwing.lua
#
@@ -65,7 +67,6 @@ OvaleOptions.lua
#
OvaleFuture.lua
#
-OvaleDamageTaken.lua
OvaleState.lua
#
OvaleCondition.lua
diff --git a/OvaleCondition.lua b/OvaleCondition.lua
index bb617f1..5553053 100644
--- a/OvaleCondition.lua
+++ b/OvaleCondition.lua
@@ -24,6 +24,7 @@ local OvaleEnemies = Ovale.OvaleEnemies
local OvaleEquipement = Ovale.OvaleEquipement
local OvaleFuture = Ovale.OvaleFuture
local OvaleGUID = Ovale.OvaleGUID
+local OvaleLatency = Ovale.OvaleLatency
local OvalePaperDoll = Ovale.OvalePaperDoll
local OvaleSpellDamage = Ovale.OvaleSpellDamage
local OvaleStance = Ovale.OvaleStance
@@ -2297,8 +2298,7 @@ OvaleCondition.conditions.lastswing = function(condition)
return 0, nil, 0, OvaleSwing:GetLast(condition[1]), 1
end
---- Get the most recent estimate of latency in milliseconds.
--- This condition is experimental and may not yield correct results.
+--- Get the most recent estimate of roundtrip latency in milliseconds.
-- @name Latency
-- @paramsig number or boolean
-- @param operator Optional. Comparison operator: equal, less, more.
@@ -2310,7 +2310,7 @@ end
-- if Latency(more 1000) Spell(sinister_strike)
OvaleCondition.conditions.latency = function(condition)
- return 0, nil, OvaleFuture.latency * 1000, 0, 0
+ return 0, nil, OvaleLatency:GetLatency() * 1000, 0, 0
end
--- Get the level of the target.
diff --git a/OvaleDamageTaken.lua b/OvaleDamageTaken.lua
index e160ef9..652dde4 100644
--- a/OvaleDamageTaken.lua
+++ b/OvaleDamageTaken.lua
@@ -15,7 +15,7 @@ Ovale.OvaleDamageTaken = OvaleDamageTaken
--<private-static-properties>
local OvaleGUID = Ovale.OvaleGUID
-local OvaleFuture = Ovale.OvaleFuture
+local OvaleLatency = Ovale.OvaleLatency
local OvalePool = Ovale.OvalePool
local OvaleQueue = Ovale.OvaleQueue
@@ -80,7 +80,7 @@ end
function OvaleDamageTaken:GetRecentDamage(interval, lagCorrection)
local lowerBound = Ovale.now - interval
if lagCorrection then
- lowerBound = lowerBound - OvaleFuture.latency
+ lowerBound = lowerBound - OvaleLatency:GetLatency()
end
self:RemoveExpiredEvents()
diff --git a/OvaleFuture.lua b/OvaleFuture.lua
index c03415c..aca9565 100644
--- a/OvaleFuture.lua
+++ b/OvaleFuture.lua
@@ -49,10 +49,6 @@ local self_lastTarget = nil
-- Time at which a player aura was last added.
local self_timeAuraAdded = nil
--- The spell requests that have been sent to the server and are awaiting a reply.
--- self_sentSpellcast[lineId] = timestamp
-local self_sentSpellcast = {}
-
local OVALE_UNKNOWN_GUID = 0
-- These CLEU events are eventually received after a successful spellcast.
@@ -69,8 +65,6 @@ local OVALE_CLEU_SPELLCAST_RESULTS = {
--<public-static-properties>
--spell counter (see Counter function)
OvaleFuture.counter = {}
--- Most recent latency (time between UNIT_SPELLCAST_SENT and UNIT_SPELLCAST_SUCCEEDED events).
-OvaleFuture.latency = 0
-- Debugging: spells to trace
OvaleFuture.traceSpellList = nil
--</public-static-properties>
@@ -167,24 +161,8 @@ local function AddSpellToQueue(spellId, lineId, startTime, endTime, channeled, a
else
spellcast.removeOnSuccess = true
end
-
tinsert(self_activeSpellcast, spellcast)
- -- Update latency measurement. API_GetTime() only updates on frame refresh (OnUpdate) so
- -- this latency measurement has a lower bound of the 1/FPS, where FPS is the current frame
- -- rate.
- if self_sentSpellcast[lineId] then
- local latency = Ovale.now - self_sentSpellcast[lineId]
- local castTime = endTime - startTime
- if castTime > 0 and latency > castTime then
- latency = castTime
- end
- if latency > 0 then
- self.latency = latency
- end
- self_sentSpellcast[lineId] = nil
- end
-
ScoreSpell(spellId)
Ovale.refreshNeeded["player"] = true
end
@@ -347,9 +325,6 @@ function OvaleFuture:UNIT_SPELLCAST_SENT(event, unit, spell, rank, target, lineI
self_lastTarget = OVALE_UNKNOWN_GUID
end
TracePrintf(spell, "%s: %f %s on %s, lineId=%d", event, Ovale.now, spell, self_lastTarget, lineId)
-
- -- Note starting time for latency calculation.
- self_sentSpellcast[lineId] = Ovale.now
end
end
diff --git a/OvaleLatency.lua b/OvaleLatency.lua
new file mode 100644
index 0000000..fdb30c2
--- /dev/null
+++ b/OvaleLatency.lua
@@ -0,0 +1,77 @@
+--[[--------------------------------------------------------------------
+ Ovale Spell Priority
+ Copyright (C) 2013 Johnny C. Lam
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License in the LICENSE
+ file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+local OvaleLatency = Ovale:NewModule("OvaleLatency", "AceEvent-3.0")
+Ovale.OvaleLatency = OvaleLatency
+
+--<private-static-properties>
+local select = select
+local API_GetNetStats = GetNetStats
+
+-- The spell requests that have been sent to the server and are awaiting a reply.
+-- self_sentSpellcast[lineId] = GetTime() timestamp
+local self_sentSpellcast = {}
+
+local self_lastUpdateTime = nil
+local self_latency = nil
+--</private-static-properties>
+
+--<public-static-methods>
+function OvaleLatency:OnEnable()
+ self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", "UpdateLatency")
+ self:RegisterEvent("UNIT_SPELLCAST_SENT")
+ self:RegisterEvent("UNIT_SPELLCAST_START", "UpdateLatency")
+ self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "UpdateLatency")
+end
+
+function OvaleLatency:OnDisable()
+ self:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START")
+ self:UnregisterEvent("UNIT_SPELLCAST_SENT")
+ self:UnregisterEvent("UNIT_SPELLCAST_START")
+ self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
+end
+
+-- Event handler for UNIT_SPELLCAST_* events that updates the current roundtrip latency.
+function OvaleLatency:UpdateLatency(event, unit, name, rank, lineId, spellId)
+ if unit == "player" and self_sentSpellcast[lineId] then
+ --[[
+ Assume an event loop looks like:
+
+ client --SENT--> server (processing) --CHANNEL_START/START/SUCCEEDED--> client
+
+ By taking the difference between the SENT and CHANNEL_START/START/SUCCEEDED events,
+ we are assuming that the processing time on the server is negligible compared to the
+ network latency. As a result, this will always over-estimate the true latency.
+ ]]--
+ local latency = Ovale.now - self_sentSpellcast[lineId]
+ if latency > 0 then
+ self_latency = latency
+ self_lastUpdateTime = Ovale.now
+ end
+ self_sentSpellcast[lineId] = nil
+ end
+end
+
+function OvaleLatency:UNIT_SPELLCAST_SENT(event, unit, spell, rank, target, lineId)
+ if unit == "player" then
+ -- Note starting time for latency calculation.
+ self_sentSpellcast[lineId] = Ovale.now
+ end
+end
+
+function OvaleLatency:GetLatency()
+ -- If we haven't cast a spell in a while, then get the average world roundtrip latency
+ -- using GetNetStats().
+ if not self_latency or not self_lastUpdateTime or Ovale.now - self_lastUpdateTime > 10 then
+ self_latency = select(4, API_GetNetStats()) / 1000
+ end
+ return self_latency
+end
+--</public-static-methods>