1
0
Bifurcation 0
Ce dépôt a été archivé le 2020-03-15. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
questhelperredux/QuestHelper/collect.lua

304 lignes
9.8 KiB
Lua

local GetTime = QuestHelper_GetTime
QuestHelper_File["collect.lua"] = "4.0.1.$svnversion$"
QuestHelper_Loadtime["collect.lua"] = GetTime()
local --[[ static ]] MINSVNVERSION = 283
local --[[ static ]] PURGEDEV = false
local debug_output = false
if QuestHelper_File["collect.lua"] == "Development Version" then debug_output = true end
local QuestHelper_Collector_Version_Current = 9
QuestHelper_Collector = {}
QuestHelper_Collector_Version = QuestHelper_Collector_Version_Current
local OnUpdateRegistrar = {}
local TooltipRegistrar = {}
local function OnUpdateHookRegistrar(func)
QuestHelper: Assert(func)
table.insert(OnUpdateRegistrar, func)
end
local suppress = false
-- real tooltips don't use this function
local SetTextScript = GameTooltip.SetText
GameTooltip.SetText = function (...)
suppress = true
SetTextScript(...)
suppress = false
end
local function CollectTooltippery(self)
if not self then self = GameTooltip end
for k, v in pairs(TooltipRegistrar) do
v(self)
end
-- anything past here is not my fault
end
local ottsu = GameTooltip:GetScript("OnTooltipSetUnit")
QH_Hook(GameTooltip, "OnTooltipSetUnit", function (self, ...)
CollectTooltippery(self)
if ottsu then return QH_Hook_NotMyFault(ottsu, self, ...) end
end, "collection OnTooltipSetUnit")
local ottsi = GameTooltip:GetScript("OnTooltipSetItem")
QH_Hook(GameTooltip, "OnTooltipSetItem", function (self, ...)
CollectTooltippery(self)
if ottsi then return QH_Hook_NotMyFault(ottsi, self, ...) end
end, "collection OnTooltipSetItem")
local ottsh = GameTooltip:GetScript("OnShow")
QH_Hook(GameTooltip, "OnShow", function (self, ...)
CollectTooltippery(self)
if ottsh then return QH_Hook_NotMyFault(ottsh, self, ...) end
end, "collection OnShow")
local function TooltipHookRegistrar(func)
QuestHelper: Assert(func)
table.insert(TooltipRegistrar, func)
end
local API = {
Registrar_OnUpdateHook = OnUpdateHookRegistrar,
Registrar_TooltipHook = TooltipHookRegistrar,
Callback_Location_Raw = function () return QuestHelper:Location_RawRetrieve() end,
Callback_Location_Absolute = function () return QuestHelper:Location_AbsoluteRetrieve() end,
}
-- We do these early, because some things that aren't in collect may rely on these. Yes I realize that avoiding this was one of my main goals in the separate collect system, shut up go away I hate you (in all seriousness: crunch mode + lazy = some nasty bits.)
-- TODO: Make a common collect/mainmodule system, then rely on that better.
QH_Collect_Util_Init(nil, API) -- Some may actually add their own functions to the API, and should go first. There's no real formalized order, I just know which depend on others, and it's heavily asserted so it will break if it goes in the wrong order.
QH_Collect_Merger_Init(nil, API)
QH_Collect_Bitstream_Init(nil, API)
QH_Collect_Location_Init(nil, API)
QH_Collect_Patterns_Init(nil, API)
QH_Collect_Notifier_Init(nil, API)
QH_Collect_Spec_Init(nil, API)
QH_Collect_LZW_Init(nil, API)
local CompressCollection
function QH_Collector_SetupData()
local svnversion = "$svnversion$"
local buildInfo, locale, faction = GetBuildInfo(), GetLocale(), QuestHelper:PlayerFaction()
local altfaction = ""
if faction == "Alliance" then
altfaction = "Alliance"
elseif faction == "Horde" then
altfaction = "Horde"
else
altfaction = "Neutral"
end
local realm = GetRealmName()
if not QuestHelper_Collector.created then
QuestHelper_Collector.created = time();
end
local session = string.format("%q\t%q\t%q\t%q\t%q", svnversion, realm, buildInfo, locale, altfaction)
if not QuestHelper_Collector.sessions then QuestHelper_Collector.sessions = {} end
QuestHelper_Collector.sessions[sessiontime] = session
if not QuestHelper_Collector.data then QuestHelper_Collector.data = {} end
QuestHelper_Collector.data[sessiontime] = {}
return QuestHelper_Collector.data[sessiontime]
end
function QH_Collector_FactionChange()
local QHCData = QH_Collector_SetupData()
QH_Collect_Achievement_FactionChange(QHCData, API)
QH_Collect_Zone_FactionChange(QHCData, API)
QH_Collect_Hearth_FactionChange(QHCData, API)
QH_Collect_Monster_FactionChange(QHCData, API)
QH_Collect_Item_FactionChange(QHCData, API)
QH_Collect_Object_FactionChange(QHCData, API)
QH_Collect_Flight_FactionChange(QHCData, API)
QH_Collect_Quest_FactionChange(QHCData, API)
QH_Collect_Warp_FactionChange(QHCData, API)
end
function QH_Collector_Init()
-- Dunno why, but these statements cause the 1% issue.
--[[
QH_Collector_UpgradeAll(QuestHelper_Collector)
for _, v in pairs(QuestHelper_Collector) do
if not v.modified then v.modified = time() - 7 * 24 * 60 * 60 end -- eugh. Yeah, we set it to be a week ago. It's pretty grim.
end
--]]
QuestHelper_Collector_Version = QuestHelper_Collector_Version_Current
local remove_sigs = {}
for k, v in pairs(QuestHelper_Collector) do
local sig = k:match("^(%d)a$") or k:match("^(%d)b$") or k:match("^(%d)r$")
if sig then
if tonumber(sig) < MINSVNVERSION then
table.insert(remove_sigs, sig)
end
elseif k ~= svnversion then
table.insert(remove_sigs, k)
elseif k == "$svnversion\$" and PURGEDEV then
table.insert(remove_sigs, k)
end
end
for _, v in ipairs(remove_sigs) do
QuestHelper_Collector[v] = nil
end
local QHCData = QH_Collector_SetupData()
QuestHelper: Assert(not QHCData.compressed)
QH_Collect_Achievement_Init(QHCData, API)
QH_Collect_Traveled_Init(QHCData, API)
QH_Collect_Zone_Init(QHCData, API)
QH_Collect_Hearth_Init(QHCData, API)
QH_Collect_Monster_Init(QHCData, API)
QH_Collect_Item_Init(QHCData, API)
QH_Collect_Object_Init(QHCData, API)
QH_Collect_Flight_Init(QHCData, API)
QH_Collect_Quest_Init(QHCData, API)
QH_Collect_Warp_Init(QHCData, API)
QH_Collect_Loot_Init(QHCData, API)
QH_Collect_Equip_Init(QHCData, API)
QH_Collect_Merchant_Init(QHCData, API)
if false then -- this will be disabled in most public releases, or set to a very rare probabalistic thing
if not QHCData.routing_dump then QHCData.routing_dump = {} end
local nt = {}
table.insert(QHCData.routing_dump, nt)
QH_Collect_Routing_Dump = nt
end
-- So, why do we delay it?
-- It's simple. People are gonna update to this version, and then they're going to look at the memory usage. Then they will panic because omg this version uses so much more memory, I bet that will somehow hurt my framerates in a way which is not adequately explained!
-- So instead, we just wait half an hour before compressing. Compression will still get done, and I won't have to deal with panicked comments about how bloated QH has gotten.
-- addendum: yeah naturally I'm getting all sorts of panicked comments about how bloated qh has gotten, sigh
--API.Utility_Notifier(GetTime() + (debug_output and 0 or (30 * 60)), function() CompressCollection(QHCData, QuestHelper_Collector[sig_altfaction], API.Utility_Merger, API.Utility_LZW.Compress) end)
QH_Event("NEUTRAL_FACTION_SELECT_RESULT", QH_Collector_FactionChange)
end
QH_OnUpdate(function ()
local tstart = GetTime()
for _, v in pairs(OnUpdateRegistrar) do
v()
end
QH_Timeslice_Increment(GetTime() - tstart, "collect_update")
end)
--- I've tossed the compression stuff down here just 'cause I don't feel like making an entire file for it (even though I probably should.)
local noncompressible = {
modified = true,
version = true,
}
local squarify
local seritem
local serializers = {
["nil"] = function(item, add)
add("nil")
end,
["number"] = function(item, add)
add(tostring(item))
end,
["string"] = function(item, add)
add(string.format("%q", item))
end,
["boolean"] = function(item, add)
add(item and "true" or "false")
end,
["table"] = function(item, add)
add("{")
local first = true
for k, v in pairs(item) do
if not first then add(",") end
first = false
add("[")
seritem(k, add)
add("]=")
seritem(v, add)
end
add("}")
end,
}
seritem = function(item, add)
QH_Timeslice_Yield()
serializers[type(item)](item, add)
end
local function DoCompress(item, merger, comp)
if debug_output then QuestHelper: TextOut("Item condensing") end
local ts = GetTime()
local target = {}
for k, v in pairs(item) do
if not noncompressible[k] then
target[k] = v
end
end
local mg = {}
seritem(target, function(dat) merger.Add(mg, dat) end)
local tg = merger.Finish(mg)
if debug_output then QuestHelper: TextOut(string.format("Item condensed to %d bytes, %f taken so far", #tg, GetTime() - ts)) end
mg = nil
local cmp = {}
local cmptot = 0
local doublecheck = ""
for chunk = 1, #tg, 1048576 do
local fragment = tg:sub(chunk, chunk + 1048575)
doublecheck = doublecheck .. fragment
local ite = comp(fragment, 256, 8)
cmptot = cmptot + #ite
table.insert(cmp, ite)
end
QuestHelper: Assert(doublecheck == tg)
if #cmp == 1 then cmp = cmp[1] end
for k, v in pairs(target) do
if not noncompressible[k] then
item[k] = nil
end
end
item.compressed = cmp
if debug_output then QuestHelper: TextOut(string.format("Item compressed to %d bytes in %d shards (previously %d), %f taken", cmptot, type(cmp) == "table" and #cmp or 1, #tg, GetTime() - ts)) end
end
CompressCollection = function(active, active2, merger, comp)
for _, v in pairs(QuestHelper_Collector) do
if v ~= active and v ~= active2 and not v.compressed then
QH_Timeslice_Add(function ()
DoCompress(v, merger, comp)
CompressCollection(active, active2, merger, comp)
end, "compress")
break
end
end
end