From 85f033d6801bfbe3e33305dac1a4cb5ed789e3b4 Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Tue, 10 May 2022 15:18:59 -0300 Subject: [PATCH] Open Raid Lib: added cooldown added and removed events; added Keystone information --- Libs/LibOpenRaid/LibOpenRaid.lua | 257 ++++++++++++++++++++++++++++--- Libs/LibOpenRaid/docs.txt | 31 ++++ 2 files changed, 265 insertions(+), 23 deletions(-) diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index 4a834866..42281b96 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -15,6 +15,7 @@ Code Rules: - Public callbacks are callbacks registered by an external addon. Change Log: + - finished keystone info, see docs - added interrupts to cooldown tracker, new filter: "interrupt" - after encounter_end cooldowns now check for cooldowns reset. - each module now controls what to do with regen_enabled. @@ -23,13 +24,12 @@ Change Log: - major function and variables rename. - implemented pvp talents. - player information is always available even when not in a group. + - added cooldown check to se which cooldown has removed or added into the list. + - added two new callbacks: "CooldownAdded" and "CooldownRemoved", see documents. TODO: - - (finished but not active atm) need to finish the CheckForSpellsAdeedOrRemoved(), need to send the comm, need to create the local callbacks - - (finished but not active atm) create comm to add or remove a cooldown from an unit - make talents changes also send only cooldowns added or changed - add into gear info how many tier set parts the player has - - keystone info (portion of the logic is implemented, need to share the information) - raid lockouts normal-heroic-mythic - soulbind character (covenant choise) - probably not used in 10.0 @@ -45,7 +45,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE) then end local major = "LibOpenRaid-1.0" -local CONST_LIB_VERSION = 34 +local CONST_LIB_VERSION = 35 LIB_OPEN_RAID_CAN_LOAD = false --declae the library within the LibStub @@ -82,6 +82,13 @@ LIB_OPEN_RAID_CAN_LOAD = false local CONST_COMM_PLAYERINFO_TALENTS_PREFIX = "T" local CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX = "V" + local CONST_COMM_KEYSTONE_DATA_PREFIX = "K" + local CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX = "J" + + local CONST_COMM_SENDTO_PARTY = "0x1" + local CONST_COMM_SENDTO_RAID = "0x2" + local CONST_COMM_SENDTO_GUILD = "0x4" + local CONST_ONE_SECOND = 1.0 local CONST_TWO_SECONDS = 2.0 local CONST_THREE_SECONDS = 3.0 @@ -123,6 +130,22 @@ LIB_OPEN_RAID_CAN_LOAD = false end end + local checkClientVersion = function(...) + for i = 1, select("#", ...) do + local clientVersion = select(i, ...) + + if (clientVersion == "retail" and WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) then --retail + return true + + elseif (clientVersion == "classic_era" and WOW_PROJECT_ID == WOW_PROJECT_CLASSIC) then --classic era (vanila) + return true + + elseif (clientVersion == "bcc" and WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC) then --the burning crusade classic + return true + end + end + end + -------------------------------------------------------------------------------------------------------------------------------- --> ~comms openRaidLib.commHandler = {} @@ -140,7 +163,7 @@ LIB_OPEN_RAID_CAN_LOAD = false --don't receive comms from the player it self local playerName = UnitName("player") if (playerName == sender) then - return + --return end local data = text @@ -193,6 +216,8 @@ LIB_OPEN_RAID_CAN_LOAD = false [CONST_COMM_PLAYERINFO_PREFIX] = {}, --info about the player [CONST_COMM_PLAYERINFO_TALENTS_PREFIX] = {}, --talents info [CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX] = {}, --pvp talents info + [CONST_COMM_KEYSTONE_DATA_PREFIX] = {}, --received keystone data + [CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX] = {}, --received a request to send keystone data } function openRaidLib.commHandler.RegisterComm(prefix, func) @@ -200,17 +225,41 @@ LIB_OPEN_RAID_CAN_LOAD = false tinsert(openRaidLib.commHandler.commCallback[prefix], func) end - function openRaidLib.commHandler.SendCommData(data) + --@flags + --0x1: to party + --0x2: to raid + --0x4: to guild + function openRaidLib.commHandler.SendCommData(data, flags) local LibDeflate = LibStub:GetLibrary("LibDeflate") local dataCompressed = LibDeflate:CompressDeflate(data, {level = 9}) local dataEncoded = LibDeflate:EncodeForWoWAddonChannel(dataCompressed) - if (IsInGroup() and not IsInRaid()) then --in party only - C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "PARTY") + if (flags) then + if (bit.band(flags, CONST_COMM_SENDTO_PARTY)) then --send to party + if (IsInGroup() and not IsInRaid()) then + C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "PARTY") + end + end - elseif (IsInRaid()) then - C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInRaid(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "RAID") - end + if (bit.band(flags, CONST_COMM_SENDTO_RAID)) then --send to raid + if (IsInRaid()) then + C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInRaid(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "RAID") + end + end + + if (bit.band(flags, CONST_COMM_SENDTO_GUILD)) then --send to guild + if (IsInGuild()) then + C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, "GUILD") + end + end + else + if (IsInGroup() and not IsInRaid()) then --in party only + C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "PARTY") + + elseif (IsInRaid()) then + C_ChatInfo.SendAddonMessage(CONST_COMM_PREFIX, dataEncoded, IsInRaid(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "RAID") + end + end end @@ -311,6 +360,7 @@ LIB_OPEN_RAID_CAN_LOAD = false "UnitInfoWipe", "TalentUpdate", "PvPTalentUpdate", + "KeystoneUpdate", } --save build the table to avoid lose registered events on older versions @@ -407,6 +457,7 @@ LIB_OPEN_RAID_CAN_LOAD = false ["raidEncounterEnd"] = {}, ["mythicDungeonStart"] = {}, ["playerPetChange"] = {}, + ["mythicDungeonEnd"] = {}, } openRaidLib.internalCallback.RegisterCallback = function(event, func) @@ -586,7 +637,11 @@ LIB_OPEN_RAID_CAN_LOAD = false eventFrame:UnregisterEvent("UNIT_FLAGS") openRaidLib.eventFunctions["UNIT_PET"]("player") end - end + end, + + ["CHALLENGE_MODE_COMPLETED"] = function() + openRaidLib.internalCallback.TriggerEvent("mythicDungeonEnd") + end, } openRaidLib.eventFunctions = eventFunctions @@ -598,18 +653,20 @@ LIB_OPEN_RAID_CAN_LOAD = false eventFrame:RegisterEvent("UPDATE_INVENTORY_DURABILITY") eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") eventFrame:RegisterEvent("UNIT_PET") + eventFrame:RegisterEvent("PLAYER_DEAD") + eventFrame:RegisterEvent("PLAYER_ALIVE") + eventFrame:RegisterEvent("PLAYER_UNGHOST") - --eventFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") - if (not isTimewalkWoW()) then + if (checkClientVersion("retail")) then eventFrame:RegisterEvent("PLAYER_TALENT_UPDATE") eventFrame:RegisterEvent("PLAYER_PVP_TALENT_UPDATE") eventFrame:RegisterEvent("ENCOUNTER_END") eventFrame:RegisterEvent("CHALLENGE_MODE_START") + eventFrame:RegisterEvent("CHALLENGE_MODE_COMPLETED") + --eventFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") end - eventFrame:RegisterEvent("PLAYER_DEAD") - eventFrame:RegisterEvent("PLAYER_ALIVE") - eventFrame:RegisterEvent("PLAYER_UNGHOST") + eventFrame:SetScript("OnEvent", function(self, event, ...) eventFunctions[event](...) @@ -1596,8 +1653,7 @@ end end function openRaidLib.CooldownManager.OnPlayerPetChanged() - --disabled atm - --openRaidLib.CooldownManager.CheckCooldownChanges() + openRaidLib.CooldownManager.CheckCooldownChanges() end openRaidLib.internalCallback.RegisterCallback("onLeaveGroup", openRaidLib.CooldownManager.OnPlayerLeaveGroup) @@ -1863,6 +1919,7 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, openRai -------------------------------------------------------------------------------------------------------------------------------- --> ~keystones + --public callback does not check if the keystone has changed from the previous callback --> API calls --return a table containing all information of units @@ -1877,6 +1934,39 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, openRai return openRaidLib.KeystoneInfoManager.GetKeystoneInfo(unitName) end + function openRaidLib.RequestKeystoneDataFromGuild() + if (IsInGuild()) then + local dataToSend = CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX + openRaidLib.commHandler.SendCommData(dataToSend, 0x4) + diagnosticComm("RequestKeystoneDataFromGuild| " .. dataToSend) --debug + return true + else + return false + end + end + + function openRaidLib.RequestKeystoneDataFromParty() + if (IsInGroup() and not IsInRaid()) then + local dataToSend = CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX + openRaidLib.commHandler.SendCommData(dataToSend, 0x1) + diagnosticComm("RequestKeystoneDataFromParty| " .. dataToSend) --debug + return true + else + return false + end + end + + function openRaidLib.RequestKeystoneDataFromRaid() + if (IsInRaid()) then + local dataToSend = CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX + openRaidLib.commHandler.SendCommData(dataToSend, 0x2) + diagnosticComm("RequestKeystoneDataFromRaid| " .. dataToSend) --debug + return true + else + return false + end + end + --> manager constructor openRaidLib.KeystoneInfoManager = { --structure: @@ -1890,10 +1980,10 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, openRai challengeMapID = 0, } - local updateKeystoneInfo = function(keystoneInfo) - keystoneInfo.level = C_MythicPlus.GetOwnedKeystoneLevel() or 0 - keystoneInfo.mapID = C_MythicPlus.GetOwnedKeystoneMapID() or 0 - keystoneInfo.challengeMapID = C_MythicPlus.GetOwnedKeystoneChallengeMapID() or 0 + local updateKeystoneInfo = function(keystoneInfo, level, mapID, challengeMapID) + keystoneInfo.level = level or C_MythicPlus.GetOwnedKeystoneLevel() or 0 + keystoneInfo.mapID = mapID or C_MythicPlus.GetOwnedKeystoneMapID() or 0 + keystoneInfo.challengeMapID = challengeMapID or C_MythicPlus.GetOwnedKeystoneChallengeMapID() or 0 end function openRaidLib.KeystoneInfoManager.GetAllKeystonesInfo() @@ -1913,6 +2003,127 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, openRai return keystoneInfo end + local getKeystoneInfoToComm = function() + local playerName = UnitName("player") + local keystoneInfo = openRaidLib.KeystoneInfoManager.GetKeystoneInfo(playerName, true) + local dataToSend = CONST_COMM_KEYSTONE_DATA_PREFIX .. "," .. keystoneInfo.level .. "," .. keystoneInfo.mapID .. "," .. keystoneInfo.challengeMapID + return dataToSend + end + + function openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty() + local dataToSend = getKeystoneInfoToComm() + openRaidLib.commHandler.SendCommData(dataToSend, CONST_COMM_SENDTO_PARTY) + diagnosticComm("SendPlayerKeystoneInfoToParty| " .. dataToSend) --debug + end + + function openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToGuild() + local dataToSend = getKeystoneInfoToComm() + openRaidLib.commHandler.SendCommData(dataToSend, CONST_COMM_SENDTO_GUILD) + diagnosticComm("SendPlayerKeystoneInfoToGuild| " .. dataToSend) --debug + end + + function openRaidLib.KeystoneInfoManager.OnReceiveRequestData() + if (not checkClientVersion("retail")) then + return + end + + --update the information about the key stone the player has + openRaidLib.KeystoneInfoManager.GetKeystoneInfo(UnitName("player"), true) + + if (IsInGroup() and not IsInRaid()) then + openRaidLib.Schedules.NewUniqueTimer(1 + math.random(1, 3), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") + end + + if (IsInGuild()) then + openRaidLib.Schedules.NewUniqueTimer(1 + math.random(1, 3), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToGuild, "KeystoneInfoManager", "sendKeystoneInfoToGuild_Schedule") + end + end + openRaidLib.commHandler.RegisterComm(CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX, openRaidLib.KeystoneInfoManager.OnReceiveRequestData) + + function openRaidLib.KeystoneInfoManager.OnReceiveKeystoneData(data, unitName) + if (not checkClientVersion("retail")) then + return + end + + local level = tonumber(data[1]) + local mapID = tonumber(data[2]) + local challengeMapID = tonumber(data[3]) + + if (level and mapID and challengeMapID) then + local keystoneInfo = openRaidLib.KeystoneInfoManager.GetKeystoneInfo(unitName, true) + updateKeystoneInfo(keystoneInfo, level, mapID, challengeMapID) + + --trigger public callback + openRaidLib.publicCallback.TriggerCallback("KeystoneUpdate", openRaidLib.GetUnitID(unitName), keystoneInfo, openRaidLib.KeystoneInfoManager.KeystoneData) + end + end + openRaidLib.commHandler.RegisterComm(CONST_COMM_KEYSTONE_DATA_PREFIX, openRaidLib.KeystoneInfoManager.OnReceiveKeystoneData) + + --on entering a group, send keystone information for the party + function openRaidLib.KeystoneInfoManager.OnPlayerEnterGroup() + --keystones are only available on retail + if (not checkClientVersion("retail")) then + return + end + + if (IsInGroup() and not IsInRaid()) then + --update the information about the key stone the player has + openRaidLib.KeystoneInfoManager.GetKeystoneInfo(UnitName("player"), true) + --send to the group which kstone the player has + openRaidLib.Schedules.NewUniqueTimer(1 + math.random(1, 3), openRaidLib.KeystoneInfoManager.SendPlayerKeystoneInfoToParty, "KeystoneInfoManager", "sendKeystoneInfoToParty_Schedule") + end + end + + function openRaidLib.KeystoneInfoManager.OnPlayerEnterWorld() + --keystones are only available on retail + if (not checkClientVersion("retail")) then + return + end + --hack: on received data send data to party and guild + openRaidLib.KeystoneInfoManager.OnReceiveRequestData() + + --trigger public callback + local keystoneInfo = openRaidLib.KeystoneInfoManager.GetKeystoneInfo(UnitName("player"), true) + openRaidLib.publicCallback.TriggerCallback("KeystoneUpdate", "player", keystoneInfo, openRaidLib.KeystoneInfoManager.KeystoneData) + end + + function openRaidLib.KeystoneInfoManager.OnMythicDungeonFinished() + --keystones are only available on retail + if (not checkClientVersion("retail")) then + return + end + --hack: on received data send data to party and guild + openRaidLib.KeystoneInfoManager.OnReceiveRequestData() + + --trigger public callback + local keystoneInfo = openRaidLib.KeystoneInfoManager.GetKeystoneInfo(UnitName("player"), true) + openRaidLib.publicCallback.TriggerCallback("KeystoneUpdate", "player", keystoneInfo, openRaidLib.KeystoneInfoManager.KeystoneData) + end + + openRaidLib.internalCallback.RegisterCallback("onEnterWorld", openRaidLib.KeystoneInfoManager.OnPlayerEnterWorld) + openRaidLib.internalCallback.RegisterCallback("onEnterGroup", openRaidLib.KeystoneInfoManager.OnPlayerEnterGroup) + openRaidLib.internalCallback.RegisterCallback("mythicDungeonEnd", openRaidLib.KeystoneInfoManager.OnMythicDungeonFinished) + + +--DEBUG TEST +--[=[ +local ff = {} +function ff.OnKSUpdate(unitId, keystoneInfo, allKeystonesInfo) + print(unitId, keystoneInfo, allKeystonesInfo) + print(keystoneInfo.level, keystoneInfo.mapID, keystoneInfo.challengeMapID) +end +openRaidLib.RegisterCallback(ff, "KeystoneUpdate", "OnKSUpdate") + +C_Timer.After(7, function() + openRaidLib.GetAllKeystonesInfo() + print("> ", openRaidLib.GetKeystoneInfo("player")) + + openRaidLib.RequestKeystoneDataFromGuild() + openRaidLib.RequestKeystoneDataFromParty() + openRaidLib.RequestKeystoneDataFromRaid() +end) +--]=] + -------------------------------------------------------------------------------------------------------------------------------- --> data diff --git a/Libs/LibOpenRaid/docs.txt b/Libs/LibOpenRaid/docs.txt index aafec370..51b17cbe 100644 --- a/Libs/LibOpenRaid/docs.txt +++ b/Libs/LibOpenRaid/docs.txt @@ -93,6 +93,37 @@ unitInfo = { } +KEYSTONE +--send and receive mythic+ keystone information and works only in retail +--the event "KeystoneUpdate" is triggered on receive keystone info from another player + +local allKeystoneInfo = openRaidLib.GetAllKeystonesInfo() +allKeystoneInfo = { + ["unitName1"] = keystoneInfo, + ["unitName2"] = keystoneInfo, + ["unitName3"] = keystoneInfo, +} + +local keystoneInfo = openRaidLib.GetKeystoneInfo(unitId) +keystoneInfo = { + .level = number, + .mapID = number, + .challengeMapID = number, +} + +--request all online players in the guild to send their keystone information +--this call fails if the player isn't in a guild +local requestSent = openRaidLib.RequestKeystoneDataFromGuild() + +--request to players in your party to send their keystone information +--this call fails if the player is in raid +local requestSent = openRaidLib.RequestKeystoneDataFromParty() + +--request to players in your raid to send their keystone information +--this call fails if not in a raid group +local requestSent = openRaidLib.RequestKeystoneDataFromRaid() + + Callbacks: ===================================================================================================================================