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