annotate CrossRealmAssist.lua @ 12:0deef890ec99

Updated version
author ShadowTheAge
date Wed, 11 Mar 2015 22:51:00 +0300
parents 421508c17712
children 1f68e8154947
rev   line source
ShadowTheAge@0 1 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0")
ShadowTheAge@0 2 local addon = CrossRealmAssist;
ShadowTheAge@0 3 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library()
ShadowTheAge@12 4 local ScrollingTable = LibStub("ScrollingTable");
ShadowTheAge@0 5
ShadowTheAge@12 6 local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle
ShadowTheAge@0 7
ShadowTheAge@12 8 local tabs = {}
ShadowTheAge@11 9 local curRealmStat
ShadowTheAge@0 10 local scanstate=0
ShadowTheAge@0 11 local recentRealms={}
ShadowTheAge@12 12 local recentgroups={}
ShadowTheAge@0 13 local active=false
ShadowTheAge@0 14
ShadowTheAge@0 15 local lfgGroups={
ShadowTheAge@0 16 6, -- Custom
ShadowTheAge@0 17 10, -- Ashran
ShadowTheAge@0 18 1, -- Quests
ShadowTheAge@12 19 3 -- Raids
ShadowTheAge@0 20 }
ShadowTheAge@0 21
ShadowTheAge@12 22 local StatusTable = {
ShadowTheAge@12 23 ["invited"]="Invited",
ShadowTheAge@12 24 ["declined"]="Declined",
ShadowTheAge@12 25 ["timedout"]="Timed out",
ShadowTheAge@12 26 ["applied"]="Applied",
ShadowTheAge@12 27 ["cancelled"]="Join cancelled",
ShadowTheAge@12 28 ["inviteaccepted"]="Joined",
ShadowTheAge@12 29 ["_init"]="Join request"
ShadowTheAge@12 30 }
ShadowTheAge@12 31
ShadowTheAge@0 32 local curLfgGroup
ShadowTheAge@0 33 local sheduledScan
ShadowTheAge@0 34 local wasInGroup
ShadowTheAge@12 35 local inInstance
ShadowTheAge@12 36
ShadowTheAge@12 37
ShadowTheAge@12 38 -- Utils functions
ShadowTheAge@12 39
ShadowTheAge@12 40 local function PlayerName(fullname)
ShadowTheAge@12 41 fullname = fullname or "???-???"
ShadowTheAge@12 42 local name, realm = strsplit(realmSep, fullname)
ShadowTheAge@12 43 realm = realm or homeRealm;
ShadowTheAge@12 44 return name, realm;
ShadowTheAge@12 45 end
ShadowTheAge@12 46
ShadowTheAge@12 47 local function canJoinGroup()
ShadowTheAge@12 48 return (not IsInGroup()) or (UnitIsGroupLeader('player') and not IsInRaid())
ShadowTheAge@12 49 end
ShadowTheAge@12 50
ShadowTheAge@12 51 local function sortByWeight(a,b)
ShadowTheAge@12 52 return b.weight < a.weight
ShadowTheAge@12 53 end
ShadowTheAge@12 54
ShadowTheAge@12 55
ShadowTheAge@12 56 -- UI functions
ShadowTheAge@12 57
ShadowTheAge@12 58 local function createIcon(owner, icon, id)
ShadowTheAge@12 59 local image = owner:CreateTexture(nil, "BACKGROUND")
ShadowTheAge@12 60 image:SetWidth(16)
ShadowTheAge@12 61 image:SetHeight(16)
ShadowTheAge@12 62 image:SetTexture(icon)
ShadowTheAge@12 63 image:SetPoint("TOPLEFT",owner,"TOPLEFT",id*16,0)
ShadowTheAge@12 64 return image
ShadowTheAge@12 65 end
ShadowTheAge@0 66
ShadowTheAge@11 67 local function setupWidget(widget, parameters, x, y)
ShadowTheAge@11 68 if parameters then
ShadowTheAge@11 69 for key,value in pairs(parameters) do widget[key](widget,value) end
ShadowTheAge@11 70 end
ShadowTheAge@11 71 if y then
ShadowTheAge@11 72 widget:SetPoint("TOPLEFT",widget:GetParent(),"TOPLEFT",x,-y)
ShadowTheAge@11 73 end
ShadowTheAge@11 74 return widget
ShadowTheAge@11 75 end
ShadowTheAge@11 76
ShadowTheAge@11 77 local function ShowTooltip(widget)
ShadowTheAge@11 78 GameTooltip:SetOwner(widget, widget.TooltipAnchor)
ShadowTheAge@11 79 GameTooltip:ClearLines()
ShadowTheAge@11 80 widget:TooltipFactory()
ShadowTheAge@11 81 GameTooltip:Show()
ShadowTheAge@11 82 end
ShadowTheAge@11 83
ShadowTheAge@11 84 local function HideTooltip(widget)
ShadowTheAge@11 85 GameTooltip:Hide()
ShadowTheAge@11 86 end
ShadowTheAge@11 87
ShadowTheAge@11 88 local function setupTooltip(widget, anchor, factory)
ShadowTheAge@11 89 widget.TooltipAnchor = anchor;
ShadowTheAge@11 90 widget.TooltipFactory = factory;
ShadowTheAge@11 91 widget:SetScript("OnEnter", ShowTooltip)
ShadowTheAge@11 92 widget:SetScript("OnLeave", HideTooltip)
ShadowTheAge@11 93 end
ShadowTheAge@11 94
ShadowTheAge@12 95 local function SelectLfgTab(tab)
ShadowTheAge@12 96 PanelTemplates_DeselectTab(lfgTabSelected)
ShadowTheAge@12 97 lfgTabSelected = tab
ShadowTheAge@12 98 addon.LfgScan(tab.searchID)
ShadowTheAge@12 99 PanelTemplates_SelectTab(lfgTabSelected)
ShadowTheAge@12 100 end
ShadowTheAge@0 101
ShadowTheAge@12 102 local function realmToolip()
ShadowTheAge@12 103 if not curRealmStat then return end
ShadowTheAge@12 104 local players = curRealmStat.players;
ShadowTheAge@12 105 local threshold = curRealmStat.threshold
ShadowTheAge@12 106 GameTooltip:AddLine("Players in zone: "..players)
ShadowTheAge@12 107 if not curRealmStat.complete then
ShadowTheAge@12 108 GameTooltip:AppendText("+")
ShadowTheAge@12 109 end
ShadowTheAge@12 110 for i=1,curRealmStat.realms do
ShadowTheAge@12 111 local data = curRealmStat[i]
ShadowTheAge@12 112 local percent = math.ceil(100 * data.count / players - 0.5) .. "%";
ShadowTheAge@12 113 if data.count >= threshold then
ShadowTheAge@12 114 GameTooltip:AddDoubleLine(data.realm, percent, 0,1,0,0,1,0)
ShadowTheAge@12 115 else
ShadowTheAge@12 116 GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5)
ShadowTheAge@12 117 end
ShadowTheAge@12 118 end
ShadowTheAge@0 119 end
ShadowTheAge@0 120
ShadowTheAge@12 121
ShadowTheAge@12 122
ShadowTheAge@12 123
ShadowTheAge@12 124
ShadowTheAge@12 125
ShadowTheAge@12 126
ShadowTheAge@12 127 -- LFG list data providers, filters and tooltips
ShadowTheAge@12 128
ShadowTheAge@12 129 local lfgScanInProgress=false
ShadowTheAge@12 130 local hasLfgListChanges=false
ShadowTheAge@12 131
ShadowTheAge@12 132 local function addTooltipLineIcon(predicat, text, icon, r, g, b, wrap)
ShadowTheAge@12 133 if predicat then
ShadowTheAge@12 134 GameTooltip:AddLine(text, r, g, b, wrap)
ShadowTheAge@12 135 if icon then GameTooltip:AddTexture(icon) end
ShadowTheAge@12 136 end
ShadowTheAge@12 137 end
ShadowTheAge@12 138
ShadowTheAge@12 139 local function WeightLfgItem(id, forAutoJoin)
ShadowTheAge@12 140 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(id)
ShadowTheAge@12 141 if delisted then return 0 end
ShadowTheAge@12 142 local name,realm = PlayerName(fullname);
ShadowTheAge@12 143 if forAutoJoin then
ShadowTheAge@12 144 if not autoinv or pcount >= 35 or pcount <= 5 or recentgroups[fullname] then return 0 end
ShadowTheAge@12 145 end
ShadowTheAge@12 146
ShadowTheAge@12 147 local autoinvWeight = autoinv and 5 or 2
ShadowTheAge@12 148
ShadowTheAge@12 149 local visCoef = 1
ShadowTheAge@12 150 if recentgroups[fullname] then
ShadowTheAge@12 151 local ago = GetTime() - recentgroups[fullname].time;
ShadowTheAge@12 152 visCoef = math.min(1,ago/600)
ShadowTheAge@12 153 end
ShadowTheAge@12 154
ShadowTheAge@12 155 local leaderRealm = 3 -- recently visited realms
ShadowTheAge@12 156 if (realm ~= "???") then leaderRealm = (5 - (recentRealms[realm] or 0)) end
ShadowTheAge@12 157
ShadowTheAge@12 158 local countWeight = 4 -- count weight
ShadowTheAge@12 159 if pcount >= 39 or pcount <= 1 then countWeight = 1
ShadowTheAge@12 160 elseif pcount >= 35 or pcount <= 4 then countWeight = 2
ShadowTheAge@12 161 elseif pcount >= 30 or pcount <= 10 then countWeight = 3
ShadowTheAge@12 162 else countWeight = 4 end
ShadowTheAge@12 163
ShadowTheAge@12 164 local ageWeight = 2
ShadowTheAge@12 165 if time > 1200 then ageWeight = 4
ShadowTheAge@12 166 elseif time > 300 then ageWeight = 3 end
ShadowTheAge@12 167
ShadowTheAge@12 168 return leaderRealm * countWeight * visCoef * autoinvWeight * ageWeight;
ShadowTheAge@12 169 end
ShadowTheAge@12 170
ShadowTheAge@12 171 local function ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
ShadowTheAge@12 172 if not realrow then return end
ShadowTheAge@12 173 local rowdata = scrollingTable:GetRow(realrow);
ShadowTheAge@12 174 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rowdata.id)
ShadowTheAge@12 175 local friends = bnetfr+charfr+guild
ShadowTheAge@12 176 GameTooltip:SetOwner(rowFrame, "ANCHOR_BOTTOMLEFT",-10,25)
ShadowTheAge@12 177 GameTooltip:ClearLines()
ShadowTheAge@12 178 GameTooltip:AddLine(caption,1,1,1)
ShadowTheAge@12 179 addTooltipLineIcon(desc ~= "", desc, nil, 0.5, 0.5, 0.5, true)
ShadowTheAge@12 180 local name, realm = PlayerName(fullname)
ShadowTheAge@12 181 GameTooltip:AddDoubleLine("Leader:",name)
ShadowTheAge@12 182 GameTooltip:AddDoubleLine("Leader realm:",realm)
ShadowTheAge@12 183 GameTooltip:AddLine(" ")
ShadowTheAge@12 184 GameTooltip:AddDoubleLine("Players:",pcount)
ShadowTheAge@12 185 addTooltipLineIcon(ilvl > 0, "Min. ilvl: "..ilvl, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
ShadowTheAge@12 186 addTooltipLineIcon(voice ~= "", "Voice: "..voice, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
ShadowTheAge@12 187 addTooltipLineIcon(friends > 0, "Friends: "..friends, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
ShadowTheAge@12 188 addTooltipLineIcon(autoinv, "Autoinvite!", READY_CHECK_READY_TEXTURE, 0, 1, 0)
ShadowTheAge@12 189 local visitinfo = recentgroups[fullname]
ShadowTheAge@12 190 if visitinfo then
ShadowTheAge@12 191 local ago = GetTime() - visitinfo.time;
ShadowTheAge@12 192 GameTooltip:AddDoubleLine(StatusTable[visitinfo.status] or visitinfo.status,SecondsToTime(ago, false, false, 1, false).." ago",1,0,0,1,0,0)
ShadowTheAge@12 193 GameTooltip:AddTexture(READY_CHECK_NOT_READY_TEXTURE)
ShadowTheAge@12 194 end
ShadowTheAge@12 195 GameTooltip:Show()
ShadowTheAge@12 196 end
ShadowTheAge@12 197
ShadowTheAge@12 198 local function updateTableData(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...)
ShadowTheAge@12 199 if fShow then
ShadowTheAge@12 200 local rowdata = table:GetRow(realrow);
ShadowTheAge@12 201 local icons = cellFrame.icons
ShadowTheAge@12 202 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rowdata.id)
ShadowTheAge@12 203 if not icons then
ShadowTheAge@12 204 local miscdata = createIcon(cellFrame,READY_CHECK_WAITING_TEXTURE,0)
ShadowTheAge@12 205 local autoinv = createIcon(cellFrame,READY_CHECK_READY_TEXTURE, 1)
ShadowTheAge@12 206 local visited = createIcon(cellFrame,READY_CHECK_NOT_READY_TEXTURE, 2)
ShadowTheAge@12 207 icons = {misc=miscdata, autoinv=autoinv, visited=visited}
ShadowTheAge@12 208 cellFrame.icons = icons
ShadowTheAge@12 209 end
ShadowTheAge@12 210 icons.misc:SetShown(voice ~= "" or bnetfr > 0 or charfr > 0 or guild > 0 or ilvl > 0)
ShadowTheAge@12 211 icons.autoinv:SetShown(autoinv)
ShadowTheAge@12 212 icons.visited:SetShown(recentgroups[fullname])
ShadowTheAge@12 213 if GameTooltip:GetOwner() == rowFrame then ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, table) end
ShadowTheAge@12 214 end
ShadowTheAge@12 215 end
ShadowTheAge@12 216
ShadowTheAge@12 217 local function updateGroupName(id)
ShadowTheAge@12 218 return select(3, C_LFGList.GetSearchResultInfo(id))
ShadowTheAge@12 219 end
ShadowTheAge@12 220
ShadowTheAge@12 221 local function updateGroupCount(id)
ShadowTheAge@12 222 return select(13, C_LFGList.GetSearchResultInfo(id))
ShadowTheAge@12 223 end
ShadowTheAge@12 224
ShadowTheAge@12 225 local function updateGroupRealm(id)
ShadowTheAge@12 226 local name = select(12, C_LFGList.GetSearchResultInfo(id))
ShadowTheAge@12 227 local pname, realm = PlayerName(name);
ShadowTheAge@12 228 return realm
ShadowTheAge@12 229 end
ShadowTheAge@12 230
ShadowTheAge@12 231 local function filterTable(self, row)
ShadowTheAge@12 232 local delisted = select(11, C_LFGList.GetSearchResultInfo(row.id))
ShadowTheAge@12 233 return not delisted;
ShadowTheAge@12 234 end
ShadowTheAge@12 235
ShadowTheAge@12 236 function addon:UpdateResponseData(event, result)
ShadowTheAge@12 237 if select(11, C_LFGList.GetSearchResultInfo(result)) then
ShadowTheAge@12 238 lfgTable:SetFilter(filterTable)
ShadowTheAge@12 239 end
ShadowTheAge@12 240 hasLfgListChanges = true
ShadowTheAge@12 241 end
ShadowTheAge@12 242
ShadowTheAge@12 243 local function refreshLFGList()
ShadowTheAge@12 244 if lfgScanInProgress or not lfgTable then return end
ShadowTheAge@12 245 local count, list = C_LFGList.GetSearchResults()
ShadowTheAge@12 246 local tableData = {}
ShadowTheAge@12 247 for i = 1,count do
ShadowTheAge@12 248 local rid = list[i];
ShadowTheAge@12 249 if not rid then break end
ShadowTheAge@12 250 local data = list[i];
ShadowTheAge@12 251 local cols = {}
ShadowTheAge@12 252 local row = {rid}
ShadowTheAge@12 253 cols[1] = {value=updateGroupName,args=row}
ShadowTheAge@12 254 cols[2] = {value=updateGroupCount,args=row}
ShadowTheAge@12 255 cols[3] = {value=updateGroupRealm,args=row}
ShadowTheAge@12 256 cols[4] = {}
ShadowTheAge@12 257 table.insert(tableData, {cols=cols,id=rid,weight=WeightLfgItem(rid)})
ShadowTheAge@12 258 end
ShadowTheAge@12 259 table.sort(tableData, sortByWeight);
ShadowTheAge@12 260 lfgTable:SetData(tableData)
ShadowTheAge@12 261 end
ShadowTheAge@12 262
ShadowTheAge@12 263 local function JoinGroup(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
ShadowTheAge@12 264 if not realrow or not canJoinGroup() then return end
ShadowTheAge@12 265 local rowdata = scrollingTable:GetRow(realrow);
ShadowTheAge@12 266 local tank, heal, dd = C_LFGList.GetAvailableRoles()
ShadowTheAge@12 267 addon:SetGroupJoinStatus(rowdata.id, "_init")
ShadowTheAge@12 268 C_LFGList.ApplyToGroup(rowdata.id, "", tank, heal, dd)
ShadowTheAge@12 269 end
ShadowTheAge@12 270
ShadowTheAge@12 271
ShadowTheAge@12 272
ShadowTheAge@12 273
ShadowTheAge@12 274
ShadowTheAge@12 275
ShadowTheAge@12 276 -- Addon functions and gui constructors
ShadowTheAge@12 277
ShadowTheAge@0 278 function addon:OnEnable()
ShadowTheAge@0 279 local tabCount = table.getn(lfgGroups)
ShadowTheAge@0 280 realmSep = _G.REALM_SEPARATORS
ShadowTheAge@11 281 playerName = UnitName("player")
ShadowTheAge@0 282 homeRealm = GetRealmName()
ShadowTheAge@0 283 addon:RegisterChatCommand("cra", "Activate")
ShadowTheAge@0 284 addon:RegisterChatCommand("crossrealmassist", "Activate")
ShadowTheAge@11 285
ShadowTheAge@11 286 addon:ScheduleTimer("Activate", 0.5)
ShadowTheAge@0 287 end
ShadowTheAge@0 288
ShadowTheAge@0 289 function addon:OnDisable()
ShadowTheAge@0 290 addon:Deactivate()
ShadowTheAge@0 291 end
ShadowTheAge@0 292
ShadowTheAge@0 293 function addon:Activate()
ShadowTheAge@0 294 if active then return end
ShadowTheAge@0 295 active=true
ShadowTheAge@0 296 wasInGroup = IsInGroup()
ShadowTheAge@11 297 if not gui then addon:CreateUI() end
ShadowTheAge@11 298 addon:updateCurrentRealm();
ShadowTheAge@11 299 addon:ForceRefreshZone();
ShadowTheAge@11 300 gui:Show()
ShadowTheAge@11 301 addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "ForceRefreshZone")
ShadowTheAge@11 302 addon:RegisterEvent("SCENARIO_UPDATE", "ForceRefreshZone")
ShadowTheAge@12 303 addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData")
ShadowTheAge@12 304 addon:RegisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED", "UpdateResponseData")
ShadowTheAge@12 305 addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed")
ShadowTheAge@12 306 addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo")
ShadowTheAge@12 307 addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus")
ShadowTheAge@12 308 addon.LfgScan(lfgGroups[1])
ShadowTheAge@0 309 end
ShadowTheAge@0 310
ShadowTheAge@0 311 function addon:Deactivate()
ShadowTheAge@0 312 if not active then return end
ShadowTheAge@0 313 active = false
ShadowTheAge@12 314 gui:Hide()
ShadowTheAge@12 315 if lfgui then lfgui:Hide() end
ShadowTheAge@0 316 scanstate = 0
ShadowTheAge@0 317 lfgScanInProgress = false
ShadowTheAge@0 318 addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
ShadowTheAge@0 319 addon:UnregisterEvent("PLAYER_REGEN_ENABLED")
ShadowTheAge@0 320 addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED")
ShadowTheAge@12 321 addon:UnregisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED")
ShadowTheAge@0 322 addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED")
ShadowTheAge@0 323 addon:UnregisterEvent("GROUP_ROSTER_UPDATE")
ShadowTheAge@0 324 addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED")
ShadowTheAge@0 325 end
ShadowTheAge@0 326
ShadowTheAge@11 327 function addon:SetStatus(status)
ShadowTheAge@11 328 if status then
ShadowTheAge@11 329 lbStatus:SetText(status)
ShadowTheAge@11 330 else
ShadowTheAge@11 331 lbStatus:SetText("") -- TODO
ShadowTheAge@11 332 end
ShadowTheAge@11 333 end
ShadowTheAge@11 334
ShadowTheAge@0 335 function addon:CreateUI()
ShadowTheAge@12 336 gui = setupWidget(CreateFrame("Frame","CrossRealmAssistMainUI",nil,"InsetFrameTemplate3"), {SetFrameStrata="LOW",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true})
ShadowTheAge@11 337 local title = setupWidget(CreateFrame("Frame",nil,gui), {SetWidth=190,SetHeight=18,EnableMouse=true,RegisterForDrag="LeftButton"}, 0, 6);
ShadowTheAge@11 338 title:SetScript("OnDragStart", function() gui:StartMoving() end)
ShadowTheAge@11 339 title:SetScript("OnDragStop", function() gui:StopMovingOrSizing() end)
ShadowTheAge@11 340 gui:SetScript("OnHide", addon.Deactivate)
ShadowTheAge@12 341 setupTooltip(title, "ANCHOR_TOP", realmToolip)
ShadowTheAge@11 342
ShadowTheAge@11 343 lbRealm = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontNormal"), {SetWidth=200,SetHeight=18}, 0, 6)
ShadowTheAge@11 344 lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23)
ShadowTheAge@11 345
ShadowTheAge@12 346 btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Quick join"},4,36)
ShadowTheAge@12 347 btQuick:SetScript("OnClick",addon.DoAutoAction)
ShadowTheAge@12 348 btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Manual join"},94,36)
ShadowTheAge@12 349 btManual:SetScript("OnClick",addon.ShowManualLfg)
ShadowTheAge@11 350 setupWidget(CreateFrame("Button",nil,gui,"UIPanelCloseButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},188,0)
ShadowTheAge@11 351
ShadowTheAge@12 352 btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,36)
ShadowTheAge@11 353 btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
ShadowTheAge@11 354 btRefresh.icon:SetTexCoord(0,1,0,1);
ShadowTheAge@11 355 btRefresh:SetScript("OnClick",addon.RefreshZone)
ShadowTheAge@11 356
ShadowTheAge@11 357 gui:SetPoint("CENTER",0,0)
ShadowTheAge@12 358 addon:UpdateAutoButtonStatus()
ShadowTheAge@12 359 end
ShadowTheAge@11 360
ShadowTheAge@12 361 function addon:ShowManualLfg()
ShadowTheAge@12 362 if not lfgui then addon:CreateLFGUI() end
ShadowTheAge@12 363 lfgui:Show()
ShadowTheAge@12 364 end
ShadowTheAge@0 365
ShadowTheAge@12 366 function addon.lfgUpdate()
ShadowTheAge@12 367 if hasLfgListChanges then
ShadowTheAge@12 368 lfgTable:Refresh()
ShadowTheAge@12 369 hasLfgListChanges = false
ShadowTheAge@12 370 end
ShadowTheAge@12 371 end
ShadowTheAge@0 372
ShadowTheAge@12 373 function addon:CreateLFGUI()
ShadowTheAge@12 374 lfgui = setupWidget(CreateFrame("Frame","CrossRealmAssistJoinUI",nil,"UIPanelDialogTemplate"), {SetFrameStrata="DIALOG",SetWidth=405,SetHeight=300,EnableMouse=true,SetMovable=true})
ShadowTheAge@12 375 lfgui.title:SetText("Click to join group")
ShadowTheAge@12 376 lfgui:SetScript("OnUpdate",addon.lfgUpdate)
ShadowTheAge@12 377 local titlereg = lfgui:CreateTitleRegion()
ShadowTheAge@12 378 titlereg:SetAllPoints(lfgui.title)
ShadowTheAge@12 379 addon:CreateTabs()
ShadowTheAge@0 380
ShadowTheAge@12 381 lfgTable = ScrollingTable:CreateST({
ShadowTheAge@12 382 {name="Title",width=160},
ShadowTheAge@12 383 {name="#",width=30,align="CENTER"},
ShadowTheAge@12 384 {name="Realm",width=120,align="RIGHT"},
ShadowTheAge@12 385 {name="",width=50,DoCellUpdate=updateTableData}
ShadowTheAge@12 386 },15,16,nil,lfgui);
ShadowTheAge@0 387
ShadowTheAge@12 388 lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=JoinGroup})
ShadowTheAge@0 389
ShadowTheAge@12 390 setupWidget(lfgTable.frame, nil, 10, 45);
ShadowTheAge@12 391 lfgTable.frame:SetBackdrop(nil)
ShadowTheAge@12 392 lfgui:SetPoint("CENTER",0,0)
ShadowTheAge@12 393 refreshLFGList()
ShadowTheAge@0 394
ShadowTheAge@12 395 lbThrottle = setupWidget(lfgui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmall"), {SetWidth=300}, 50, 100)
ShadowTheAge@12 396 lbThrottle:Hide();
ShadowTheAge@0 397
ShadowTheAge@12 398 local btRefresh = setupWidget(CreateFrame("Button",nil,lfgui,"UIPanelSquareButton"),{SetWidth=22,SetHeight=22},379,27)
ShadowTheAge@12 399 btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
ShadowTheAge@12 400 btRefresh.icon:SetTexCoord(0,1,0,1);
ShadowTheAge@12 401 btRefresh:SetScript("OnClick",addon.refreshLfgCurrent)
ShadowTheAge@12 402 end
ShadowTheAge@0 403
ShadowTheAge@12 404 function addon:CreateTabs()
ShadowTheAge@12 405 local prevTab
ShadowTheAge@12 406 for i=1,#lfgGroups do
ShadowTheAge@12 407 local tab = CreateFrame("Button","$parentTab"..i,lfgui,"CharacterFrameTabButtonTemplate")
ShadowTheAge@12 408 tab:SetText((C_LFGList.GetCategoryInfo(lfgGroups[i])));
ShadowTheAge@12 409 tab.searchID = lfgGroups[i];
ShadowTheAge@12 410 tab:SetID(i);
ShadowTheAge@12 411 PanelTemplates_TabResize(tab, 0)
ShadowTheAge@12 412 if i == 1 then
ShadowTheAge@12 413 tab:SetPoint("TOPLEFT", lfgui, "BOTTOMLEFT", 10, 7)
ShadowTheAge@12 414 lfgTabSelected = tab
ShadowTheAge@12 415 PanelTemplates_SelectTab(tab)
ShadowTheAge@12 416 else
ShadowTheAge@12 417 tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0)
ShadowTheAge@12 418 PanelTemplates_DeselectTab(tab)
ShadowTheAge@12 419 end
ShadowTheAge@12 420 tab:SetScript("OnClick", SelectLfgTab)
ShadowTheAge@12 421 tabs[i] = tab
ShadowTheAge@12 422 prevTab = tab
ShadowTheAge@12 423 end
ShadowTheAge@0 424 end
ShadowTheAge@0 425
ShadowTheAge@0 426 -- LFG scanning routine
ShadowTheAge@0 427
ShadowTheAge@12 428 function addon.refreshLfgCurrent()
ShadowTheAge@12 429 addon.LfgScan(curLfgGroup)
ShadowTheAge@0 430 end
ShadowTheAge@0 431
ShadowTheAge@12 432 function addon.LfgScan(group)
ShadowTheAge@12 433 if lfgTable then lfgTable:SetData({}) end
ShadowTheAge@0 434 lfgScanInProgress = true
ShadowTheAge@12 435 curLfgGroup = group
ShadowTheAge@0 436 C_LFGList.Search(curLfgGroup,"")
ShadowTheAge@0 437 end
ShadowTheAge@0 438
ShadowTheAge@0 439 function addon:LfgScanFailed(event, reason)
ShadowTheAge@0 440 if reason == "throttled" then
ShadowTheAge@12 441 addon:ScheduleTimer(addon.LfgScan, 2, curLfgGroup)
ShadowTheAge@12 442 lbThrottle:SetText("LFG scan is delayed (throttled).\nThis page will update automatically...")
ShadowTheAge@12 443 else
ShadowTheAge@12 444 lbThrottle:SetText("Scan failed ("..reason..")")
ShadowTheAge@0 445 end
ShadowTheAge@12 446 lbThrottle:Show()
ShadowTheAge@0 447 end
ShadowTheAge@0 448
ShadowTheAge@0 449 function addon:LfgResponseData()
ShadowTheAge@0 450 lfgScanInProgress = false;
ShadowTheAge@12 451 if lbThrottle then lbThrottle:Hide() end
ShadowTheAge@12 452 refreshLFGList()
ShadowTheAge@0 453 end
ShadowTheAge@0 454
ShadowTheAge@0 455 function addon:updateAppStatus(event, id, status, oldstatus)
ShadowTheAge@0 456 if status == "invited" then
ShadowTheAge@0 457 LFGListInviteDialog_Accept(LFGListInviteDialog)
ShadowTheAge@0 458 end
ShadowTheAge@12 459 addon:UpdateAutoButtonStatus()
ShadowTheAge@12 460 addon:SetGroupJoinStatus(id, status)
ShadowTheAge@12 461 end
ShadowTheAge@12 462
ShadowTheAge@12 463 function addon:SetGroupJoinStatus(id, status)
ShadowTheAge@12 464 local name = select(12, C_LFGList.GetSearchResultInfo(id))
ShadowTheAge@12 465 recentgroups[name] = {status=status, time=GetTime()}
ShadowTheAge@12 466 end
ShadowTheAge@12 467
ShadowTheAge@12 468 function addon:updatePartyInfo()
ShadowTheAge@12 469 local realms = {}
ShadowTheAge@12 470 local inGroup = IsInGroup()
ShadowTheAge@12 471 if inGroup then
ShadowTheAge@12 472 if IsInRaid() then
ShadowTheAge@12 473 for i=1, MAX_RAID_MEMBERS do
ShadowTheAge@12 474 addon:AddUnitIdStat("raid"..i, realms)
ShadowTheAge@12 475 end
ShadowTheAge@12 476 else
ShadowTheAge@12 477 for i=1, MAX_PARTY_MEMBERS do
ShadowTheAge@12 478 addon:AddUnitIdStat("party"..i, realms)
ShadowTheAge@12 479 end
ShadowTheAge@12 480 end
ShadowTheAge@12 481 end
ShadowTheAge@12 482 if inGroup ~= wasInGroup then
ShadowTheAge@12 483 addon:ForceRefreshZone()
ShadowTheAge@12 484 wasInGroup = inGroup
ShadowTheAge@12 485 addon:UpdateAutoButtonStatus()
ShadowTheAge@12 486 end
ShadowTheAge@12 487 end
ShadowTheAge@12 488
ShadowTheAge@12 489
ShadowTheAge@12 490
ShadowTheAge@0 491
ShadowTheAge@0 492 -- Zone scanning routine
ShadowTheAge@0 493
ShadowTheAge@0 494 function addon:LeaveCombat()
ShadowTheAge@0 495 addon:UnregisterEvent("PLAYER_REGEN_ENABLED")
ShadowTheAge@0 496 scanstate = 0
ShadowTheAge@0 497 addon:ScanRealm();
ShadowTheAge@0 498 end
ShadowTheAge@0 499
ShadowTheAge@11 500 function addon:ForceRefreshZone()
ShadowTheAge@11 501 addon:RefreshZone(true)
ShadowTheAge@11 502 end
ShadowTheAge@11 503
ShadowTheAge@11 504 function addon:RefreshZone(shedule)
ShadowTheAge@11 505 local inst, instType = IsInInstance()
ShadowTheAge@12 506 inInstance = (inst or instType ~= "none")
ShadowTheAge@12 507 if inInstance then
ShadowTheAge@11 508 lbRealm:SetText("Instanced zone")
ShadowTheAge@11 509 curRealmStat = nil
ShadowTheAge@12 510 inInstance = true
ShadowTheAge@11 511 else
ShadowTheAge@12 512 inInstance = false;
ShadowTheAge@11 513 if scanstate == 0 then
ShadowTheAge@11 514 addon:ScanRealm()
ShadowTheAge@11 515 elseif shedule == true and scanstate == 2 then
ShadowTheAge@11 516 addon:SetStatus("Rescan sheduled...")
ShadowTheAge@11 517 scanstate = 3
ShadowTheAge@11 518 end
ShadowTheAge@11 519 end
ShadowTheAge@12 520 addon:UpdateAutoButtonStatus()
ShadowTheAge@11 521 end
ShadowTheAge@11 522
ShadowTheAge@0 523 function addon:ScanRealm()
ShadowTheAge@0 524 if scanstate > 0 then return end
ShadowTheAge@0 525 if InCombatLockdown() then
ShadowTheAge@0 526 addon:RegisterEvent("PLAYER_REGEN_ENABLED","LeaveCombat")
ShadowTheAge@0 527 scanstate = 1
ShadowTheAge@11 528 addon:SetStatus("Scan sheduled after combat...");
ShadowTheAge@0 529 return
ShadowTheAge@0 530 end
ShadowTheAge@0 531 scanstate = 2
ShadowTheAge@11 532 addon:SetStatus("Scanning current realm...");
ShadowTheAge@0 533 local searchString = _G.WHO_TAG_ZONE .. '"' .. GetZoneText() .. '"';
ShadowTheAge@0 534 wholib:Who(searchString, {callback = "ScanResult", handler=addon})
ShadowTheAge@0 535 end
ShadowTheAge@0 536
ShadowTheAge@0 537 function addon:ScanResult(query, results, complete)
ShadowTheAge@0 538 local realms = {}
ShadowTheAge@0 539 for _, player in ipairs(results) do
ShadowTheAge@0 540 addon:AddRealmStat(player.Name, realms);
ShadowTheAge@0 541 end
ShadowTheAge@0 542 curRealmStat = addon:GetRealmStat(realms);
ShadowTheAge@11 543 curRealmStat.complete = complete
ShadowTheAge@0 544 addon:updateCurrentRealm();
ShadowTheAge@0 545 local rescan = scanstate == 3
ShadowTheAge@0 546 scanstate = 0;
ShadowTheAge@0 547 if rescan then addon:ScanRealm() end
ShadowTheAge@0 548 end
ShadowTheAge@0 549
ShadowTheAge@0 550 function addon:AddRealmStat(name, realms)
ShadowTheAge@11 551 if (name == playerName) then return end
ShadowTheAge@11 552 local _, realm = strsplit(realmSep, name)
ShadowTheAge@0 553 realm = realm or homeRealm
ShadowTheAge@0 554 realms[realm] = (realms[realm] or 0) + 1
ShadowTheAge@0 555 end
ShadowTheAge@0 556
ShadowTheAge@0 557 function addon:AddUnitIdStat(unitid, realms)
ShadowTheAge@0 558 local name, realm = UnitName(unitid);
ShadowTheAge@0 559 if not name then return end
ShadowTheAge@0 560 if realm == "" then realm = homeRealm end
ShadowTheAge@0 561 realm = realm or homeRealm
ShadowTheAge@0 562 realms[realm] = (realms[realm] or 0) + 1
ShadowTheAge@0 563 end
ShadowTheAge@0 564
ShadowTheAge@0 565 function addon:GetRealmStat(realms)
ShadowTheAge@0 566 local rcount = 0;
ShadowTheAge@0 567 local stat = {};
ShadowTheAge@0 568 local pcount = 0;
ShadowTheAge@0 569 for realm,count in pairs(realms) do
ShadowTheAge@0 570 table.insert(stat,{realm=realm,count=count})
ShadowTheAge@0 571 rcount = rcount + 1;
ShadowTheAge@0 572 pcount = pcount + count;
ShadowTheAge@0 573 end
ShadowTheAge@0 574 if rcount > 1 then
ShadowTheAge@0 575 table.sort(stat, function(a,b) return a.count > b.count end)
ShadowTheAge@0 576 stat.max = stat[1].count
ShadowTheAge@0 577 else stat.max = 0 end
ShadowTheAge@0 578 stat.players = pcount;
ShadowTheAge@0 579 stat.realms = rcount;
ShadowTheAge@0 580 return stat;
ShadowTheAge@0 581 end
ShadowTheAge@0 582
ShadowTheAge@0 583 function addon:updateCurrentRealm()
ShadowTheAge@11 584 addon:SetStatus();
ShadowTheAge@11 585 if not curRealmStat or curRealmStat.realms < 1 then
ShadowTheAge@11 586 lbRealm:SetText("Unknown realm (No players)")
ShadowTheAge@11 587 return;
ShadowTheAge@0 588 end
ShadowTheAge@11 589
ShadowTheAge@11 590 local bestRealm = curRealmStat[1]
ShadowTheAge@12 591 local prevThreshold = math.min(bestRealm.count/3,10)
ShadowTheAge@11 592 local mixCount = 0
ShadowTheAge@11 593 for i=2,curRealmStat.realms do
ShadowTheAge@0 594 local data = curRealmStat[i]
ShadowTheAge@11 595 if data.count >= prevThreshold then
ShadowTheAge@11 596 mixCount = mixCount + 1
ShadowTheAge@12 597 prevThreshold = math.min(data.count/3,10)
ShadowTheAge@0 598 end
ShadowTheAge@0 599 end
ShadowTheAge@11 600 curRealmStat.threshold = prevThreshold
ShadowTheAge@11 601
ShadowTheAge@11 602 if (mixCount > 0) then
ShadowTheAge@11 603 lbRealm:SetText("Mixed "..bestRealm.realm.." +"..mixCount)
ShadowTheAge@11 604 else
ShadowTheAge@11 605 lbRealm:SetText(bestRealm.realm)
ShadowTheAge@0 606 end
ShadowTheAge@0 607 end
ShadowTheAge@0 608
ShadowTheAge@12 609
ShadowTheAge@12 610
ShadowTheAge@12 611
ShadowTheAge@12 612
ShadowTheAge@12 613
ShadowTheAge@12 614 -- Auto action button
ShadowTheAge@12 615
ShadowTheAge@12 616 local action;
ShadowTheAge@12 617
ShadowTheAge@12 618 local function CancelJoin()
ShadowTheAge@12 619 local apps = C_LFGList.GetApplications();
ShadowTheAge@12 620 if apps[1] then
ShadowTheAge@12 621 C_LFGList.CancelApplication(apps[1])
ShadowTheAge@11 622 end
ShadowTheAge@11 623 end
ShadowTheAge@11 624
ShadowTheAge@12 625 local function findGroupToJoin()
ShadowTheAge@12 626 local count, list = C_LFGList.GetSearchResults()
ShadowTheAge@12 627 local tableData = {}
ShadowTheAge@12 628 for i = 1,count do
ShadowTheAge@12 629 local rid = list[i];
ShadowTheAge@12 630 if not rid then break end
ShadowTheAge@12 631 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid)
ShadowTheAge@12 632
ShadowTheAge@12 633 local data = list[i];
ShadowTheAge@12 634 local cols = {}
ShadowTheAge@12 635 local row = {rid}
ShadowTheAge@12 636 cols[1] = {value=updateGroupName,args=row}
ShadowTheAge@12 637 cols[2] = {value=updateGroupCount,args=row}
ShadowTheAge@12 638 cols[3] = {value=updateGroupRealm,args=row}
ShadowTheAge@12 639 cols[4] = {}
ShadowTheAge@12 640 table.insert(tableData, {cols=cols,id=rid})
ShadowTheAge@12 641
ShadowTheAge@0 642 end
ShadowTheAge@0 643 end
ShadowTheAge@0 644
ShadowTheAge@12 645 local function QuickJoin()
ShadowTheAge@12 646
ShadowTheAge@0 647 end
ShadowTheAge@0 648
ShadowTheAge@12 649 function addon:DoAutoAction()
ShadowTheAge@12 650 if action then action() end
ShadowTheAge@12 651 addon:UpdateAutoButtonStatus()
ShadowTheAge@0 652 end
ShadowTheAge@0 653
ShadowTheAge@12 654 function addon:UpdateAutoButtonStatus()
ShadowTheAge@12 655 btQuick:Enable()
ShadowTheAge@0 656 if IsInGroup() then
ShadowTheAge@12 657 action = LeaveParty;
ShadowTheAge@12 658 btQuick:SetText("Leave group")
ShadowTheAge@12 659 elseif C_LFGList.GetNumApplications() > 0 then
ShadowTheAge@12 660 action = CancelJoin;
ShadowTheAge@12 661 btQuick:SetText("Cancel join")
ShadowTheAge@12 662 else
ShadowTheAge@12 663 if inInstance then btQuick:Disable() end
ShadowTheAge@12 664 btQuick:SetText("Quick join")
ShadowTheAge@0 665 end
ShadowTheAge@12 666 end