if (true) then --return end local Details = _G.Details local bit = _G.bit local DETAILS_ATTRIBUTE_DAMAGE = _G.DETAILS_ATTRIBUTE_DAMAGE local DF = _G.DetailsFramework local tonumber = _G.tonumber local select = _G.select local strsplit = _G.strsplit local floor = _G.floor local tremove = _G.tremove local UnitName = _G.UnitName local tinsert = tinsert local IsInRaid = _G.IsInRaid local GetNumGroupMembers = _G.GetNumGroupMembers local GetRaidRosterInfo = _G.GetRaidRosterInfo local unpack = _G.unpack local IsInGroup = _G.IsInGroup local addonName, Details222 = ... Details.packFunctions = {} --lookup actor information tables local actorInformation = {} local actorInformationIndexes = {} local actorDamageInfo = {} local actorHealInfo = {} local actorUtilityInfo = {} --flags local REACTION_HOSTILE = 0x00000040 local IS_GROUP_OBJECT = 0x00000007 local REACTION_FRIENDLY = 0x00000010 local OBJECT_TYPE_MASK = 0x0000FC00 local OBJECT_TYPE_OBJECT = 0x00004000 local OBJECT_TYPE_PETGUARDIAN = 0x00003000 local OBJECT_TYPE_GUARDIAN = 0x00002000 local OBJECT_TYPE_PET = 0x00001000 local OBJECT_TYPE_NPC = 0x00000800 local OBJECT_TYPE_PLAYER = 0x00000400 local INDEX_EXPORT_FLAG = 1 local INDEX_COMBAT_START_TIME = 2 local INDEX_COMBAT_END_TIME = 3 local INDEX_COMBAT_START_DATE = 4 local INDEX_COMBAT_END_DATE = 5 local INDEX_COMBAT_NAME = 6 local TOTAL_INDEXES_FOR_COMBAT_INFORMATION = 6 local entitySerialCounter = 0 local isDebugging = false function Details.packFunctions.GetAllData() local combat = Details:GetCurrentCombat() local packedData = Details.packFunctions.PackCombatData(combat, 0x1B) --local packedData = Details.packFunctions.PackCombatData(combat, 0x13) return packedData end --debug function Details.packFunctions.GetAllDataDebug() local combat = Details:GetCurrentCombat() local packedData = Details.packFunctions.PackCombatData(combat, 0x13) --unpack data Details.packFunctions.DeployPackedCombatData(packedData) end --pack the combat function Details.packFunctions.PackCombatData(combatObject, flags) --0x1 damage --0x2 healing --0x4 energy --0x8 misc --0x10 no combat header Details:Destroy(actorInformation) Details:Destroy(actorInformationIndexes) Details:Destroy(actorDamageInfo) Details:Destroy(actorHealInfo) Details:Destroy(actorUtilityInfo) --reset the serial counter entitySerialCounter = 0 local isBossEncouter = combatObject.is_boss local startDate, endDate = combatObject:GetDate() local startCombatTime = combatObject:GetStartTime() or 0 local endCombatTime = combatObject:GetEndTime() or 0 local combatInfo = { floor(startCombatTime), --1 floor(endCombatTime), --2 startDate, --3 endDate, --4 isBossEncouter and isBossEncouter.encounter or "Unknown Enemy" --5 } --if there's no combat information, indexes for combat data is zero if (bit.band(flags, 0x10) ~= 0) then TOTAL_INDEXES_FOR_COMBAT_INFORMATION = 0 end if (bit.band(flags, 0x1) ~= 0) then ---print("pack damage") Details.packFunctions.PackDamage(combatObject) end if (bit.band(flags, 0x2) ~= 0) then --print("pack heal") Details.packFunctions.PackHeal(combatObject) end if (bit.band(flags, 0x8) ~= 0) then --print("pack utility") Details.packFunctions.PackUtility(combatObject) end --prepare data to send over network local exportedString = flags .. "," --add the combat info if (bit.band(flags, 0x10) == 0) then for index, data in ipairs(combatInfo) do exportedString = exportedString .. data .. "," end end --add the actor references table for index, data in ipairs(actorInformation) do exportedString = exportedString .. data .. "," end --add the damage actors data if (bit.band(flags, 0x1) ~= 0) then exportedString = exportedString .. "!D" .. "," for index, data in ipairs(actorDamageInfo) do exportedString = exportedString .. data .. "," end end --add the heal actors data if (bit.band(flags, 0x2) ~= 0) then exportedString = exportedString .. "!H" .. "," for index, data in ipairs(actorHealInfo) do exportedString = exportedString .. data .. "," end end --add the utility actors data if (bit.band(flags, 0x8) ~= 0) then exportedString = exportedString .. "!U" .. "," for index, data in ipairs(actorUtilityInfo) do exportedString = exportedString .. data .. "," end end --main stuff --print("finished export (debug):", exportedString) --debug --print("uncompressed (debug):", format("%.2f", #exportedString/1024), "KBytes") --if true then return exportedString end if (isDebugging) then print(exportedString) end --Details:Dump({exportedString}) --print("EXPORTING STRING FINAL:", exportedString) --compress local LibDeflate = _G.LibStub:GetLibrary("LibDeflate") local dataCompressed = LibDeflate:CompressDeflate(exportedString, {level = 9}) local dataEncoded = LibDeflate:EncodeForWoWAddonChannel(dataCompressed) --print("encoded for WowAddonChannel (debug):", format("%.2f", #dataEncoded/1024), "KBytes") return dataEncoded end function Details.packFunctions.GenerateSerialNumber() local serialNumber = entitySerialCounter entitySerialCounter = entitySerialCounter + 1 return serialNumber end --[[ actor flag IDs 1: player friendly 2: player enemy 3: enemy npc pet 4: enemy npc non-pet 5: friendly npc pet 6: friendly non-npc 7: unknown entity type ]] local packActorFlag = function(actor) if (actor.grupo) then --it's a player in the group return 1 end local flag = actor.flag_original or 0 --check hostility if (bit.band(flag, REACTION_HOSTILE) ~= 0) then --is hostile if (bit.band(flag, OBJECT_TYPE_PLAYER) == 0) then --isn't a player if (bit.band(flag, OBJECT_TYPE_PETGUARDIAN) ~= 0) then --is pet return 3 else --is enemy npc return 4 end else --is enemy player return 2 end else --is friendly if (bit.band(flag, OBJECT_TYPE_PLAYER) == 0) then --is player return 1 else --isn't a player if (bit.band(flag, OBJECT_TYPE_PETGUARDIAN) ~= 0) then --is friendly pet return 5 else --is a friendly entity, most likely a npc return 6 end end end return 7 end local unpackActorFlag = function(flag) --convert to integer flag = tonumber(flag) if (flag == 1) then --player return 0x511 elseif (flag == 2) then --enemy player return 0x548 elseif (flag == 3) then --enemy pet with player or AI controller return 0x1A48 elseif (flag == 4) then --enemy npc return 0xA48 elseif (flag == 5) then --friendly pet return 0x1914 elseif (flag == 6) then --friendly npc return 0xA14 elseif (flag == 7) then --unknown entity return 0x4A28 end end local isActorInGroup = function(class, flag) if (bit.band(flag, IS_GROUP_OBJECT) ~= 0 and class ~= "UNKNOW" and class ~= "UNGROUPPLAYER" and class ~= "PET") then return true end return false end --[[ actor class IDs 1-12: player class Id 20: "PET" 21: "UNKNOW" 22: "UNGROUPPLAYER" 23: "ENEMY" 24: "MONSTER" ]] local detailsClassIndexToFileName = { [20] = "PET", [21] = "UNKNOW", [22] = "UNGROUPPLAYER", [23] = "ENEMY", [24] = "MONSTER", } local packActorClass = function(actor) local classId = DF.ClassFileNameToIndex[actor.classe] if (classId) then return classId elseif (classId == "PET") then return 20 elseif (classId == "UNKNOW") then return 21 elseif (classId == "UNGROUPPLAYER") then return 22 elseif (classId == "ENEMY") then return 23 elseif (classId == "MONSTER") then return 24 end return 21 end local unpackActorClass = function(classId) --convert to integer classId = tonumber(classId) local classFileName = DF.ClassIndexToFileName[classId] if (not classFileName) then classFileName = detailsClassIndexToFileName[classId] end return classFileName end --[[ actor serial creature: C12345 (numbers are the npcId) player: P --]] local packActorSerial = function(actor) local serial = actor.serial if (serial:match("^C") == "C") then local npcId = tonumber(select(6, strsplit("-", serial)) or 0) return "C" .. npcId elseif (serial:match("^P") == "P") then return "P" elseif (serial == "") then return "C12345" end end local unpackActorSerial = function(serialNumber) --player serial if (serialNumber:match("^P")) then return "Player-1-" .. Details.packFunctions.GenerateSerialNumber() elseif (serialNumber:match("^C")) then return "Creature-0-0-0-0-" .. serialNumber:gsub("C", "") .."-" .. Details.packFunctions.GenerateSerialNumber() end end function Details.packFunctions.AddActorInformation(actor) --the next index to use on the actor info table local currentIndex = #actorInformation + 1 --calculate where this actor will be placed on the combatData table local indexOnCombatDataTable = TOTAL_INDEXES_FOR_COMBAT_INFORMATION + currentIndex + 1 --add the actor start information index actorInformationIndexes[actor.nome] = indexOnCombatDataTable --index 1: actor name actorInformation[currentIndex] = actor.nome or "unnamed" --[1] --index 2: actor flag actorInformation[currentIndex + 1] = packActorFlag(actor) --[2] --index 3: actor serial actorInformation[currentIndex + 2] = packActorSerial(actor) or "" --[3] --index 4: actor class actorInformation[currentIndex + 3] = packActorClass(actor) --[4] --index 5: actor spec actorInformation[currentIndex + 4] = actor.spec or 0 --[5] return indexOnCombatDataTable end function Details.packFunctions.RetriveActorInformation(combatData, index) --name [1] local actorName = combatData[index] if (not actorName) then return end --flag [2] local actorFlag = combatData[index + 1] actorFlag = unpackActorFlag(actorFlag) --serial [3] local serialNumber = combatData[index + 2] serialNumber = unpackActorSerial(serialNumber) --class[4] local class = combatData[index + 3] class = unpackActorClass(class) --spec[5] local spec = tonumber(combatData[index + 4]) --return the values return actorName, actorFlag, serialNumber, class, spec end --pack damage passes the player damage info + pets the player own --each player will also send an enemy, the enemy will be in order of raidIndex of the player function Details.packFunctions.PackDamage(combatObject) if (isDebugging) then print("PackDamage(): start.") end --store actorObjects to pack local actorsToPack = {} --get the player object from the combat > damage container local playerName = Details.playername local playerObject = combatObject:GetActor(DETAILS_ATTRIBUTE_DAMAGE, playerName) if (not playerObject) then if (isDebugging) then print("PackDamage(): return | no player object.") end return end tinsert(actorsToPack, playerObject) --get the list of pets the player own local playerPets = playerObject.pets for _, petName in ipairs(playerPets) do local petObject = combatObject:GetActor(DETAILS_ATTRIBUTE_DAMAGE, petName) if (petObject) then tinsert(actorsToPack, petObject) end end local playerIndex = _G.UnitInRaid("player") if (not playerIndex) then --no player index if (isDebugging) then print("PackDamage(): return | no player index found.") end return end --get all npc enemies and sort them by their respaw id local allActors = combatObject[DETAILS_ATTRIBUTE_DAMAGE]._ActorTable local allEnemies = {} --this have subtables, format: {actorObject, spawnId} for i = 1, #allActors do --get the actor object local actor = allActors[i] --check if is an enemy or neutral if (actor:IsNeutralOrEnemy()) then --get the spawnId local spawnId = select(7, strsplit("-", actor.serial)) if (spawnId) then --convert hex to number spawnId = tonumber(spawnId:sub(1, 10), 16) if (spawnId) then --first index is the actorObject, the second index is the spawnId to sort enemies tinsert(allEnemies, {actor, spawnId}) end end end end --sort enemies by their spawnId table.sort(allEnemies, Details.Sort2) local allPlayerNames = {} for i = 1, 20 do local name, _, subgroup = GetRaidRosterInfo(i) if (name) then --maybe the group has less than 20 players name = _G.Ambiguate(name, "none") if (name and subgroup <= 4) then tinsert(allPlayerNames, name) end end end table.sort(allPlayerNames, function(t1, t2) return t1 < t2 end) local playerName = UnitName("player") for i = 1, #allPlayerNames do if (playerName == allPlayerNames[i]) then playerIndex = i break end end --this is the enemy that this player has to send local enemyObjectToSend = allEnemies[playerIndex] and allEnemies[playerIndex][1] if (enemyObjectToSend) then tinsert(actorsToPack, enemyObjectToSend) end --add the actors to actor information table for _, actorObject in ipairs(actorsToPack) do --check if already has the actor information local indexToActorInfo = actorInformationIndexes[actorObject.nome] --actor name if (not indexToActorInfo) then --need to add the actor general information into the actor information table indexToActorInfo = Details.packFunctions.AddActorInformation(actorObject) end end for i = 1, #actorsToPack do --get the actor object local actor = actorsToPack[i] local indexToActorInfo = actorInformationIndexes[actor.nome] --where the information of this actor starts local currentIndex = #actorDamageInfo + 1 --[1] index where is stored the this actor info like name, class, spec, etc actorDamageInfo[currentIndex] = indexToActorInfo --[1] --[2 - 6] actorDamageInfo [currentIndex + 1] = floor(actor.total) --[2] actorDamageInfo [currentIndex + 2] = floor(actor.totalabsorbed) --[3] actorDamageInfo [currentIndex + 3] = floor(actor.damage_taken) --[4] actorDamageInfo [currentIndex + 4] = floor(actor.friendlyfire_total) --[5] actorDamageInfo [currentIndex + 5] = floor(actor.total_without_pet) --[6] local spellContainer = actor.spells._ActorTable --reserve an index to tell the length of spells actorDamageInfo [#actorDamageInfo + 1] = 0 local reservedSpellSizeIndex = #actorDamageInfo local totalSpellIndexes = 0 for spellId, spellInfo in pairs(spellContainer) do local spellDamage = spellInfo.total local spellHits = spellInfo.counter local spellTargets = spellInfo.targets actorDamageInfo [#actorDamageInfo + 1] = floor(spellId) actorDamageInfo [#actorDamageInfo + 1] = floor(spellDamage) actorDamageInfo [#actorDamageInfo + 1] = floor(spellHits) totalSpellIndexes = totalSpellIndexes + 3 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorDamageInfo [#actorDamageInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, damageDone in pairs(spellTargets) do actorDamageInfo [#actorDamageInfo + 1] = actorName actorDamageInfo [#actorDamageInfo + 1] = floor(damageDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorDamageInfo[reservedSpellSizeIndex] = totalSpellIndexes end if (isDebugging) then print("PackDamage(): done.") end end -------------------------------------------------------------------------------------------------------------------------------- --unpack --@currentCombat: details! combat object --@combatData: array with strings with combat information --@tablePosition: first index of the first damage actor function Details.packFunctions.UnPackDamage(currentCombat, combatData, tablePosition) if (isDebugging) then print("UnPackDamage(): start.") end --get the damage container local damageContainer = currentCombat[DETAILS_ATTRIBUTE_DAMAGE] --loop from 1 to 199, the amount of actors store is unknown --todo: it's only unpacking the first actor from the table, e.g. theres izimode and eye of corruption, after export it only shows the eye of corruption --table position does not move forward for i = 1, 199 do --actor information index in the combatData table --this index gives the position where the actor name, class, spec are stored local actorReference = tonumber(combatData[tablePosition]) --[1] local actorName, actorFlag, serialNumber, class, spec = Details.packFunctions.RetriveActorInformation(combatData, actorReference) if (isDebugging) then print("UnPackDamage(): Retrivied Data From " .. (actorReference or "nil") .. ":", actorName, actorFlag, serialNumber, class, spec) end --check if all damage actors has been processed --if there's no actor name it means it reached the end if (not actorName) then if (isDebugging) then print("UnPackDamage(): break damage, end index:", i, (actorReference or "nil"), "tablePosition:", tablePosition, "value:", combatData[tablePosition]) end break end --get or create the actor object local actorObject = damageContainer:GetOrCreateActor(serialNumber, actorName, actorFlag, true) --set the actor class, spec and group actorObject.classe = class actorObject:SetSpecId(spec) actorObject.grupo = isActorInGroup(class, actorFlag) actorObject.flag_original = actorFlag --copy back the base damage actorObject.total = tonumber(combatData[tablePosition+1]) --[2] actorObject.totalabsorbed = tonumber(combatData[tablePosition+2]) --[3] actorObject.damage_taken = tonumber(combatData[tablePosition+3]) --[4] actorObject.friendlyfire_total = tonumber(combatData[tablePosition+4]) --[5] actorObject.total_without_pet = tonumber(combatData[tablePosition+5]) --[6] tablePosition = tablePosition + 6 --increase table position --copy back the actor spells --amount of indexes used to store spells for this actor local spellsSize = tonumber(combatData [tablePosition]) --[7] if (isDebugging) then print("spell size unpack:", spellsSize) end tablePosition = tablePosition + 1 local newTargetsTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData [spellIndex]) --[1] local spellDamage = tonumber(combatData [spellIndex+1]) --[2] local spellHits = tonumber(combatData [spellIndex+2]) --[3] local targetsSize = tonumber(combatData[spellIndex+3]) --[4] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+3, true) local spellObject = actorObject.spells:GetOrCreateSpell(spellId, true) --this one need some translation spellObject.total = spellDamage spellObject.counter = spellHits spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount end spellIndex = spellIndex + targetsSize + 4 end actorObject.targets = newTargetsTable tablePosition = tablePosition + spellsSize --increase table position end if (isDebugging) then print("UnPackDamage(): done.") end return tablePosition end function Details.packFunctions.PackHeal(combatObject) if (isDebugging) then print("PackHeal(): start.") end --store actorObjects to pack local actorsToPack = {} --get the player object from the combat > damage container local playerName = Details.playername local playerObject = combatObject:GetActor(DETAILS_ATTRIBUTE_HEAL, playerName) if (not playerObject) then if (isDebugging) then print("PackHeal(): return | no player object.") end return end tinsert(actorsToPack, playerObject) --get the list of pets the player own local playerPets = playerObject.pets for _, petName in ipairs(playerPets) do local petObject = combatObject:GetActor(DETAILS_ATTRIBUTE_HEAL, petName) if (petObject) then tinsert(actorsToPack, petObject) end end local playerIndex = UnitInRaid("player") if (not playerIndex) then --no player index if (isDebugging) then print("PackHeal(): return | no player index found.") end return end --get all npc enemies and sort them by their respaw id local allActors = combatObject[DETAILS_ATTRIBUTE_HEAL]._ActorTable local allEnemies = {} --this have subtables, format: {actorObject, spawnId} for i = 1, #allActors do --get the actor object local actor = allActors[i] --check if is an enemy or neutral if (actor:IsNeutralOrEnemy()) then --get the spawnId local spawnId = select(7, strsplit("-", actor.serial)) if (spawnId) then --convert hex to number spawnId = tonumber(spawnId:sub(1, 10), 16) if (spawnId) then --first index is the actorObject, the second index is the spawnId to sort enemies tinsert(allEnemies, {actor, spawnId}) end end end end --sort enemies by their spawnId table.sort(allEnemies, Details.Sort2) local allPlayerNames = {} for i = 1, 20 do local name, _, subgroup = GetRaidRosterInfo(i) if (name) then --maybe the group has less than 20 players name = Ambiguate(name, "none") if (name and subgroup <= 4) then tinsert(allPlayerNames, name) end end end table.sort(allPlayerNames, function(t1, t2) return t1 < t2 end) local playerName = UnitName("player") for i = 1, #allPlayerNames do if (playerName == allPlayerNames[i]) then playerIndex = i break end end --this is the enemy that this player has to send local enemyObjectToSend = allEnemies[playerIndex] and allEnemies[playerIndex][1] if (enemyObjectToSend) then tinsert(actorsToPack, enemyObjectToSend) end --add the actors to actor information table for _, actorObject in ipairs(actorsToPack) do --check if already has the actor information local indexToActorInfo = actorInformationIndexes[actorObject.nome] --actor name if (not indexToActorInfo) then --need to add the actor general information into the actor information table indexToActorInfo = Details.packFunctions.AddActorInformation(actorObject) end end for i = 1, #actorsToPack do --get the actor object local actor = actorsToPack[i] local indexToActorInfo = actorInformationIndexes[actor.nome] --where the information of this actor starts local currentIndex = #actorHealInfo + 1 --[1] index where is stored the this actor info like name, class, spec, etc actorHealInfo[currentIndex] = indexToActorInfo --[1] --[2 - 6] actorHealInfo [currentIndex + 1] = floor(actor.total) --[2] actorHealInfo [currentIndex + 2] = floor(actor.totalabsorb) --[3] actorHealInfo [currentIndex + 3] = floor(actor.totalover) --[4] actorHealInfo [currentIndex + 4] = floor(actor.healing_taken) --[5] actorHealInfo [currentIndex + 5] = floor(actor.totalover_without_pet) --[6] local spellContainer = actor.spells._ActorTable --reserve an index to tell the length of spells actorHealInfo [#actorHealInfo + 1] = 0 local reservedSpellSizeIndex = #actorHealInfo local totalSpellIndexes = 0 for spellId, spellInfo in pairs(spellContainer) do local spellHealingDone = spellInfo.total local spellHits = spellInfo.counter local spellTargets = spellInfo.targets actorHealInfo [#actorHealInfo + 1] = floor(spellId) actorHealInfo [#actorHealInfo + 1] = floor(spellHealingDone) actorHealInfo [#actorHealInfo + 1] = floor(spellHits) totalSpellIndexes = totalSpellIndexes + 3 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorHealInfo [#actorHealInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, healingDone in pairs(spellTargets) do actorHealInfo [#actorHealInfo + 1] = actorName actorHealInfo [#actorHealInfo + 1] = floor(healingDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorHealInfo[reservedSpellSizeIndex] = totalSpellIndexes end if (isDebugging) then print("PackHeal(): done.") end end -------------------------------------------------------------------------------------------------------------------------------- --unpack function Details.packFunctions.UnPackHeal(currentCombat, combatData, tablePosition) if (isDebugging) then print("UnPackHeal(): start.") end --get the healing container local healContainer = currentCombat[DETAILS_ATTRIBUTE_HEAL] --loop from 1 to 199, the amount of actors store is unknown --todo: it's only unpacking the first actor from the table, e.g. theres izimode and eye of corruption, after export it only shows the eye of corruption --table position does not move forward for i = 1, 199 do --actor information index in the combatData table --this index gives the position where the actor name, class, spec are stored local actorReference = tonumber(combatData[tablePosition]) --[1] local actorName, actorFlag, serialNumber, class, spec = Details.packFunctions.RetriveActorInformation(combatData, actorReference) if (isDebugging) then print("UnPackHeal(): Retrivied Data From " .. (actorReference or "nil") .. ":", actorName, actorFlag, serialNumber, class, spec) end --check if all healing actors has been processed --if there's no actor name it means it reached the end if (not actorName) then if (isDebugging) then print("UnPackHeal(): break | Heal loop has been stopped", "index:", i, "tablePosition:", tablePosition, "value:", combatData[tablePosition]) end break end --get or create the actor object local actorObject = healContainer:GetOrCreateActor(serialNumber, actorName, actorFlag, true) --set the actor class, spec and group actorObject.classe = class actorObject:SetSpecId(spec) actorObject.grupo = isActorInGroup(class, actorFlag) actorObject.flag_original = actorFlag --copy the base healing actorObject.total = tonumber(combatData[tablePosition+1]) --[2] actorObject.totalabsorb = tonumber(combatData[tablePosition+2]) --[3] actorObject.totalover = tonumber(combatData[tablePosition+3]) --[4] actorObject.healing_taken = tonumber(combatData[tablePosition+4]) --[5] actorObject.totalover_without_pet = tonumber(combatData[tablePosition+5]) --[6] tablePosition = tablePosition + 6 --copy back the actor spells --amount of indexes used to store spells for this actor local spellsSize = tonumber(combatData [tablePosition]) --[7] if (isDebugging) then print("spell size unpack:", spellsSize) end tablePosition = tablePosition + 1 local newTargetsTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData [spellIndex]) --[1] local spellHealingDone = tonumber(combatData [spellIndex+1]) --[2] local spellHits = tonumber(combatData [spellIndex+2]) --[3] local targetsSize = tonumber(combatData[spellIndex+3]) --[4] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+3, true) local spellObject = actorObject.spells:GetOrCreateSpell(spellId, true) --this one need some translation spellObject.total = spellHealingDone spellObject.counter = spellHits spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount end spellIndex = spellIndex + targetsSize + 4 end actorObject.targets = newTargetsTable tablePosition = tablePosition + spellsSize --increase table position end if (isDebugging) then print("UnPackHeal(): done.") end return tablePosition end -------------------------------------------------------------------------------------------------- --pack utility data --pack utility passes the player utility info + pets the player own --each player will also send an enemy, the enemy will be in order of raidIndex of the player function Details.packFunctions.PackUtility(combatObject) if (isDebugging) then print("PackUtility(): start.") end --store actorObjects to pack local actorsToPack = {} --get the player object from the combat > utility container local playerName = Details.playername local playerObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, playerName) if (not playerObject) then if (isDebugging) then print("PackUtility(): return | no player object.") end return end tinsert(actorsToPack, playerObject) --get the list of pets the player own local playerPets = playerObject.pets for _, petName in ipairs(playerPets) do local petObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, petName) if (petObject) then tinsert(actorsToPack, petObject) end end local playerIndex = _G.UnitInRaid("player") if (not playerIndex) then --no player index if (isDebugging) then print("PackUtility(): return | no player index found.") end return end --get all npc enemies and sort them by their respaw id local allActors = combatObject[DETAILS_ATTRIBUTE_MISC]._ActorTable local allEnemies = {} --this have subtables, format: {actorObject, spawnId} for i = 1, #allActors do --get the actor object local actor = allActors[i] --check if is an enemy or neutral if (actor:IsNeutralOrEnemy()) then --get the spawnId local spawnId = select(7, strsplit("-", actor.serial)) if (spawnId) then --convert hex to number spawnId = tonumber(spawnId:sub(1, 10), 16) if (spawnId) then --first index is the actorObject, the second index is the spawnId to sort enemies tinsert(allEnemies, {actor, spawnId}) end end end end --sort enemies by their spawnId table.sort(allEnemies, Details.Sort2) local allPlayerNames = {} for i = 1, 20 do local name, _, subgroup = GetRaidRosterInfo(i) if (name) then --maybe the group has less than 20 players name = _G.Ambiguate(name, "none") if (name and subgroup <= 4) then tinsert(allPlayerNames, name) end end end table.sort(allPlayerNames, function(t1, t2) return t1 < t2 end) local playerName = UnitName("player") for i = 1, #allPlayerNames do if (playerName == allPlayerNames[i]) then playerIndex = i break end end --this is the enemy that this player has to send local enemyObjectToSend = allEnemies[playerIndex] and allEnemies[playerIndex][1] if (enemyObjectToSend) then tinsert(actorsToPack, enemyObjectToSend) end --add the actors to actor information table for _, actorObject in ipairs(actorsToPack) do --check if already has the actor information local indexToActorInfo = actorInformationIndexes[actorObject.nome] --actor name if (not indexToActorInfo) then --need to add the actor general information into the actor information table indexToActorInfo = Details.packFunctions.AddActorInformation(actorObject) end end for i = 1, #actorsToPack do --get the actor object local actor = actorsToPack[i] local indexToActorInfo = actorInformationIndexes[actor.nome] --where the information of this actor starts local currentIndex = #actorUtilityInfo + 1 --[1] index where is stored the actor info like name, class, spec, etc actorUtilityInfo[currentIndex] = indexToActorInfo --[1] --[=[ interrupt_spells._ActorTable [spellId] = { [2139] = { ["id"] = 2139, ["interrompeu_oque"] = { [337110] = 1, }, ["targets"] = { ["Baroness Frieda"] = 1, }, ["counter"] = 1, }, } cooldowns_defensive cooldowns_defensive_targets ["cooldowns_defensive_spells"] = { ["_ActorTable"] = { [45438] = { ["id"] = 45438, ["targets"] = { ["Relune-Tichondrius"] = 1, }, ["counter"] = 1, }, }, ["tipo"] = 9, }, cc_break cc_break_oque cc_break_targets ["cc_break_spells"] = { ["_ActorTable"] = { [42223] = { ["cc_break_oque"] = { [197214] = 2, }, ["id"] = 42223, ["targets"] = { ["Castellan Niklaus"] = 1, ["Baroness Frieda"] = 1, }, ["cc_break"] = 2, ["counter"] = 0, }, }, }, ["cc_done_spells"] = { ["_ActorTable"] = { [127797] = { ["id"] = 127797, ["targets"] = { ["Castellan Niklaus"] = 1, ["Lord Stavros"] = 1, ["Baroness Frieda"] = 1, }, ["counter"] = 3, }, }, ["tipo"] = 9, }, ["dispell_spells"] = { ["_ActorTable"] = { [77130] = { ["targets"] = { ["Magicgreenie-BleedingHollow"] = 1, }, ["id"] = 77130, ["dispell_oque"] = { [337110] = 1, }, ["dispell"] = 1, ["counter"] = 0, }, }, ["tipo"] = 9, }, ress ress_targets ["ress_spells"] = { ["_ActorTable"] = { [212048] = { ["id"] = 212048, ["ress"] = 7, ["targets"] = { ["Freezerbeef-Illidan"] = 1, ["Jilkari-ThoriumBrotherhood"] = 1, ["Ditador"] = 1, ["Caller-Thrall"] = 1, ["Thebappo-Tichondrius"] = 1, ["Superskourge-Area52"] = 1, ["Rorschak-Area52"] = 1, }, ["counter"] = 0, }, }, ["tipo"] = 9, }, --]=] --cooldowns, pack player cooldowns used actorUtilityInfo [#actorUtilityInfo + 1] = "C" local cooldownContainer = actor.cooldowns_defensive_spells and actor.cooldowns_defensive_spells._ActorTable local totalSpellIndexes = 0 if (cooldownContainer) then --reserve an index to tell the length of spells actorUtilityInfo [#actorUtilityInfo + 1] = 0 local reservedSpellSizeIndex = #actorUtilityInfo for spellId, spellInfo in pairs(cooldownContainer) do local spellCounter = spellInfo.counter local spellTargets = spellInfo.targets actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellId) actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellCounter) totalSpellIndexes = totalSpellIndexes + 2 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, totalDone in pairs(spellTargets) do actorUtilityInfo [#actorUtilityInfo + 1] = actorName actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorUtilityInfo[reservedSpellSizeIndex] = totalSpellIndexes else actorUtilityInfo [#actorUtilityInfo + 1] = 0 end --interrupts, pack player interrupts actorUtilityInfo [#actorUtilityInfo + 1] = "I" local interruptsContainer = actor.interrupt_spells and actor.interrupt_spells._ActorTable local totalSpellIndexes = 0 if (interruptsContainer) then --reserve an index to tell the length of spells actorUtilityInfo [#actorUtilityInfo + 1] = 0 local reservedSpellSizeIndex = #actorUtilityInfo for spellId, spellInfo in pairs(interruptsContainer) do local spellCounter = spellInfo.counter local spellTargets = spellInfo.targets local whatGotInterrupted = spellInfo.interrompeu_oque actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellId) actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellCounter) --spellCounter is nil totalSpellIndexes = totalSpellIndexes + 2 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, totalDone in pairs(spellTargets) do actorUtilityInfo [#actorUtilityInfo + 1] = actorName actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end --build what was interrupted by the spell local interruptedSize = Details.packFunctions.CountTableEntriesValid(whatGotInterrupted) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = interruptedSize totalSpellIndexes = totalSpellIndexes + 1 for spellId, totalDone in pairs(whatGotInterrupted) do actorUtilityInfo [#actorUtilityInfo + 1] = spellId actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorUtilityInfo[reservedSpellSizeIndex] = totalSpellIndexes else actorUtilityInfo [#actorUtilityInfo + 1] = 0 end --cc break, pack player crowd control breaks actorUtilityInfo [#actorUtilityInfo + 1] = "B" local ccBreakContainer = actor.cc_break_spells and actor.cc_break_spells._ActorTable local totalSpellIndexes = 0 if (ccBreakContainer) then --reserve an index to tell the length of spells actorUtilityInfo [#actorUtilityInfo + 1] = 0 local reservedSpellSizeIndex = #actorUtilityInfo for spellId, spellInfo in pairs(ccBreakContainer) do local spellCounter = spellInfo.cc_break local spellTargets = spellInfo.targets local whatGotCCBroken = spellInfo.cc_break_oque actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellId) actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellCounter) totalSpellIndexes = totalSpellIndexes + 2 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, totalDone in pairs(spellTargets) do actorUtilityInfo [#actorUtilityInfo + 1] = actorName actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end --build what was interrupted by the spell local ccBrokenSize = Details.packFunctions.CountTableEntriesValid(whatGotCCBroken) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = ccBrokenSize totalSpellIndexes = totalSpellIndexes + 1 for spellId, totalDone in pairs(whatGotCCBroken) do actorUtilityInfo [#actorUtilityInfo + 1] = spellId actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorUtilityInfo[reservedSpellSizeIndex] = totalSpellIndexes else actorUtilityInfo [#actorUtilityInfo + 1] = 0 end --dispel, pack player dispels done actorUtilityInfo [#actorUtilityInfo + 1] = "D" local dispelsContainer = actor.dispell_spells and actor.dispell_spells._ActorTable local totalSpellIndexes = 0 if (dispelsContainer) then --reserve an index to tell the length of spells actorUtilityInfo [#actorUtilityInfo + 1] = 0 local reservedSpellSizeIndex = #actorUtilityInfo for spellId, spellInfo in pairs(dispelsContainer) do local spellTotal = spellInfo.dispell local spellTargets = spellInfo.targets local whatGotDispelled = spellInfo.dispell_oque actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellId) actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellTotal) totalSpellIndexes = totalSpellIndexes + 2 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, totalDone in pairs(spellTargets) do actorUtilityInfo [#actorUtilityInfo + 1] = actorName actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end --build what was dispelled by the spell local dispelsSize = Details.packFunctions.CountTableEntriesValid(whatGotDispelled) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = dispelsSize totalSpellIndexes = totalSpellIndexes + 1 for spellId, totalDone in pairs(whatGotDispelled) do actorUtilityInfo [#actorUtilityInfo + 1] = spellId actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorUtilityInfo[reservedSpellSizeIndex] = totalSpellIndexes else actorUtilityInfo [#actorUtilityInfo + 1] = 0 end --ress, pack player ress performed actorUtilityInfo [#actorUtilityInfo + 1] = "R" local ressContainer = actor.ress_spells and actor.ress_spells._ActorTable local totalSpellIndexes = 0 if (ressContainer) then --reserve an index to tell the length of spells actorUtilityInfo [#actorUtilityInfo + 1] = 0 local reservedSpellSizeIndex = #actorUtilityInfo for spellId, spellInfo in pairs(ressContainer) do local spellTotal = spellInfo.ress local spellTargets = spellInfo.targets actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellId) actorUtilityInfo [#actorUtilityInfo + 1] = floor(spellTotal) totalSpellIndexes = totalSpellIndexes + 2 --build targets local targetsSize = Details.packFunctions.CountTableEntriesValid(spellTargets) * 2 actorUtilityInfo [#actorUtilityInfo + 1] = targetsSize totalSpellIndexes = totalSpellIndexes + 1 for actorName, totalDone in pairs(spellTargets) do actorUtilityInfo [#actorUtilityInfo + 1] = actorName actorUtilityInfo [#actorUtilityInfo + 1] = floor(totalDone) totalSpellIndexes = totalSpellIndexes + 2 end end --amount of indexes spells are using actorUtilityInfo[reservedSpellSizeIndex] = totalSpellIndexes else actorUtilityInfo [#actorUtilityInfo + 1] = 0 end end if (isDebugging) then print("PackUtility(): done.") end end function Details.packFunctions.UnPackUtility(currentCombat, combatData, tablePosition) if (isDebugging) then print("UnPackUtility(): start.") end --get the utility container local utilityContainer = currentCombat[DETAILS_ATTRIBUTE_MISC] --loop from 1 to 199, the amount of actors store is unknown --todo: it's only unpacking the first actor from the table, e.g. theres izimode and eye of corruption, after export it only shows the eye of corruption --table position does not move forward for i = 1, 199 do --actor information index in the combatData table --this index gives the position where the actor name, class, spec are stored local actorReference = tonumber(combatData[tablePosition]) --[1] local actorName, actorFlag, serialNumber, class, spec = Details.packFunctions.RetriveActorInformation(combatData, actorReference) if (isDebugging) then print("UnPackUtility(): Retrivied Data From " .. (actorReference or "nil") .. ":", actorName, actorFlag, serialNumber, class, spec) end --check if all utility actors has been processed --if there's no actor name it means it reached the end if (not actorName) then if (isDebugging) then print("UnPackUtiliyu(): break | Utility loop has been stopped", "index:", i, "tablePosition:", tablePosition, "value:", combatData[tablePosition]) end break end --get or create the actor object local actorObject = utilityContainer:GetOrCreateActor(serialNumber, actorName, actorFlag, true) --set the actor class, spec and group actorObject.classe = class actorObject:SetSpecId(spec) actorObject.grupo = isActorInGroup(class, actorFlag) actorObject.flag_original = actorFlag --finished utility actor setup --C - cooldowns --I - interrupts --B - cc break --D - dispels --R - ress --copy back the actor cooldowns spells tablePosition = tablePosition + 1 tablePosition = tablePosition + 1 --amount of indexes used to store cooldowns spells for this actor local spellsSize = tonumber(combatData[tablePosition]) --[7] if (isDebugging) then print("cooldowns size unpack:", spellsSize) end tablePosition = tablePosition + 1 --check if there's cooldown data if (spellsSize > 0) then local newTotal = 0 local newTargetsTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData[spellIndex]) --[1] local spellTotal = tonumber(combatData[spellIndex+1]) --[2] local targetsSize = tonumber(combatData[spellIndex+2]) --[3] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+2, true) if (not actorObject.cooldowns_defensive_spells) then actorObject.cooldowns_defensive_spells = Details.container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) end local spellObject = actorObject.cooldowns_defensive_spells:GetOrCreateSpell(spellId, true) spellObject.counter = spellTotal spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount newTotal = newTotal + amount end spellIndex = spellIndex + targetsSize + 3 end actorObject.cooldowns_defensive = newTotal actorObject.cooldowns_defensive_targets = newTargetsTable tablePosition = tablePosition + spellsSize --increase table position end --copy back the actor interrupts spells --tablePosition = tablePosition + 1 local startInterrupt = combatData[tablePosition] tablePosition = tablePosition + 1 --amount of indexes used to store interrupt spells for this actor local spellsSize = tonumber(combatData[tablePosition]) --[7] if (isDebugging) then print("interrupt size unpack:", spellsSize) end tablePosition = tablePosition + 1 if (spellsSize > 0) then local newTotal = 0 local newTargetsTable = {} local newTargetWhatTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData[spellIndex]) --[1] local spellTotal = tonumber(combatData[spellIndex+1]) --[2] local targetsSize = tonumber(combatData[spellIndex+2]) --[3] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+2, true) if (not actorObject.interrupt_spells) then actorObject.interrupt_spells = Details.container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) end local spellObject = actorObject.interrupt_spells:GetOrCreateSpell(spellId, true) spellObject.counter = spellTotal spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount newTotal = newTotal + amount end --interrupt what spellIndex = spellIndex + targetsSize + 3 local interruptWhatTableSize = combatData[spellIndex] local interruptWhatTable = Details.packFunctions.UnpackTable(combatData, spellIndex, true) --table[index] is nil spellObject.interrompeu_oque = interruptWhatTable for targetName, amount in pairs(spellObject.targets) do newTargetWhatTable[targetName] = (newTargetWhatTable[targetName] or 0) + amount end spellIndex = spellIndex + interruptWhatTableSize + 1 end actorObject.interrupt = newTotal actorObject.interrupt_targets = newTargetsTable actorObject.interrompeu_oque = newTargetWhatTable tablePosition = tablePosition + spellsSize --increase table position end --copy back the actor cc break spells --tablePosition = tablePosition + 1 local startCCBreak = combatData[tablePosition] tablePosition = tablePosition + 1 --amount of indexes used to store cc break spells for this actor local spellsSize = tonumber(combatData[tablePosition]) --[7] if (isDebugging) then print("cc break size unpack:", spellsSize) end tablePosition = tablePosition + 1 if (spellsSize > 0) then local newTotal = 0 local newTargetsTable = {} local newTargetWhatTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData[spellIndex]) --[1] local spellTotal = tonumber(combatData[spellIndex+1]) --[2] local targetsSize = tonumber(combatData[spellIndex+2]) --[3] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+2, true) if (not actorObject.cc_break_spells) then actorObject.cc_break_spells = Details.container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) end local spellObject = actorObject.cc_break_spells:GetOrCreateSpell(spellId, true) spellObject.cc_break = spellTotal spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount newTotal = newTotal + amount end --cc broke what spellIndex = spellIndex + targetsSize + 3 local ccBrokeWhatTableSize = combatData[spellIndex] local ccBrokeWhatTable = Details.packFunctions.UnpackTable(combatData, spellIndex, true) spellObject.cc_break_oque = ccBrokeWhatTable for targetName, amount in pairs(spellObject.cc_break_oque) do newTargetWhatTable[targetName] = (newTargetWhatTable[targetName] or 0) + amount end spellIndex = spellIndex + ccBrokeWhatTableSize + 1 end actorObject.cc_break = newTotal actorObject.cc_break_targets = newTargetsTable actorObject.cc_break_oque = newTargetWhatTable tablePosition = tablePosition + spellsSize --increase table position end --copy back the actor dispel spells --tablePosition = tablePosition + 1 tablePosition = tablePosition + 1 --amount of indexes used to store dispel spells for this actor local spellsSize = tonumber(combatData[tablePosition]) --[7] if (isDebugging) then print("dispel size unpack:", spellsSize) end tablePosition = tablePosition + 1 if (spellsSize > 0) then local newTotal = 0 local newTargetsTable = {} local newTargetWhatTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData[spellIndex]) --[1] local spellTotal = tonumber(combatData[spellIndex+1]) --[2] local targetsSize = tonumber(combatData[spellIndex+2]) --[3] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+2, true) if (not actorObject.dispell_spells) then actorObject.dispell_spells = Details.container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) end local spellObject = actorObject.dispell_spells:GetOrCreateSpell(spellId, true) spellObject.dispell = spellTotal spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount newTotal = newTotal + amount end spellIndex = spellIndex + targetsSize + 3 --dispel what local dispelWhatTableSize = combatData[spellIndex] local dispelWhatTable = Details.packFunctions.UnpackTable(combatData, spellIndex, true) spellObject.dispell_oque = dispelWhatTable for spellId, amount in pairs(spellObject.dispell_oque) do newTargetWhatTable[spellId] = (newTargetWhatTable[spellId] or 0) + amount end spellIndex = spellIndex + dispelWhatTableSize + 1 end actorObject.dispell = newTotal actorObject.dispell_targets = newTargetsTable actorObject.dispell_oque = newTargetWhatTable tablePosition = tablePosition + spellsSize --increase table position end --ress --ress_targets --ress_spells --copy back the actor ress spells --tablePosition = tablePosition + 1 tablePosition = tablePosition + 1 --amount of indexes used to store ress spells for this actor local spellsSize = tonumber(combatData[tablePosition]) --[7] if (isDebugging) then print("ress size unpack:", spellsSize) end tablePosition = tablePosition + 1 if (spellsSize > 0) then local newTotal = 0 local newTargetsTable = {} local spellIndex = tablePosition while(spellIndex < tablePosition + spellsSize) do local spellId = tonumber(combatData[spellIndex]) --[1] local spellTotal = tonumber(combatData[spellIndex+1]) --[2] local targetsSize = tonumber(combatData[spellIndex+2]) --[3] local targetTable = Details.packFunctions.UnpackTable(combatData, spellIndex+2, true) if (not actorObject.ress_spells) then actorObject.ress_spells = Details.container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) end local spellObject = actorObject.ress_spells:GetOrCreateSpell(spellId, true) spellObject.ress = spellTotal spellObject.targets = targetTable for targetName, amount in pairs(spellObject.targets) do newTargetsTable[targetName] = (newTargetsTable[targetName] or 0) + amount newTotal = newTotal + amount end spellIndex = spellIndex + targetsSize + 3 end actorObject.ress = newTotal actorObject.ress_targets = newTargetsTable tablePosition = tablePosition + spellsSize --increase table position end end if (isDebugging) then print("UnPackUtility(): done.") end return tablePosition end --this function does the same as the function above but does not create a new combat, it just add new information function Details.packFunctions.DeployPackedCombatData(packedCombatData) if (isDebugging) then print("DeployPackedCombatData(): start.") end local LibDeflate = _G.LibStub:GetLibrary("LibDeflate") local dataCompressed = LibDeflate:DecodeForWoWAddonChannel(packedCombatData) local combatDataString = LibDeflate:DecompressDeflate(dataCompressed) if (isDebugging) then print(combatDataString) end local function count(text, pattern) return select(2, text:gsub(pattern, "")) end local combatData = {} local amountOfIndexes = count(combatDataString, ",") + 1 while (amountOfIndexes > 0) do local splitPart = {strsplit(",", combatDataString, 4000)} if (#splitPart == 4000 and amountOfIndexes > 4000) then for i = 1, 3999 do combatData[#combatData+1] = splitPart[i] end --get get part that couldn't be read this loop combatDataString = splitPart[4000] amountOfIndexes = amountOfIndexes - 3999 else for i = 1, #splitPart do combatData[#combatData+1] = splitPart[i] end amountOfIndexes = amountOfIndexes - #splitPart end end local flags = tonumber(combatData[INDEX_EXPORT_FLAG]) local tablePosition if (bit.band(flags, 0x10) ~= 0) then tablePosition = 2 TOTAL_INDEXES_FOR_COMBAT_INFORMATION = 0 --there's no combat info, data starts after the dataFlag on position [1] else tablePosition = TOTAL_INDEXES_FOR_COMBAT_INFORMATION + 1 end --get the current combat local currentCombat = Details:GetCurrentCombat() --check if this export has included damage info if (bit.band(flags, 0x1) ~= 0) then --find the index where the damage information start for i = tablePosition, #combatData do if (combatData[i] == "!D") then tablePosition = i + 1 break end end if (isDebugging) then print("DeployPackedCombatData(): data has damage info, Damage Index:", tablePosition) end --unpack damage tablePosition = Details.packFunctions.UnPackDamage(currentCombat, combatData, tablePosition) end if (bit.band(flags, 0x2) ~= 0) then --find the index where the heal information start for i = tablePosition, #combatData do if (combatData[i] == "!H") then tablePosition = i + 1 break end end if (isDebugging) then print("DeployPackedCombatData(): data has healing info, Heal Index:", tablePosition) end --unpack heal Details.packFunctions.UnPackHeal(currentCombat, combatData, tablePosition) end if (bit.band(flags, 0x8) ~= 0) then --find the index where the utility information start for i = tablePosition, #combatData do if (combatData[i] == "!U") then tablePosition = i + 1 break end end if (isDebugging) then print("DeployPackedCombatData(): data has utility info, Utility Index:", tablePosition) end --unpack utility Details.packFunctions.UnPackUtility(currentCombat, combatData, tablePosition) end if (bit.band(flags, 0x10) == 0) then --set the start and end of combat time and date currentCombat:SetStartTime(combatData[INDEX_COMBAT_START_TIME]) currentCombat:SetEndTime(combatData[INDEX_COMBAT_END_TIME]) currentCombat:SetDate(combatData[INDEX_COMBAT_START_DATE], combatData[INDEX_COMBAT_END_DATE]) currentCombat.enemy = combatData[INDEX_COMBAT_NAME] end --refresh container currentCombat[DETAILS_ATTRIBUTE_DAMAGE]:Remap() currentCombat[DETAILS_ATTRIBUTE_HEAL]:Remap() --refresh damage taken do local damageContainer = currentCombat[DETAILS_ATTRIBUTE_DAMAGE] local allActors = damageContainer._ActorTable for i = 1, #allActors do --reset damage taken table local actor = allActors[i] actor.damage_taken = 0 actor.damage_from = {} end for i = 1, #allActors do local actor = allActors[i] for targetName, amount in pairs(actor.targets) do local actorIndex = damageContainer._NameIndexTable[targetName] if (actorIndex) then local targetActor = allActors[actorIndex] if (targetActor) then targetActor.damage_taken = targetActor.damage_taken + amount targetActor.damage_from[actor.nome] = (targetActor.damage_from[actor.nome] or 0) + amount end end end end end --refresh healing taken do local healingContainer = currentCombat[DETAILS_ATTRIBUTE_HEAL] local allActors = healingContainer._ActorTable for i = 1, #allActors do --reset healing taken table local actor = allActors[i] actor.healing_taken = 0 actor.healing_from = {} end for i = 1, #allActors do local actor = allActors[i] for targetName, amount in pairs(actor.targets) do local actorIndex = healingContainer._NameIndexTable[targetName] if (actorIndex) then local targetActor = allActors[actorIndex] if (targetActor) then targetActor.healing_taken = targetActor.healing_taken + amount targetActor.healing_from[actor.nome] = (targetActor.healing_from[actor.nome] or 0) + amount end end end end end --refresh windows currentCombat[DETAILS_ATTRIBUTE_DAMAGE].need_refresh = true currentCombat[DETAILS_ATTRIBUTE_HEAL].need_refresh = true end --get the amount of entries of a hash table function Details.packFunctions.CountTableEntries(hasTable) local amount = 0 for _ in pairs(hasTable) do amount = amount + 1 end return amount end --get the amount of entries and check for validation function Details.packFunctions.CountTableEntriesValid(hasTable) local amount = 0 for actorName, _ in pairs(hasTable) do --if (actorInformationIndexes[actorName]) then amount = amount + 1 --end end return amount end --stract some indexes of a table local selectIndexes = function(table, startIndex, amountIndexes) local values = {} for i = startIndex, amountIndexes do values[#values+1] = tonumber(table[i]) or 0 end return unpack(values) end function Details.packFunctions.UnpackTable(table, index, isPair, valueAsTable, amountOfValues) local result = {} local reservedIndexes = tonumber(table[index]) local indexStart = index+1 local indexEnd = reservedIndexes+index if (isPair) then amountOfValues = amountOfValues or 2 for i = indexStart, indexStart + reservedIndexes - 1, amountOfValues do if (valueAsTable) then local key = tonumber(table[i]) result[key] = {selectIndexes(table, i+1, amountOfValues-1)} else local key = table[i] local value = tonumber(table[i+1]) result[key] = value end end else for i = indexStart, indexEnd do local value = tonumber(table[i]) result[#result+1] = value end end return result end