if WOW_PROJECT_ID == WOW_PROJECT_CLASSIC then
local L = BigWigsAPI : GetLocale ( " BigWigs " )
print ( L.classicWarning1 )
print ( L.classicWarning2 )
BasicMessageDialog.Text : SetText ( L.classicWarning1 )
BasicMessageDialog : Show ( )
return
end
local L = BigWigsAPI : GetLocale ( " BigWigs " )
local mod , public = { } , { }
local bwFrame = CreateFrame ( " Frame " )
local ldb = LibStub ( " LibDataBroker-1.1 " )
local ldbi = LibStub ( " LibDBIcon-1.0 " )
local strfind = string.find
-----------------------------------------------------------------------
-- Generate our version variables
--
local BIGWIGS_VERSION = 227
local BIGWIGS_RELEASE_STRING , BIGWIGS_VERSION_STRING = " " , " "
local versionQueryString , versionResponseString = " Q^%d^%s^%d^%s " , " V^%d^%s^%d^%s "
local customGuildName = false
local BIGWIGS_GUILD_VERSION = 0
local guildWarnMessage = " "
do
-- START: MAGIC PACKAGER VOODOO VERSION STUFF
local _ , tbl = ...
local REPO = " REPO "
local ALPHA = " ALPHA "
local RELEASE = " RELEASE "
local releaseType = RELEASE
local myGitHash = " 5438284 " -- The ZIP packager will replace this with the Git hash.
local releaseString = " "
--[=[@alpha@
-- The following code will only be present in alpha ZIPs.
releaseType = ALPHA
--@end-alpha@]=]
-- If we find "@" then we're running from Git directly.
if strfind ( myGitHash , " @ " , nil , true ) then
myGitHash = " repo "
releaseType = REPO
end
if releaseType == REPO then
releaseString = L.sourceCheckout : format ( BIGWIGS_VERSION )
elseif releaseType == RELEASE then
releaseString = L.officialRelease : format ( BIGWIGS_VERSION , myGitHash )
elseif releaseType == ALPHA then
releaseString = L.alphaRelease : format ( BIGWIGS_VERSION , myGitHash )
end
-- Format is "V:version^hash^guildVersion^guildName"
local isVersionNumber = type ( tbl.guildVersion ) == " number "
local isGuildString = type ( tbl.guildName ) == " string "
local isGuildWarnString = type ( tbl.guildWarn ) == " string "
if isVersionNumber and isGuildString and isGuildWarnString and tbl.guildVersion > 0 and tbl.guildName : gsub ( " " , " " ) ~= " " then
customGuildName = tbl.guildName
BIGWIGS_GUILD_VERSION = tbl.guildVersion
guildWarnMessage = tbl.guildWarn
releaseString = L.guildRelease : format ( BIGWIGS_GUILD_VERSION , BIGWIGS_VERSION )
versionQueryString = versionQueryString : format ( BIGWIGS_VERSION , myGitHash , tbl.guildVersion , tbl.guildName )
versionResponseString = versionResponseString : format ( BIGWIGS_VERSION , myGitHash , tbl.guildVersion , tbl.guildName )
BIGWIGS_VERSION_STRING = ( " %d/%d-%s " ) : format ( BIGWIGS_GUILD_VERSION , BIGWIGS_VERSION , myGitHash )
else
versionQueryString = versionQueryString : format ( BIGWIGS_VERSION , myGitHash , 0 , " " )
versionResponseString = versionResponseString : format ( BIGWIGS_VERSION , myGitHash , 0 , " " )
BIGWIGS_VERSION_STRING = ( " %d-%s " ) : format ( BIGWIGS_VERSION , myGitHash )
end
BIGWIGS_RELEASE_STRING = releaseString
-- END: MAGIC PACKAGER VOODOO VERSION STUFF
end
-----------------------------------------------------------------------
-- Locals
--
local tooltipFunctions = { }
local next , tonumber , type , strsplit = next , tonumber , type , strsplit
local SendAddonMessage , Ambiguate , CTimerAfter , CTimerNewTicker = C_ChatInfo.SendAddonMessage , Ambiguate , C_Timer.After , C_Timer.NewTicker
local GetInstanceInfo , GetBestMapForUnit , GetMapInfo = GetInstanceInfo , C_Map.GetBestMapForUnit , C_Map.GetMapInfo
local UnitName , UnitGUID = UnitName , UnitGUID
local debugstack , print = debugstack , print
-- Try to grab unhooked copies of critical funcs (hooked by some crappy addons)
public.GetBestMapForUnit = GetBestMapForUnit
public.GetMapInfo = GetMapInfo
public.GetInstanceInfo = GetInstanceInfo
public.SendAddonMessage = SendAddonMessage
public.SendChatMessage = SendChatMessage
public.CTimerAfter = CTimerAfter
public.CTimerNewTicker = CTimerNewTicker
public.UnitName = UnitName
public.UnitGUID = UnitGUID
public.SetRaidTarget = SetRaidTarget
public.UnitHealth = UnitHealth
public.UnitHealthMax = UnitHealthMax
public.UnitDetailedThreatSituation = UnitDetailedThreatSituation
-- Version
local usersHash = { }
local usersVersion = { }
local usersGuildVersion = { }
local usersGuildName = { }
local usersDBM = { }
local highestFoundVersion = BIGWIGS_VERSION
local highestFoundGuildVersion = BIGWIGS_GUILD_VERSION
-- Loading
local isMouseDown = false
local loadOnCoreEnabled = { } -- BigWigs modulepacks that should load when a hostile zone is entered or the core is manually enabled, this would be the default plugins Bars, Messages etc
local loadOnZone = { } -- BigWigs modulepack that should load on a specific zone
local loadOnSlash = { } -- BigWigs modulepacks that can load from a chat command
local menus = { } -- contains the menus for BigWigs, once the core is loaded they will get injected
local enableZones = { } -- contains the zones in which BigWigs will enable
local disabledZones -- contains the zones in which BigWigs will enable, but the user has disabled the addon
local worldBosses = { } -- contains the list of world bosses per zone that should enable the core
local fakeZones = { -- Fake zones used as GUI menus
[ - 101 ] = true , -- Outland
[ - 424 ] = true , -- Pandaria
[ - 572 ] = true , -- Draenor
[ - 619 ] = true , -- Broken Isles
[ - 947 ] = true , -- Azeroth
[ - 1647 ] = true , -- Shadowlands
}
do
local c = " BigWigs_Classic "
local bc = " BigWigs_BurningCrusade "
local wotlk = " BigWigs_WrathOfTheLichKing "
local cata = " BigWigs_Cataclysm "
local mop = " BigWigs_MistsOfPandaria "
local wod = " BigWigs_WarlordsOfDraenor "
local l = " BigWigs_Legion "
local bfa = " BigWigs_BattleForAzeroth "
local s = " BigWigs_Shadowlands "
local lw_c = " LittleWigs_Classic "
local lw_bc = " LittleWigs_BurningCrusade "
local lw_wotlk = " LittleWigs_WrathOfTheLichKing "
local lw_cata = " LittleWigs_Cataclysm "
local lw_mop = " LittleWigs_MistsOfPandaria "
local lw_wod = " LittleWigs_WarlordsOfDraenor "
local lw_l = " LittleWigs_Legion "
local lw_bfa = " LittleWigs_BattleForAzeroth "
local lw_s = " LittleWigs_Shadowlands "
public.zoneTbl = {
--[[ BigWigs: Classic ]] --
[ 409 ] = c , -- Molten Core
[ 469 ] = c , -- Blackwing Lair
[ 509 ] = c , -- Ruins of Ahn'Qiraj
[ 531 ] = c , -- Ahn'Qiraj Temple
--[[ BigWigs: The Burning Crusade ]] --
[ - 101 ] = bc , -- Outland (Fake Menu)
[ 565 ] = bc , -- Gruul's Lair
[ 532 ] = bc , -- Karazhan
[ 548 ] = bc , -- Coilfang: Serpentshrine Cavern
[ 550 ] = bc , -- Tempest Keep
[ 544 ] = bc , -- Magtheridon's Lair
[ 534 ] = bc , -- The Battle for Mount Hyjal
[ 564 ] = bc , -- Black Temple
[ 580 ] = bc , -- The Sunwell
--[[ BigWigs: Wrath of the Lich King ]] --
[ 533 ] = wotlk , -- Naxxramas
[ 616 ] = wotlk , -- The Eye of Eternity
[ 603 ] = wotlk , -- Ulduar
[ 624 ] = wotlk , -- Vault of Archavon
[ 649 ] = wotlk , -- Trial of the Crusader
[ 724 ] = wotlk , -- The Ruby Sanctum
[ 631 ] = wotlk , -- Icecrown Citadel
[ 615 ] = wotlk , -- The Obsidian Sanctum
[ 249 ] = wotlk , -- Onyxia's Lair
--[[ BigWigs: Cataclysm ]] --
[ 671 ] = cata , -- The Bastion of Twilight
[ 669 ] = cata , -- Blackwing Descent
[ 754 ] = cata , -- Throne of the Four Winds
[ 757 ] = cata , -- Baradin Hold
[ 720 ] = cata , -- Firelands
[ 967 ] = cata , -- Dragon Soul
--[[ BigWigs: Mists of Pandaria ]] --
[ - 424 ] = mop , -- Pandaria (Fake Menu)
[ 1009 ] = mop , -- Heart of Fear
[ 996 ] = mop , -- Terrace of Endless Spring
[ 1008 ] = mop , -- Mogu'shan Vaults
[ 1098 ] = mop , -- Throne of Thunder
[ 1136 ] = mop , -- Siege of Orgrimmar
--[[ BigWigs: Warlords of Draenor ]] --
[ - 572 ] = wod , -- Draenor (Fake Menu)
[ 1228 ] = wod , -- Highmaul
[ 1205 ] = wod , -- Blackrock Foundry
[ 1448 ] = wod , -- Hellfire Citadel
--[[ BigWigs: Legion ]] --
[ - 619 ] = l , -- Broken Isles (Fake Menu)
[ 1520 ] = l , -- The Emerald Nightmare
[ 1648 ] = l , -- Trial of Valor
[ 1530 ] = l , -- The Nighthold
[ 1676 ] = l , -- Tomb of Sargeras
[ 1712 ] = l , -- Antorus, the Burning Throne
[ 1779 ] = l , -- Invasion Points
--[[ BigWigs: Battle for Azeroth ]] --
[ - 947 ] = bfa , -- Azeroth (Fake Menu)
[ 1861 ] = bfa , -- Uldir
[ 2070 ] = bfa , -- Battle Of Dazar'alor
[ 2096 ] = bfa , -- Crucible of Storms
[ 2164 ] = bfa , -- The Eternal Palace
[ 2217 ] = bfa , -- Ny'alotha, the Waking City
--[[ BigWigs: Shadowlands ]] --
[ - 1647 ] = s , -- Shadowlands (Fake Menu)
[ 2296 ] = s , -- Castle Nathria
[ 2450 ] = s , -- Sanctum of Domination
--[[ LittleWigs: Classic ]] --
[ 33 ] = lw_c , -- Shadowfang Keep
[ 36 ] = lw_c , -- Deadmines
--[[ LittleWigs: The Burning Crusade ]] --
[ 540 ] = lw_bc , -- Hellfire Citadel: The Shattered Halls
[ 542 ] = lw_bc , -- Hellfire Citadel: The Blood Furnace
[ 543 ] = lw_bc , -- Hellfire Citadel: Ramparts
[ 546 ] = lw_bc , -- Coilfang: The Underbog
[ 545 ] = lw_bc , -- Coilfang: The Steamvault
[ 547 ] = lw_bc , -- Coilfang: The Slave Pens
[ 553 ] = lw_bc , -- Tempest Keep: The Botanica
[ 554 ] = lw_bc , -- Tempest Keep: The Mechanar
[ 552 ] = lw_bc , -- Tempest Keep: The Arcatraz
[ 556 ] = lw_bc , -- Auchindoun: Sethekk Halls
[ 555 ] = lw_bc , -- Auchindoun: Shadow Labyrinth
[ 557 ] = lw_bc , -- Auchindoun: Mana-Tombs
[ 558 ] = lw_bc , -- Auchindoun: Auchenai Crypts
[ 269 ] = lw_bc , -- Opening of the Dark Portal
[ 560 ] = lw_bc , -- The Escape from Durnholde
[ 585 ] = lw_bc , -- Magister's Terrace
--[[ LittleWigs: Wrath of the Lich King ]] --
[ 576 ] = lw_wotlk , -- The Nexus
[ 578 ] = lw_wotlk , -- The Oculus
[ 608 ] = lw_wotlk , -- Violet Hold
[ 595 ] = lw_wotlk , -- The Culling of Stratholme
[ 619 ] = lw_wotlk , -- Ahn'kahet: The Old Kingdom
[ 604 ] = lw_wotlk , -- Gundrak
[ 574 ] = lw_wotlk , -- Utgarde Keep
[ 575 ] = lw_wotlk , -- Utgarde Pinnacle
[ 602 ] = lw_wotlk , -- Halls of Lightning
[ 601 ] = lw_wotlk , -- Azjol-Nerub
[ 658 ] = lw_wotlk , -- Pit of Saron
[ 599 ] = lw_wotlk , -- Halls of Stone
[ 600 ] = lw_wotlk , -- Drak'Tharon Keep
[ 650 ] = lw_wotlk , -- Trial of the Champion
[ 668 ] = lw_wotlk , -- Halls of Reflection
[ 632 ] = lw_wotlk , -- The Forge of Souls
--[[ LittleWigs: Cataclysm ]] --
[ 568 ] = lw_cata , -- Zul'Aman
[ 859 ] = lw_cata , -- Zul'Gurub
[ 643 ] = lw_cata , -- Throne of the Tides
[ 644 ] = lw_cata , -- Halls of Origination
[ 645 ] = lw_cata , -- Blackrock Caverns
[ 755 ] = lw_cata , -- Lost City of the Tol'vir
[ 725 ] = lw_cata , -- The Stonecore
[ 938 ] = lw_cata , -- End Time
[ 939 ] = lw_cata , -- Well of Eternity
[ 657 ] = lw_cata , -- The Vortex Pinnacle
[ 670 ] = lw_cata , -- Grim Batol
--[[ LittleWigs: Mists of Pandaria ]] --
[ 959 ] = lw_mop , -- Shado-Pan Monastery
[ 960 ] = lw_mop , -- Temple of the Jade Serpent
[ 961 ] = lw_mop , -- Stormstout Brewery
[ 962 ] = lw_mop , -- Gate of the Setting Sun
[ 994 ] = lw_mop , -- Mogu'shan Palace
[ 1001 ] = lw_mop , -- Scarlet Halls
[ 1011 ] = lw_mop , -- Siege of Niuzao Temple
[ 1112 ] = lw_mop , -- Pursuing the Black Harvest
[ 1004 ] = lw_mop , -- Scarlet Monastery
--[[ LittleWigs: Warlords of Draenor ]] --
[ 1209 ] = lw_wod , -- Skyreach
[ 1176 ] = lw_wod , -- Shadowmoon Burial Grounds
[ 1208 ] = lw_wod , -- Grimrail Depot
[ 1279 ] = lw_wod , -- The Everbloom
[ 1195 ] = lw_wod , -- Iron Docks
[ 1182 ] = lw_wod , -- Auchindoun
[ 1175 ] = lw_wod , -- Bloodmaul Slag Mines
[ 1358 ] = lw_wod , -- Upper Blackrock Spire
--[[ LittleWigs: Legion ]] --
[ 1544 ] = lw_l , -- Assault on Violet Hold
[ 1677 ] = lw_l , -- Cathedral of Eternal Night
[ 1571 ] = lw_l , -- Court of Stars
[ 1651 ] = lw_l , -- Return to Karazhan
[ 1501 ] = lw_l , -- Black Rook Hold
[ 1516 ] = lw_l , -- The Arcway
[ 1466 ] = lw_l , -- Darkheart Thicket
[ 1458 ] = lw_l , -- Neltharion's Lair
[ 1456 ] = lw_l , -- Eye of Azshara
[ 1492 ] = lw_l , -- Maw of Souls
[ 1477 ] = lw_l , -- Halls of Valor
[ 1493 ] = lw_l , -- Vault of the Wardens
[ 1753 ] = lw_l , -- Seat of the Triumvirate
--[[ LittleWigs: Battle for Azeroth ]] --
[ 1763 ] = lw_bfa , -- Atal'Dazar
[ 1754 ] = lw_bfa , -- Freehold
[ 1762 ] = lw_bfa , -- King's Rest
[ 1864 ] = lw_bfa , -- Shrine of the Storm
[ 1822 ] = lw_bfa , -- Siege of Boralus
[ 1877 ] = lw_bfa , -- Temple of Sethraliss
[ 1594 ] = lw_bfa , -- The Undermine
[ 1771 ] = lw_bfa , -- Tol Dagor
[ 1841 ] = lw_bfa , -- Underrot
[ 1862 ] = lw_bfa , -- Waycrest Manor
[ 2097 ] = lw_bfa , -- Operation: Mechagon
[ 2212 ] = lw_bfa , -- Horrific Vision of Orgrimmar
[ 2213 ] = lw_bfa , -- Horrific Vision of Stormwind
--[[ LittleWigs: Shadowlands ]] --
[ 2284 ] = lw_s , -- Sanguine Depths
[ 2285 ] = lw_s , -- Spires of Ascension
[ 2286 ] = lw_s , -- The Necrotic Wake
[ 2287 ] = lw_s , -- Halls of Atonement
[ 2289 ] = lw_s , -- Plaguefall
[ 2290 ] = lw_s , -- Mists of Tirna Scithe
[ 2291 ] = lw_s , -- De Other Side
[ 2293 ] = lw_s , -- Theater of Pain
[ 2441 ] = lw_s , -- Tazavesh, the Veiled Market
}
public.zoneTblWorld = {
[ - 104 ] = - 101 , [ - 100 ] = - 101 , -- Outland
[ - 376 ] = - 424 , [ - 379 ] = - 424 , [ - 504 ] = - 424 , [ - 507 ] = - 424 , [ - 554 ] = - 424 , -- Pandaria
[ - 542 ] = - 572 , [ - 543 ] = - 572 , [ - 534 ] = - 572 , -- Draenor
[ - 630 ] = - 619 , [ - 634 ] = - 619 , [ - 641 ] = - 619 , [ - 650 ] = - 619 , [ - 680 ] = - 619 , -- Broken Isles
[ - 942 ] = - 947 , -- Azeroth/BfA
[ - 1536 ] = - 1647 , [ - 1565 ] = - 1647 , [ - 1525 ] = - 1647 , [ - 1533 ] = - 1647 , -- Shadowlands
}
end
-----------------------------------------------------------------------
-- Utility
--
local EnableAddOn , GetAddOnEnableState , GetAddOnInfo , IsAddOnLoaded , LoadAddOn = EnableAddOn , GetAddOnEnableState , GetAddOnInfo , IsAddOnLoaded , LoadAddOn
local GetAddOnMetadata , IsInGroup , IsInRaid , UnitAffectingCombat , UnitGroupRolesAssigned = GetAddOnMetadata , IsInGroup , IsInRaid , UnitAffectingCombat , UnitGroupRolesAssigned
local GetSpecialization , GetSpecializationRole , IsPartyLFG , UnitIsDeadOrGhost , UnitSetRole = GetSpecialization , GetSpecializationRole , IsPartyLFG , UnitIsDeadOrGhost , UnitSetRole
local reqFuncAddons = {
BigWigs_Core = true ,
BigWigs_Options = true ,
BigWigs_Plugins = true ,
}
local function IsAddOnEnabled ( addon )
local character = UnitName ( " player " )
return GetAddOnEnableState ( character , addon ) > 0
end
local function sysprint ( msg )
print ( " |cFF33FF99BigWigs|r: " .. msg )
end
local function load ( obj , index )
if obj then return true end
if loadOnSlash [ index ] then
if not IsAddOnLoaded ( index ) then -- Check if we need remove our slash handler stub.
for _ , slash in next , loadOnSlash [ index ] do
hash_SlashCmdList [ slash ] = nil
end
end
loadOnSlash [ index ] = nil
end
if reqFuncAddons [ index ] then
reqFuncAddons [ index ] = nil
if index == " BigWigs_Core " then
reqFuncAddons.BigWigs_Plugins = nil
end
end
EnableAddOn ( index ) -- Make sure it wasn't left disabled for whatever reason
local loaded , reason = LoadAddOn ( index )
if not loaded then
sysprint ( ADDON_LOAD_FAILED : format ( GetAddOnInfo ( index ) , _G [ " ADDON_ " .. reason ] ) )
end
return loaded
end
local function loadAddons ( tbl )
if not tbl [ 1 ] then return end
for i = 1 , # tbl do
local index = tbl [ i ]
if not IsAddOnLoaded ( index ) and load ( nil , index ) then
local name = GetAddOnInfo ( index )
public : SendMessage ( " BigWigs_ModulePackLoaded " , name )
end
end
for i = # tbl , 1 , - 1 do
tbl [ i ] = nil
end
end
local function loadZone ( zone )
if loadOnZone [ zone ] then
loadAddons ( loadOnZone [ zone ] )
end
end
local function loadAndEnableCore ( )
local loaded = load ( BigWigs , " BigWigs_Core " )
if not BigWigs then return end
loadAddons ( loadOnCoreEnabled )
BigWigs : Enable ( )
return loaded
end
local function loadCoreAndOpenOptions ( )
loadAndEnableCore ( )
load ( BigWigsOptions , " BigWigs_Options " )
if BigWigsOptions then
BigWigsOptions : Open ( )
end
end
local function Popup ( msg )
BasicMessageDialog.Text : SetText ( msg )
BasicMessageDialog : Show ( )
end
-----------------------------------------------------------------------
-- LDB Plugin
--
local dataBroker = ldb : NewDataObject ( " BigWigs " ,
{ type = " launcher " , label = " BigWigs " , icon = " Interface \\ AddOns \\ BigWigs \\ Media \\ Icons \\ core-disabled " }
)
function dataBroker . OnClick ( self , button )
-- If you are a dev and need the BigWigs options loaded to do something, please come talk to us on Discord about your use case
if button == " RightButton " then
--if isMouseDown then
loadCoreAndOpenOptions ( )
--else
-- local trace = debugstack(2)
-- public.mstack = trace
-- sysprint("|cFFff0000WARNING!|r")
-- sysprint("One of your addons was prevented from force loading the BigWigs options.")
-- sysprint("Contact us on the BigWigs Discord about this, it should not be happening.")
--end
end
end
function dataBroker . OnTooltipShow ( tt )
tt : AddLine ( " BigWigs " )
if BigWigs and BigWigs : IsEnabled ( ) then
local added = false
for name , module in BigWigs : IterateBossModules ( ) do
if module : IsEnabled ( ) then
if not added then
tt : AddLine ( L.activeBossModules , 1 , 1 , 1 )
added = true
end
tt : AddLine ( module.displayName )
end
end
end
for i = 1 , # tooltipFunctions do
tooltipFunctions [ i ] ( tt )
end
tt : AddLine ( L.tooltipHint , 0.2 , 1 , 0.2 , 1 )
end
-----------------------------------------------------------------------
-- Version listing functions
--
tooltipFunctions [ # tooltipFunctions + 1 ] = function ( tt )
local add , i = false , 0
for _ , version in next , usersVersion do
i = i + 1
if version < highestFoundVersion then
add = true
break
end
end
if not add and i ~= GetNumGroupMembers ( ) then
add = true
end
if add then
tt : AddLine ( L.oldVersionsInGroup , 1 , 0 , 0 , 1 )
end
end
-----------------------------------------------------------------------
-- Loader initialization
--
do
local loadOnInstanceAddons = { } -- Will contain all names of addons with an X-BigWigs-LoadOn-InstanceId directive
local loadOnWorldBoss = { } -- Addons that should load when targetting a specific mob
local extraMenus = { } -- Addons that contain extra zone menus to appear in the GUI
local noMenus = { } -- Addons that contain zones that shouldn't create a menu
local blockedMenus = { } -- Zones that shouldn't create a menu
for i = 1 , GetNumAddOns ( ) do
local name = GetAddOnInfo ( i )
if reqFuncAddons [ name ] then
EnableAddOn ( i ) -- Make sure it wasn't left disabled for whatever reason
end
if IsAddOnEnabled ( i ) then
local meta = GetAddOnMetadata ( i , " X-BigWigs-LoadOn-CoreEnabled " )
if meta then
if name == " BigWigs_Plugins " then -- Always first
table.insert ( loadOnCoreEnabled , 1 , i )
else
loadOnCoreEnabled [ # loadOnCoreEnabled + 1 ] = i
end
end
meta = GetAddOnMetadata ( i , " X-BigWigs-LoadOn-InstanceId " )
if meta then
loadOnInstanceAddons [ # loadOnInstanceAddons + 1 ] = i
end
meta = GetAddOnMetadata ( i , " X-BigWigs-ExtraMenu " )
if meta then
extraMenus [ # extraMenus + 1 ] = i
end
meta = GetAddOnMetadata ( i , " X-BigWigs-NoMenu " )
if meta then
noMenus [ # noMenus + 1 ] = i
end
meta = GetAddOnMetadata ( i , " X-BigWigs-LoadOn-WorldBoss " )
if meta then
loadOnWorldBoss [ # loadOnWorldBoss + 1 ] = i
end
meta = GetAddOnMetadata ( i , " X-BigWigs-LoadOn-Slash " )
if meta then
loadOnSlash [ i ] = { }
local tbl = { strsplit ( " , " , meta ) }
for j = 1 , # tbl do
local slash = tbl [ j ] : trim ( ) : upper ( )
_G [ " SLASH_ " .. slash .. 1 ] = slash
SlashCmdList [ slash ] = function ( text )
if strfind ( name , " BigWigs " , nil , true ) then
-- Attempting to be smart. Only load core & config if it's a BW plugin.
loadAndEnableCore ( )
load ( BigWigsOptions , " BigWigs_Options " )
end
if load ( nil , i ) then -- Load the addon/plugin
-- Call the slash command again, which should have been set by the addon.
-- Authors, do NOT delay setting it in OnInitialize/OnEnable/etc.
ChatFrame_ImportAllListsToHash ( )
local func = hash_SlashCmdList [ slash ]
if func then
func ( text )
else
-- Addon didn't register the slash command for whatever reason, print the default invalid slash message.
local info = ChatTypeInfo [ " SYSTEM " ]
DEFAULT_CHAT_FRAME : AddMessage ( HELP_TEXT_SIMPLE , info.r , info.g , info.b , info.id )
end
end
end
loadOnSlash [ i ] [ j ] = slash
end
end
else
local meta = GetAddOnMetadata ( i , " X-BigWigs-LoadOn-InstanceId " )
if meta then -- Disabled content
for j = 1 , select ( " # " , strsplit ( " , " , meta ) ) do
local rawId = select ( j , strsplit ( " , " , meta ) )
local id = tonumber ( rawId : trim ( ) )
if id and id > 0 then
if public.zoneTbl [ id ] then
if not disabledZones then disabledZones = { } end
disabledZones [ id ] = name
end
end
end
end
end
if next ( loadOnSlash ) then
ChatFrame_ImportAllListsToHash ( ) -- Add our slashes to the hash.
end
end
local function iterateInstanceIds ( addon , ... )
for i = 1 , select ( " # " , ... ) do
local rawId = select ( i , ... )
local id = tonumber ( rawId : trim ( ) )
if id then
local instanceName = GetRealZoneText ( id )
-- register the instance id for enabling.
if instanceName and instanceName ~= " " then -- Protect live client from beta client ids
enableZones [ id ] = true
if not loadOnZone [ id ] then loadOnZone [ id ] = { } end
loadOnZone [ id ] [ # loadOnZone [ id ] + 1 ] = addon
if not menus [ id ] and not blockedMenus [ id ] then menus [ id ] = true end
end
else
local name = GetAddOnInfo ( addon )
sysprint ( ( " The instance ID %q from the addon %q was not parsable. " ) : format ( tostring ( rawId ) , name ) )
end
end
end
local currentZone = nil
local function iterateWorldBosses ( addon , ... )
for i = 1 , select ( " # " , ... ) do
local rawZoneOrBoss = select ( i , ... )
local zoneOrBoss = tonumber ( rawZoneOrBoss : trim ( ) )
if zoneOrBoss then
if not currentZone then
currentZone = zoneOrBoss
-- register the zone for enabling.
enableZones [ currentZone ] = " world "
if not loadOnZone [ currentZone ] then loadOnZone [ currentZone ] = { } end
loadOnZone [ currentZone ] [ # loadOnZone [ currentZone ] + 1 ] = addon
else
worldBosses [ zoneOrBoss ] = currentZone
currentZone = nil
end
else
local name = GetAddOnInfo ( addon )
sysprint ( ( " The zone ID %q from the addon %q was not parsable. " ) : format ( tostring ( rawZoneOrBoss ) , name ) )
end
end
end
local function addExtraMenus ( addon , ... )
for i = 1 , select ( " # " , ... ) do
local rawMenu = select ( i , ... )
local id = tonumber ( rawMenu : trim ( ) )
if id then
local name
if id < 0 then
local tbl = GetMapInfo ( - id )
if tbl then
name = tbl.name
else
name = tostring ( id )
end
else
name = GetRealZoneText ( id )
end
if name and name ~= " " then -- Protect live client from beta client ids
if not loadOnZone [ id ] then loadOnZone [ id ] = { } end
loadOnZone [ id ] [ # loadOnZone [ id ] + 1 ] = addon
if not menus [ id ] then menus [ id ] = true end
end
else
local name = GetAddOnInfo ( addon )
sysprint ( ( " The extra menu ID %q from the addon %q was not parsable. " ) : format ( tostring ( rawMenu ) , name ) )
end
end
end
local function blockMenus ( addon , ... )
for i = 1 , select ( " # " , ... ) do
local rawMenu = select ( i , ... )
local id = tonumber ( rawMenu : trim ( ) )
if id then
local name
if id < 0 then
local tbl = GetMapInfo ( - id )
if tbl then
name = tbl.name
else
name = tostring ( id )
end
else
name = GetRealZoneText ( id )
end
if name and name ~= " " and not blockedMenus [ id ] then -- Protect live client from beta client ids
blockedMenus [ id ] = true
end
else
local name = GetAddOnInfo ( addon )
sysprint ( ( " The block menu ID %q from the addon %q was not parsable. " ) : format ( tostring ( rawMenu ) , name ) )
end
end
end
for i = 1 , # extraMenus do
local index = extraMenus [ i ]
local data = GetAddOnMetadata ( index , " X-BigWigs-ExtraMenu " )
if data then
addExtraMenus ( index , strsplit ( " , " , data ) )
end
end
for i = 1 , # noMenus do
local index = noMenus [ i ]
local data = GetAddOnMetadata ( index , " X-BigWigs-NoMenu " )
if data then
blockMenus ( index , strsplit ( " , " , data ) )
end
end
for i = 1 , # loadOnInstanceAddons do
local index = loadOnInstanceAddons [ i ]
local instancesIds = GetAddOnMetadata ( index , " X-BigWigs-LoadOn-InstanceId " )
if instancesIds then
iterateInstanceIds ( index , strsplit ( " , " , instancesIds ) )
end
end
for i = 1 , # loadOnWorldBoss do
local index = loadOnWorldBoss [ i ]
local zones = GetAddOnMetadata ( index , " X-BigWigs-LoadOn-WorldBoss " )
if zones then
iterateWorldBosses ( index , strsplit ( " , " , zones ) )
end
end
end
function mod : ADDON_LOADED ( addon )
if addon ~= " BigWigs " then
-- If you are a dev and need the BigWigs options loaded to do something, please come talk to us on Discord about your use case
--if reqFuncAddons[addon] then
-- local trace = debugstack(2)
-- public.lstack = trace
-- sysprint("|cFFff0000WARNING!|r")
-- sysprint("One of your addons is force loading the BigWigs options.")
-- sysprint("Contact us on the BigWigs Discord about this, it should not be happening.")
-- reqFuncAddons = {}
--end
return
end
--bwFrame:RegisterEvent("GLOBAL_MOUSE_DOWN")
--bwFrame:RegisterEvent("GLOBAL_MOUSE_UP")
bwFrame : RegisterEvent ( " ZONE_CHANGED " )
bwFrame : RegisterEvent ( " PLAYER_ENTERING_WORLD " )
bwFrame : RegisterEvent ( " GROUP_ROSTER_UPDATE " )
bwFrame : RegisterEvent ( " LFG_PROPOSAL_SHOW " )
-- Role Updating
bwFrame : RegisterEvent ( " ACTIVE_TALENT_GROUP_CHANGED " )
RolePollPopup : UnregisterEvent ( " ROLE_POLL_BEGIN " )
bwFrame : RegisterEvent ( " CHAT_MSG_ADDON " )
C_ChatInfo.RegisterAddonMessagePrefix ( " BigWigs " )
C_ChatInfo.RegisterAddonMessagePrefix ( " D4 " ) -- DBM
-- LibDBIcon setup
if type ( BigWigsIconDB ) ~= " table " then
BigWigsIconDB = { }
end
ldbi : Register ( " BigWigs " , dataBroker , BigWigsIconDB )
if BigWigs3DB then
-- Somewhat ugly, but saves loading AceDB with the loader instead of with the core
if BigWigs3DB.profileKeys and BigWigs3DB.profiles then
local name = UnitName ( " player " )
local realm = GetRealmName ( )
if name and realm and BigWigs3DB.profileKeys [ name .. " - " .. realm ] then
local key = BigWigs3DB.profiles [ BigWigs3DB.profileKeys [ name .. " - " .. realm ] ]
if key then
self.isFakingDBM = key.fakeDBMVersion
self.isShowingZoneMessages = key.showZoneMessages
end
if BigWigs3DB.namespaces and BigWigs3DB.namespaces . BigWigs_Plugins_Sounds and BigWigs3DB.namespaces . BigWigs_Plugins_Sounds.profiles and BigWigs3DB.namespaces . BigWigs_Plugins_Sounds.profiles [ BigWigs3DB.profileKeys [ name .. " - " .. realm ] ] then
self.isSoundOn = BigWigs3DB.namespaces . BigWigs_Plugins_Sounds.profiles [ BigWigs3DB.profileKeys [ name .. " - " .. realm ] ] . sound
end
end
end
-- Cleanup function.
-- TODO: look into having a way for our boss modules not to create a table when no options are changed.
if BigWigs3DB.namespaces then
for k , v in next , BigWigs3DB.namespaces do
if strfind ( k , " BigWigs_Bosses_ " , nil , true ) and not next ( v ) then
BigWigs3DB.namespaces [ k ] = nil
end
end
end
BigWigs3DB.wipe80 = nil -- XXX temp boss DB wipe for 8.0.1 // removed in 9.0.2
BigWigs3DB.discord = nil -- XXX 9.0.2
end
self : BigWigs_CoreOptionToggled ( nil , " fakeDBMVersion " , self.isFakingDBM )
local num = tonumber ( C_CVar.GetCVar ( " Sound_NumChannels " ) ) or 0
if num < 64 then
C_CVar.SetCVar ( " Sound_NumChannels " , " 64 " ) -- Blizzard keeps screwing with addon sound priority so we force this minimum
end
num = tonumber ( C_CVar.GetCVar ( " Sound_MaxCacheSizeInBytes " ) ) or 0
if num < 67108864 then
C_CVar.SetCVar ( " Sound_MaxCacheSizeInBytes " , " 67108864 " ) -- Set the cache to the "Small (64MB)" setting as a minimum
end
--bwFrame:UnregisterEvent("ADDON_LOADED")
--self.ADDON_LOADED = nil
bwFrame.UnregisterEvent ( UIParent , " TALKINGHEAD_REQUESTED " ) -- Prevent the event order re-shuffling mid-instance
end
function mod : GLOBAL_MOUSE_DOWN ( button )
if button == " RightButton " then
isMouseDown = true
end
end
function mod : GLOBAL_MOUSE_UP ( button )
if button == " RightButton " then
isMouseDown = false
end
end
-- We can't do our addon loading in ADDON_LOADED as the target addons may be registering that
-- which would break that event for those addons. Use this event instead.
function mod : UPDATE_FLOATING_CHAT_WINDOWS ( )
bwFrame : UnregisterEvent ( " UPDATE_FLOATING_CHAT_WINDOWS " )
self.UPDATE_FLOATING_CHAT_WINDOWS = nil
self : GROUP_ROSTER_UPDATE ( )
self : PLAYER_ENTERING_WORLD ( )
self : ZONE_CHANGED ( )
end
-- Various temporary printing stuff
do
local old = {
BigWigs_Ulduar = " BigWigs_WrathOfTheLichKing " ,
BigWigs_Yogg_Brain = " BigWigs_WrathOfTheLichKing " ,
BigWigs_TheEye = " BigWigs_BurningCrusade " ,
BigWigs_Sunwell = " BigWigs_BurningCrusade " ,
BigWigs_SSC = " BigWigs_BurningCrusade " ,
BigWigs_Outland = " BigWigs_BurningCrusade " ,
BigWigs_Northrend = " BigWigs_WrathOfTheLichKing " ,
BigWigs_Naxxramas = " BigWigs_WrathOfTheLichKing " ,
BigWigs_MC = " BigWigs_Classic " ,
BigWigs_Karazhan = " BigWigs_BurningCrusade " ,
BigWigs_Hyjal = " BigWigs_BurningCrusade " ,
BigWigs_Coliseum = " BigWigs_WrathOfTheLichKing " ,
BigWigs_Citadel = " BigWigs_WrathOfTheLichKing " ,
BigWigs_LK_Valkyr_Marker = " BigWigs_WrathOfTheLichKing " ,
BigWigs_BWL = " BigWigs_Classic " ,
BigWigs_BlackTemple = " BigWigs_BurningCrusade " ,
BigWigs_AQ20 = " BigWigs_Classic " ,
BigWigs_AQ40 = " BigWigs_Classic " ,
BigWigs_Baradin = " BigWigs_Cataclysm " ,
BigWigs_Bastion = " BigWigs_Cataclysm " ,
BigWigs_Blackwing = " BigWigs_Cataclysm " ,
BigWigs_DragonSoul = " BigWigs_Cataclysm " ,
BigWigs_Firelands = " BigWigs_Cataclysm " ,
BigWigs_Throne = " BigWigs_Cataclysm " ,
bigwigs_zonozzicons = " BigWigs_Cataclysm " ,
BigWigs_EndlessSpring = " BigWigs_MistsOfPandaria " ,
BigWigs_HeartOfFear = " BigWigs_MistsOfPandaria " ,
BigWigs_Mogushan = " BigWigs_MistsOfPandaria " ,
BigWigs_Pandaria = " BigWigs_MistsOfPandaria " ,
BigWigs_SiegeOfOrgrimmar = " BigWigs_MistsOfPandaria " ,
BigWigs_ThroneOfThunder = " BigWigs_MistsOfPandaria " ,
BigWigs_Draenor = " BigWigs_WarlordsOfDraenor " ,
BigWigs_Highmaul = " BigWigs_WarlordsOfDraenor " ,
BigWigs_BlackrockFoundry = " BigWigs_WarlordsOfDraenor " ,
BigWigs_HellfireCitadel = " BigWigs_WarlordsOfDraenor " ,
LittleWigs_ShadoPanMonastery = " LittleWigs " ,
LittleWigs_ScarletHalls = " LittleWigs " ,
LittleWigs_ScarletMonastery = " LittleWigs " ,
LittleWigs_MogushanPalace = " LittleWigs " ,
LittleWigs_TempleOfTheJadeSerpent = " LittleWigs " ,
LittleWigs_TBC = " LittleWigs " ,
LittleWigs_Auchindoun = " LittleWigs " ,
LittleWigs_Coilfang = " LittleWigs " ,
LittleWigs_CoT = " LittleWigs " ,
LittleWigs_HellfireCitadel = " LittleWigs " ,
LittleWigs_MagistersTerrace = " LittleWigs " ,
LittleWigs_TempestKeep = " LittleWigs " ,
LittleWigs_LK = " LittleWigs " ,
LittleWigs_Coldarra = " LittleWigs " ,
LittleWigs_Dalaran = " LittleWigs " ,
LittleWigs_Dragonblight = " LittleWigs " ,
LittleWigs_Frozen_Halls = " LittleWigs " ,
LittleWigs_Howling_Fjord = " LittleWigs " ,
LittleWigs_Icecrown = " LittleWigs " ,
LittleWigs_Stratholme = " LittleWigs " ,
LittleWigs_Storm_Peaks = " LittleWigs " ,
[ " LittleWigs_Zul'Drak " ] = " LittleWigs " ,
BigWigs_TayakIcons = " BigWigs " ,
BigWigs_PizzaBar = " BigWigs " ,
BigWigs_ShaIcons = " BigWigs " ,
BigWigs_LeiShi_Marker = " BigWigs " ,
BigWigs_NoPluginWarnings = " BigWigs " ,
LFG_ProposalTime = " BigWigs " ,
CourtOfStarsGossipHelper = " LittleWigs " ,
BigWigs_DispelResist = " Abandoned " ,
BigWigs_Voice_HeroesOfTheStorm = " BigWigs_Countdown_HeroesOfTheStorm " ,
BigWigs_Voice_Overwatch = " BigWigs_Countdown_Overwatch " ,
BigWigs_AutoReply = " BigWigs " ,
BigWigs_AutoReply2 = " BigWigs " ,
BigWigs_Antorus = " BigWigs_Legion " ,
BigWigs_ArgusInvasionPoints = " BigWigs_Legion " ,
BigWigs_BrokenIsles = " BigWigs_Legion " ,
BigWigs_Nighthold = " BigWigs_Legion " ,
BigWigs_Nightmare = " BigWigs_Legion " ,
BigWigs_TombOfSargeras = " BigWigs_Legion " ,
BigWigs_TrialOfValor = " BigWigs_Legion " ,
BigWigs_SiegeOfZuldazar = " BigWigs " ,
FS_Core = " Abandoned " , -- abandoned addon breaking the load order
BigWigs_Azeroth = " BigWigs_BattleForAzeroth " ,
BigWigs_BattleOfDazaralor = " BigWigs_BattleForAzeroth " ,
BigWigs_CrucibleOfStorms = " BigWigs_BattleForAzeroth " ,
BigWigs_EternalPalace = " BigWigs_BattleForAzeroth " ,
BigWigs_Nyalotha = " BigWigs_BattleForAzeroth " ,
BigWigs_Uldir = " BigWigs_BattleForAzeroth " ,
}
local delayedMessages = { }
local warning = " The addon '|cffffff00%s|r' is forcing %s to load prematurely, notify the BigWigs authors! "
local dontForceLoadList = {
BigWigs_Core = true ,
BigWigs_Plugins = true ,
BigWigs_Options = true ,
BigWigs_Shadowlands = true ,
BigWigs_CastleNathria = true ,
BigWigs_SanctumOfDomination = true ,
BigWigs_Classic = true ,
BigWigs_BurningCrusade = true ,
BigWigs_WrathOfTheLichKing = true ,
BigWigs_Cataclysm = true ,
BigWigs_MistsOfPandaria = true ,
BigWigs_WarlordsOfDraenor = true ,
BigWigs_Legion = true ,
BigWigs_BattleForAzeroth = true ,
LittleWigs = true ,
LittleWigs_Classic = true ,
LittleWigs_BurningCrusade = true ,
LittleWigs_WrathOfTheLichKing = true ,
LittleWigs_Cataclysm = true ,
LittleWigs_MistsOfPandaria = true ,
LittleWigs_WarlordsOfDraenor = true ,
LittleWigs_Legion = true ,
LittleWigs_BattleForAzeroth = true ,
}
-- Try to teach people not to force load our modules.
for i = 1 , GetNumAddOns ( ) do
local name = GetAddOnInfo ( i )
if IsAddOnEnabled ( i ) and not IsAddOnLoadOnDemand ( i ) then
for j = 1 , select ( " # " , GetAddOnOptionalDependencies ( i ) ) do
local meta = select ( j , GetAddOnOptionalDependencies ( i ) )
local addonName = tostring ( meta )
if dontForceLoadList [ addonName ] then
delayedMessages [ # delayedMessages + 1 ] = warning : format ( name , addonName )
end
end
for j = 1 , select ( " # " , GetAddOnDependencies ( i ) ) do
local meta = select ( j , GetAddOnDependencies ( i ) )
local addonName = tostring ( meta )
if dontForceLoadList [ addonName ] then
delayedMessages [ # delayedMessages + 1 ] = warning : format ( name , addonName )
end
end
end
if old [ name ] then
delayedMessages [ # delayedMessages + 1 ] = L.removeAddon : format ( name , old [ name ] )
Popup ( L.removeAddon : format ( name , old [ name ] ) )
end
end
local L = GetLocale ( )
local locales = {
--ruRU = "Russian (ruRU)",
itIT = " Italian (itIT) " ,
--koKR = "Korean (koKR)",
esES = " Spanish (esES) " ,
--esMX = "Spanish (esMX)",
--deDE = "German (deDE)",
--ptBR = "Portuguese (ptBR)",
--frFR = "French (frFR)",
}
if locales [ L ] then
delayedMessages [ # delayedMessages + 1 ] = ( " BigWigs is missing translations for %s. Can you help? Visit git.io/vpBye or ask us on Discord for more info. " ) : format ( locales [ L ] )
end
if # delayedMessages > 0 then
function mod : LOADING_SCREEN_DISABLED ( )
bwFrame : UnregisterEvent ( " LOADING_SCREEN_DISABLED " )
CTimerAfter ( 0 , function ( ) -- Timers aren't fully functional until 1 frame after loading is done
CTimerAfter ( 15 , function ( )
for i = 1 , # delayedMessages do
sysprint ( delayedMessages [ i ] )
end
delayedMessages = nil
end )
end )
self.LOADING_SCREEN_DISABLED = nil
end
bwFrame : RegisterEvent ( " LOADING_SCREEN_DISABLED " )
end
end
-----------------------------------------------------------------------
-- Callback handler
--
do
local callbackMap = { }
function public : RegisterMessage ( msg , func )
if self == BigWigsLoader then
error ( " .RegisterMessage(addon, message, function) attempted to register a function to BigWigsLoader, you might be using : instead of . to register the callback. " )
end
if type ( msg ) ~= " string " then
error ( " :RegisterMessage(message, function) attempted to register invalid message, must be a string! " )
end
local funcType = type ( func )
if funcType == " string " then
if not self [ func ] then error ( ( " :RegisterMessage(message, function) attempted to register the function '%s' but it doesn't exist! " ) : format ( func ) ) end
elseif funcType == " nil " then
if not self [ msg ] then error ( ( " :RegisterMessage(message, function) attempted to register the function '%s' but it doesn't exist! " ) : format ( msg ) ) end
elseif funcType ~= " function " then
error ( " :RegisterMessage(message, function) attempted to register an invalid function! " )
end
if not callbackMap [ msg ] then callbackMap [ msg ] = { } end
callbackMap [ msg ] [ self ] = func or msg
end
function public : UnregisterMessage ( msg )
if self == BigWigsLoader then
error ( " .UnregisterMessage(addon, message, function) attempted to unregister a function from BigWigsLoader, you might be using : instead of . to register the callback. " )
end
if type ( msg ) ~= " string " then error ( " :UnregisterMessage(message) attempted to unregister an invalid message, must be a string! " ) end
if not callbackMap [ msg ] then return end
callbackMap [ msg ] [ self ] = nil
if not next ( callbackMap [ msg ] ) then
callbackMap [ msg ] = nil
end
end
local pcall , geterrorhandler = pcall , geterrorhandler
function public : SendMessage ( msg , ... )
if callbackMap [ msg ] then
for k , v in next , callbackMap [ msg ] do
if type ( v ) == " function " then
local success , errorMsg = pcall ( v , msg , ... )
if not success then
geterrorhandler ( ) ( ( " BigWigs: One of your addons caused an error on the %q callback: \n %s " ) : format ( msg , errorMsg ) )
end
else
local success , errorMsg = pcall ( k [ v ] , k , msg , ... )
if not success then
geterrorhandler ( ) ( ( " BigWigs: One of your addons caused an error on the %q callback: \n %s " ) : format ( msg , errorMsg ) )
end
end
end
end
end
local function UnregisterAllMessages ( _ , module )
for k , v in next , callbackMap do
for j in next , v do
if j == module then
public.UnregisterMessage ( module , k )
end
end
end
end
public.RegisterMessage ( mod , " BigWigs_OnBossDisable " , UnregisterAllMessages )
public.RegisterMessage ( mod , " BigWigs_OnBossWipe " , UnregisterAllMessages )
public.RegisterMessage ( mod , " BigWigs_OnPluginDisable " , UnregisterAllMessages )
end
-----------------------------------------------------------------------
-- DBM version collection & faking
--
do
local DBMdotRevision = " 20210701004539 " -- The changing version of the local client, changes with every new zip using the project-date-integer packager replacement.
local DBMdotDisplayVersion = " 9.1.1 " -- "N.N.N" for a release and "N.N.N alpha" for the alpha duration.
local DBMdotReleaseRevision = " 20210630000000 " -- Hardcoded time, manually changed every release, they use it to track the highest release version, a new DBM release is the only time it will change.
local timer , prevUpgradedUser = nil , nil
local function sendMsg ( )
if IsInGroup ( ) then
SendAddonMessage ( " D4 " , " V \t " .. DBMdotRevision .. " \t " .. DBMdotReleaseRevision .. " \t " .. DBMdotDisplayVersion .. " \t " .. GetLocale ( ) .. " \t " .. " true " , IsInGroup ( 2 ) and " INSTANCE_CHAT " or " RAID " ) -- LE_PARTY_CATEGORY_INSTANCE = 2
end
timer , prevUpgradedUser = nil , nil
end
function mod : DBM_VersionCheck ( prefix , sender , revision , releaseRevision , displayVersion )
if prefix == " H " and ( BigWigs and BigWigs.db and BigWigs.db . profile.fakeDBMVersion or self.isFakingDBM ) then
if timer then timer : Cancel ( ) end
timer = CTimerNewTicker ( 3.3 , sendMsg , 1 )
elseif prefix == " V " then
usersDBM [ sender ] = displayVersion
--if BigWigs and BigWigs.db.profile.fakeDBMVersion or self.isFakingDBM then
-- -- If there are people with newer versions than us, suddenly we've upgraded!
-- local rev, dotRev = tonumber(revision), tonumber(DBMdotRevision)
-- if rev and displayVersion and rev ~= 99999 and rev > dotRev and not strfind(displayVersion, "alpha", nil, true) then -- Failsafes
-- if not prevUpgradedUser then
-- prevUpgradedUser = sender
-- elseif prevUpgradedUser ~= sender then
-- DBMdotRevision = revision -- Update our local rev with the highest possible rev found.
-- DBMdotReleaseRevision = releaseRevision -- Update our release rev with the highest found, this should be the same for alpha users and latest release users.
-- DBMdotDisplayVersion = displayVersion -- Update to the latest display version.
-- -- Re-send the addon message.
-- if timer then timer:Cancel() end
-- timer = CTimerNewTicker(1, sendMsg, 1)
-- end
-- end
--end
end
end
function mod : BigWigs_CoreOptionToggled ( _ , key , value )
if key == " fakeDBMVersion " and value and IsInGroup ( ) then
self : DBM_VersionCheck ( " H " ) -- Send addon message if feature is being turned on inside a raid/group.
end
end
public.RegisterMessage ( mod , " BigWigs_CoreOptionToggled " )
end
-----------------------------------------------------------------------
-- Events
--
bwFrame : SetScript ( " OnEvent " , function ( _ , event , ... )
mod [ event ] ( mod , ... )
end )
bwFrame : RegisterEvent ( " ADDON_LOADED " )
bwFrame : RegisterEvent ( " UPDATE_FLOATING_CHAT_WINDOWS " )
do
-- Role Updating
local prev = 0
function mod : PLAYER_REGEN_ENABLED ( )
bwFrame : UnregisterEvent ( " PLAYER_REGEN_ENABLED " )
self : ACTIVE_TALENT_GROUP_CHANGED ( ) -- Force role check
end
function mod : ACTIVE_TALENT_GROUP_CHANGED ( )
if IsInGroup ( ) then
if IsPartyLFG ( ) then return end
local tree = GetSpecialization ( )
if not tree then return end -- No spec selected
local role = GetSpecializationRole ( tree )
if role and UnitGroupRolesAssigned ( " player " ) ~= role then
if InCombatLockdown ( ) or UnitAffectingCombat ( " player " ) then
bwFrame : RegisterEvent ( " PLAYER_REGEN_ENABLED " )
return
end
-- ACTIVE_TALENT_GROUP_CHANGED fires twice when changing spec, leaving the talent tree, and entering the new tree. We throttle this to prevent a double role chat message.
-- It should only fire once when joining a group (triggered from GROUP_ROSTER_UPDATE)
-- This will fail when logging in/reloading in a group because GetSpecializationRole is nil since WoW v7 when GROUP_ROSTER_UPDATE fires
-- However, your role seems to be saved internally and preserved, so is this really an issue?
local t = GetTime ( )
if ( t - prev ) > 2 then
prev = t
UnitSetRole ( " player " , role )
end
end
end
end
end
-- Merged LFG_ProposalTime addon by Freebaser
do
local prev
function mod : LFG_PROPOSAL_SHOW ( )
if not prev then
local timerBar = CreateFrame ( " StatusBar " , nil , LFGDungeonReadyPopup )
timerBar : SetPoint ( " TOP " , LFGDungeonReadyPopup , " BOTTOM " , 0 , - 5 )
local tex = timerBar : CreateTexture ( )
tex : SetTexture ( 137012 ) -- Interface\\TargetingFrame\\UI-StatusBar
timerBar : SetStatusBarTexture ( tex )
timerBar : SetSize ( 190 , 9 )
timerBar : SetStatusBarColor ( 1 , 0.1 , 0 )
timerBar : SetMinMaxValues ( 0 , 40 )
timerBar : Show ( )
local bg = timerBar : CreateTexture ( nil , " BACKGROUND " )
bg : SetAllPoints ( timerBar )
bg : SetColorTexture ( 0 , 0 , 0 , 0.7 )
local spark = timerBar : CreateTexture ( nil , " OVERLAY " )
spark : SetTexture ( 130877 ) -- Interface\\CastingBar\\UI-CastingBar-Spark
spark : SetSize ( 32 , 32 )
spark : SetBlendMode ( " ADD " )
spark : SetPoint ( " LEFT " , tex , " RIGHT " , - 15 , 0 )
local border = timerBar : CreateTexture ( nil , " OVERLAY " )
border : SetTexture ( 130874 ) -- Interface\\CastingBar\\UI-CastingBar-Border
border : SetSize ( 256 , 64 )
border : SetPoint ( " TOP " , timerBar , 0 , 28 )
timerBar.text = timerBar : CreateFontString ( nil , " OVERLAY " , " GameFontHighlight " )
timerBar.text : SetPoint ( " CENTER " , timerBar , " CENTER " )
self.LFG_PROPOSAL_SHOW = function ( )
prev = GetTime ( ) + 40
-- Play in Master for those that have SFX off or very low.
-- Using false as third arg to avoid the "only one of each sound at a time" throttle.
-- Only play via the "Master" channel if we have sounds turned on
if ( BigWigs and BigWigs : GetPlugin ( " Sounds " ) and BigWigs : GetPlugin ( " Sounds " ) . db.profile . sound ) or self.isSoundOn ~= false then
local _ , id = PlaySound ( 8960 , " Master " , false ) -- SOUNDKIT.READY_CHECK
if id then
StopSound ( id - 1 ) -- Should work most of the time to stop the blizz sound
end
end
end
self : LFG_PROPOSAL_SHOW ( )
timerBar : SetScript ( " OnUpdate " , function ( f )
local timeLeft = prev - GetTime ( )
if timeLeft > 0 then
f : SetValue ( timeLeft )
f.text : SetFormattedText ( " BigWigs: %.1f " , timeLeft )
end
end )
-- USE THIS CALLBACK TO SKIN THIS WINDOW! NO NEED FOR UGLY HAX! E.g.
-- local name, addon = ...
-- if BigWigsLoader then
-- BigWigsLoader.RegisterMessage(addon, "BigWigs_FrameCreated", function(event, frame, name) print(name.." frame created.") end)
-- end
public : SendMessage ( " BigWigs_FrameCreated " , timerBar , " QueueTimer " )
end
end
end
function mod : CHAT_MSG_ADDON ( prefix , msg , channel , sender )
if channel ~= " RAID " and channel ~= " PARTY " and channel ~= " INSTANCE_CHAT " then
return
elseif prefix == " BigWigs " then
local bwPrefix , bwMsg , extra , guildVersion , guildName = strsplit ( " ^ " , msg )
sender = Ambiguate ( sender , " none " )
if bwPrefix == " V " or bwPrefix == " Q " then
self : VersionCheck ( bwPrefix , bwMsg , extra , guildVersion , guildName , sender )
elseif bwPrefix == " B " then
public : SendMessage ( " BigWigs_BossComm " , bwMsg , extra , sender )
elseif bwPrefix == " P " then
if bwMsg == " Pull " then
local _ , _ , _ , instanceId = UnitPosition ( " player " )
local _ , _ , _ , tarInstanceId = UnitPosition ( sender )
if instanceId == tarInstanceId then
loadAndEnableCore ( ) -- Force enable the core when receiving a pull timer.
end
elseif bwMsg == " Break " then
loadAndEnableCore ( ) -- Force enable the core when receiving a break timer.
end
public : SendMessage ( " BigWigs_PluginComm " , bwMsg , extra , sender )
end
elseif prefix == " D4 " then
local dbmPrefix , arg1 , arg2 , arg3 , arg4 = strsplit ( " \t " , msg )
sender = Ambiguate ( sender , " none " )
if dbmPrefix == " V " or dbmPrefix == " H " then
self : DBM_VersionCheck ( dbmPrefix , sender , arg1 , arg2 , arg3 )
elseif dbmPrefix == " U " or dbmPrefix == " PT " or dbmPrefix == " M " or dbmPrefix == " BT " then
if dbmPrefix == " PT " then
local _ , _ , _ , instanceId = UnitPosition ( " player " )
local _ , _ , _ , tarInstanceId = UnitPosition ( sender )
if instanceId == tarInstanceId then
loadAndEnableCore ( ) -- Force enable the core when receiving a pull timer.
end
elseif dbmPrefix == " BT " then
loadAndEnableCore ( ) -- Force enable the core when receiving a break timer.
end
public : SendMessage ( " DBM_AddonMessage " , sender , dbmPrefix , arg1 , arg2 , arg3 , arg4 )
end
end
end
local ResetVersionWarning
do
local timer = nil
local function sendMsg ( )
if IsInGroup ( ) then
SendAddonMessage ( " BigWigs " , versionResponseString , IsInGroup ( 2 ) and " INSTANCE_CHAT " or " RAID " ) -- LE_PARTY_CATEGORY_INSTANCE = 2
end
timer = nil
end
local hasWarned = 0
local hasGuildWarned = false
local verTimer = nil
local verGuildTimer = nil
function ResetVersionWarning ( )
hasWarned = 0
hasGuildWarned = false
if verTimer then verTimer : Cancel ( ) end -- We may have left the group whilst a warning is about to show
if verGuildTimer then verGuildTimer : Cancel ( ) end
verTimer = nil
verGuildTimer = nil
end
local function printOutOfDate ( tbl )
if hasWarned == 3 then return end
local warnedOutOfDate , warnedReallyOutOfDate , warnedExtremelyOutOfDate = 0 , 0 , 0
for k , v in next , tbl do
if v > BIGWIGS_VERSION then
warnedOutOfDate = warnedOutOfDate + 1
if ( v - 1 ) > BIGWIGS_VERSION then -- 2+ releases
warnedReallyOutOfDate = warnedReallyOutOfDate + 1
if ( v - 2 ) > BIGWIGS_VERSION then -- 3+ releases
warnedExtremelyOutOfDate = warnedExtremelyOutOfDate + 1
end
end
end
end
if warnedExtremelyOutOfDate > 1 then
if verTimer then verTimer : Cancel ( ) end
verTimer = CTimerNewTicker ( 3 , function ( )
hasWarned = 3
verTimer = nil
local diff = highestFoundVersion - BIGWIGS_VERSION
if not customGuildName then
local msg = L.warnSeveralReleases : format ( diff )
sysprint ( msg )
Popup ( msg )
RaidNotice_AddMessage ( RaidWarningFrame , msg , { r = 1 , g = 1 , b = 1 } , 40 )
else
sysprint ( L.warnOldBase : format ( BIGWIGS_GUILD_VERSION , BIGWIGS_VERSION , diff ) )
end
end , 1 )
elseif warnedReallyOutOfDate > 1 and hasWarned < 2 and not customGuildName then
if verTimer then verTimer : Cancel ( ) end
verTimer = CTimerNewTicker ( 3 , function ( )
hasWarned = 2
verTimer = nil
sysprint ( L.warnTwoReleases )
RaidNotice_AddMessage ( RaidWarningFrame , L.warnTwoReleases , { r = 1 , g = 1 , b = 1 } , 20 )
end , 1 )
elseif warnedOutOfDate > 1 and hasWarned < 1 and not customGuildName then
if verTimer then verTimer : Cancel ( ) end
verTimer = CTimerNewTicker ( 3 , function ( )
hasWarned = 1
verTimer = nil
sysprint ( L.getNewRelease )
end , 1 )
end
end
local function printGuildOutOfDate ( tbl )
if hasGuildWarned then return end
local warnedOutOfDate = 0
for k , v in next , tbl do
if v > BIGWIGS_GUILD_VERSION and usersGuildName [ k ] == customGuildName then
warnedOutOfDate = warnedOutOfDate + 1
end
end
if warnedOutOfDate > 1 and not hasGuildWarned then
if verGuildTimer then verGuildTimer : Cancel ( ) end
verGuildTimer = CTimerNewTicker ( 3 , function ( )
hasGuildWarned = true
verGuildTimer = nil
sysprint ( guildWarnMessage )
Popup ( guildWarnMessage )
end , 1 )
end
end
function mod : VersionCheck ( prefix , verString , hash , guildVerString , guildName , sender )
if prefix == " Q " then
if timer then timer : Cancel ( ) end
timer = CTimerNewTicker ( 3 , sendMsg , 1 )
end
if prefix == " V " or prefix == " Q " then -- V = version response, Q = version query
local version = tonumber ( verString )
if version and version > 0 then -- Allow addons to query BigWigs versions by using a version of 0, but don't add them to the user list.
usersVersion [ sender ] = version
usersHash [ sender ] = hash
if version > highestFoundVersion then highestFoundVersion = version end
local guildVersion = tonumber ( guildVerString )
if guildVersion and guildVersion > 0 then
usersGuildVersion [ sender ] = guildVersion
usersGuildName [ sender ] = guildName
if customGuildName and customGuildName == guildName then
if guildVersion > highestFoundGuildVersion then
highestFoundGuildVersion = guildVersion
end
if guildVersion > BIGWIGS_GUILD_VERSION then
printGuildOutOfDate ( usersGuildVersion )
end
end
end
if version > BIGWIGS_VERSION then
printOutOfDate ( usersVersion )
end
end
end
end
end
do
local warnedThisZone = { }
function mod : PLAYER_ENTERING_WORLD ( ) -- Raid bosses
-- Zone checking
local _ , _ , _ , _ , _ , _ , _ , id = GetInstanceInfo ( )
-- Module loading
if enableZones [ id ] then
if loadAndEnableCore ( ) then
loadZone ( id )
end
elseif BigWigs3DB and BigWigs3DB.breakTime then -- Break timer restoration
loadAndEnableCore ( )
else
if disabledZones and disabledZones [ id ] then -- We have content for the zone but it is disabled in the addons menu
local msg = L.disabledAddOn : format ( disabledZones [ id ] )
sysprint ( msg )
Popup ( msg )
-- Only print once
warnedThisZone [ id ] = true
disabledZones [ id ] = nil
end
end
-- Lacking zone modules
if ( BigWigs and BigWigs.db . profile.showZoneMessages == false ) or self.isShowingZoneMessages == false then return end
local zoneAddon = public.zoneTbl [ id ]
if zoneAddon and zoneAddon ~= " BigWigs_Shadowlands " then
if strfind ( zoneAddon , " LittleWigs_ " , nil , true ) then zoneAddon = " LittleWigs " end -- Collapse into one addon
if id > 0 and not fakeZones [ id ] and not warnedThisZone [ id ] and not IsAddOnEnabled ( zoneAddon ) then
warnedThisZone [ id ] = true
local msg = L.missingAddOn : format ( zoneAddon )
sysprint ( msg )
RaidNotice_AddMessage ( RaidWarningFrame , msg , { r = 1 , g = 1 , b = 1 } , 15 )
end
end
end
end
do
function mod : UNIT_TARGET ( unit )
local unitTarget = unit .. " target "
local guid = UnitGUID ( unitTarget )
if guid then
local _ , _ , _ , _ , _ , mobId = strsplit ( " - " , guid )
mobId = tonumber ( mobId )
local id = mobId and worldBosses [ mobId ]
if id and loadAndEnableCore ( ) then
loadZone ( id )
BigWigs : Enable ( unitTarget )
end
end
end
function mod : ZONE_CHANGED ( ) -- For world bosses, not useful for raids as it fires after loading has ended
local id = 0
local mapId = GetBestMapForUnit ( " player " )
if mapId then
id = - mapId -- Use map id for world bosses
end
-- Module loading
if enableZones [ id ] == " world " then
bwFrame : RegisterEvent ( " UNIT_TARGET " )
else
bwFrame : UnregisterEvent ( " UNIT_TARGET " )
end
end
end
do
local grouped = nil
function mod : GROUP_ROSTER_UPDATE ( )
local groupType = ( IsInGroup ( 2 ) and 3 ) or ( IsInRaid ( ) and 2 ) or ( IsInGroup ( ) and 1 ) -- LE_PARTY_CATEGORY_INSTANCE = 2
if ( not grouped and groupType ) or ( grouped and groupType and grouped ~= groupType ) then
grouped = groupType
SendAddonMessage ( " BigWigs " , versionQueryString , groupType == 3 and " INSTANCE_CHAT " or " RAID " )
SendAddonMessage ( " D4 " , " H \t " , groupType == 3 and " INSTANCE_CHAT " or " RAID " ) -- Also request DBM versions
self : ACTIVE_TALENT_GROUP_CHANGED ( ) -- Force role check
elseif grouped and not groupType then
grouped = nil
ResetVersionWarning ( )
usersVersion = { }
usersHash = { }
end
end
end
function mod : BigWigs_BossModuleRegistered ( _ , _ , module )
if module.worldBoss then
local id = - ( module.mapId )
enableZones [ id ] = " world "
worldBosses [ module.worldBoss ] = id
else
enableZones [ module.instanceId ] = true
end
local id = module.otherMenu or module.instanceId or - ( module.mapId )
if type ( menus [ id ] ) ~= " table " then menus [ id ] = { } end
menus [ id ] [ # menus [ id ] + 1 ] = module
end
public.RegisterMessage ( mod , " BigWigs_BossModuleRegistered " )
function mod : BigWigs_CoreEnabled ( )
dataBroker.icon = " Interface \\ AddOns \\ BigWigs \\ Media \\ Icons \\ core-enabled "
-- Send a version query on enable, should fix issues with joining a group then zoning into an instance,
-- which kills your ability to receive addon comms during the loading process.
if IsInGroup ( ) then
SendAddonMessage ( " BigWigs " , versionQueryString , IsInGroup ( 2 ) and " INSTANCE_CHAT " or " RAID " )
SendAddonMessage ( " D4 " , " H \t " , IsInGroup ( 2 ) and " INSTANCE_CHAT " or " RAID " ) -- Also request DBM versions
end
-- Core is loaded, nil these to force checking BigWigs.db.profile.option
self.isFakingDBM = nil
self.isShowingZoneMessages = nil
self.isSoundOn = nil
end
public.RegisterMessage ( mod , " BigWigs_CoreEnabled " )
function mod : BigWigs_CoreDisabled ( )
dataBroker.icon = " Interface \\ AddOns \\ BigWigs \\ Media \\ Icons \\ core-disabled "
end
public.RegisterMessage ( mod , " BigWigs_CoreDisabled " )
-----------------------------------------------------------------------
-- API
--
function public : RegisterTooltipInfo ( func )
for i = 1 , # tooltipFunctions do
if tooltipFunctions [ i ] == func then
error ( ( " The function %q has already been registered. " ) : format ( func ) )
end
end
tooltipFunctions [ # tooltipFunctions + 1 ] = func
end
function public : GetReleaseString ( )
return BIGWIGS_RELEASE_STRING
end
function public : GetVersionString ( )
return BIGWIGS_VERSION_STRING
end
function public : GetZoneMenus ( )
return menus
end
function public : LoadZone ( zone )
loadZone ( zone )
end
-----------------------------------------------------------------------
-- Slash commands
--
SLASH_BigWigs1 = " /bw "
SLASH_BigWigs2 = " /bigwigs "
SlashCmdList.BigWigs = function ( )
-- If you are a dev and need the BigWigs options loaded to do something, please come talk to us on Discord about your use case
--local trace = debugstack(2)
--if strfind(trace, "[string \"*:OnEnterPressed\"]:1: in function <[string \"*:OnEnterPressed\"]:1>", nil, true) then
loadCoreAndOpenOptions ( )
--else
-- public.stack = trace
-- sysprint("|cFFff0000WARNING!|r")
-- sysprint("One of your addons was prevented from force loading the BigWigs options.")
-- sysprint("Contact us on the BigWigs Discord about this, it should not be happening.")
-- return
--end
end
SLASH_BigWigsVersion1 = " /bwv "
SlashCmdList.BigWigsVersion = function ( )
if not IsInGroup ( ) then
sysprint ( BIGWIGS_RELEASE_STRING )
return
end
local function coloredNameVersion ( name , version , hash , guildVersion )
if not version then
version = " "
elseif guildVersion then
version = ( " |cFFCCCCCC(%d/%d%s)|r " ) : format ( guildVersion , version , hash and " - " .. hash or " " ) -- %d because BigWigs versions are always stored as a number
else
version = ( " |cFFCCCCCC(%s%s)|r " ) : format ( version , hash and " - " .. hash or " " ) -- %s because DBM users are stored as a string
end
local _ , class = UnitClass ( name )
local tbl = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS [ class ] or RAID_CLASS_COLORS [ class ] or GRAY_FONT_COLOR
name = name : gsub ( " %-.+ " , " * " ) -- Replace server names with *
return ( " |cFF%02x%02x%02x%s|r%s " ) : format ( tbl.r * 255 , tbl.g * 255 , tbl.b * 255 , name , version )
end
local list = { }
local unit
if not IsInRaid ( ) then
list [ 1 ] = UnitName ( " player " )
unit = " party%d "
else
unit = " raid%d "
end
for i = 1 , GetNumGroupMembers ( ) do
local n , s = UnitName ( ( unit ) : format ( i ) )
if n and s and s ~= " " then n = n .. " - " .. s end
if n then list [ # list + 1 ] = n end
end
local good = { } -- highest release users
local ugly = { } -- old version users
local bad = { } -- no boss mod
local dbm = { } -- DBM users
for i = 1 , # list do
local player = list [ i ]
local usesBossMod = nil
if usersVersion [ player ] then
usesBossMod = true
if customGuildName == usersGuildName [ player ] then
if usersGuildVersion [ player ] < highestFoundGuildVersion then
ugly [ # ugly + 1 ] = coloredNameVersion ( player , usersVersion [ player ] , usersHash [ player ] , usersGuildVersion [ player ] )
else
good [ # good + 1 ] = coloredNameVersion ( player , usersVersion [ player ] , usersHash [ player ] , usersGuildVersion [ player ] )
end
else
if usersVersion [ player ] < highestFoundVersion then
ugly [ # ugly + 1 ] = coloredNameVersion ( player , usersVersion [ player ] , usersHash [ player ] )
else
good [ # good + 1 ] = coloredNameVersion ( player , usersVersion [ player ] , usersHash [ player ] )
end
end
end
if usersDBM [ player ] then
dbm [ # dbm + 1 ] = coloredNameVersion ( player , usersDBM [ player ] )
usesBossMod = true
end
if not usesBossMod then
bad [ # bad + 1 ] = coloredNameVersion ( player , UnitIsConnected ( player ) == false and L.offline )
end
end
if # good > 0 then print ( L.upToDate , unpack ( good ) ) end
if # ugly > 0 then print ( L.outOfDate , unpack ( ugly ) ) end
if # dbm > 0 then print ( L.dbmUsers , unpack ( dbm ) ) end
if # bad > 0 then print ( L.noBossMod , unpack ( bad ) ) end
end
-------------------------------------------------------------------------------
-- Global
--
BigWigsLoader = setmetatable ( { } , { __index = public , __newindex = function ( ) end , __metatable = false } )