Mercurial > wow > crossrealmassist
changeset 1:3f83977570fb
Project file layout
| author | ShadowTheAge |
|---|---|
| date | Wed, 04 Mar 2015 21:54:21 +0300 |
| parents | 9fa8442dd547 |
| children | c73a7706861e |
| files | CrossRealmAssist.lua CrossRealmAssist.toc CrossRealmAssist/CrossRealmAssist.lua CrossRealmAssist/CrossRealmAssist.toc CrossRealmAssist/embeds.xml embeds.xml |
| diffstat | 6 files changed, 489 insertions(+), 486 deletions(-) [+] |
line wrap: on
line diff
--- a/CrossRealmAssist.lua Wed Mar 04 21:37:31 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,472 +0,0 @@ -CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") -local AceGUI = LibStub("AceGUI-3.0") -local addon = CrossRealmAssist; -local wholib = LibStub:GetLibrary('LibWho-2.0'):Library() - -local hgroup, lfgContainer, currealm, partyrealm, recrealm, curRealmStat, homeRealm, realmSep, gui, leavebtn - -local scanstate=0 -local recentRealms={} -local active=false - -local lfgGroups={ - 6, -- Custom - 10, -- Ashran - 1, -- Quests - 3, -- Raids - 8 -- BGs -} - -local lfgTabs -local curLfgGroup -local sheduledScan -local wasInGroup -local lfgScanInProgress=false - -function addon:OnInitialize() - -end - -function addon:OnEnable() - local tabCount = table.getn(lfgGroups) - lfgTabs = {} - for i=1,tabCount do - local cat = lfgGroups[i] - table.insert(lfgTabs,{value=cat,text=(C_LFGList.GetCategoryInfo(cat))}) - end - realmSep = _G.REALM_SEPARATORS - homeRealm = GetRealmName() - addon:RegisterChatCommand("cra", "Activate") - addon:RegisterChatCommand("crossrealmassist", "Activate") -end - -function addon:OnDisable() - addon:Deactivate() -end - -function addon:Activate() - if active then return end - active=true - wasInGroup = IsInGroup() - addon:CreateUI() - addon:ScanRealm() - addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "SheduleScan") - addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData") - addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed") - addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo") - addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus") -end - -function addon:Deactivate() - if not active then return end - active = false - scanstate = 0 - lfgScanInProgress = false - gui:Release(); - gui, lfgContainer, hgroup, currealm, partyrealm, recrealm, leavebtn = nil,nil,nil,nil,nil,nil,nil - addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA") - addon:UnregisterEvent("PLAYER_REGEN_ENABLED") - addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED") - addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED") - addon:UnregisterEvent("GROUP_ROSTER_UPDATE") - addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED") -end - -function addon:CreateUI() - gui = addon:AddUI(nil,"Window",{SetTitle="Cross Realm Assist",EnableResize=false,SetLayout="Flow"},true,{OnClose=addon.Deactivate}) - - local tabgroup = addon:AddUI(gui,"TabGroup",{SetFullHeight=true,SetTabs=lfgTabs,SetLayout="Fill"},true,{OnGroupSelected=addon.LfgScan}) - tabgroup:SelectTab(lfgGroups[1]) - lfgContainer = addon:AddUI(tabgroup,"ScrollFrame") - - local hgroupc = addon:AddUI(gui,"InlineGroup",{SetLayout="Fill",SetFullHeight=true,SetTitle="Realm info"},true) - hgroup = addon:AddUI(hgroupc,"ScrollFrame") - - addon:AddUI(hgroup,"Heading",{SetText="Current realm"}) - currealm = addon:AddUI(hgroup,"SimpleGroup"); - addon:AddUI(hgroup,"Button",{SetText="Refresh",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ScanRealm}) - - addon:AddUI(hgroup,"Heading",{SetText="Party statistics"}) - partyrealm = addon:AddUI(hgroup,"SimpleGroup"); - leavebtn = addon:AddUI(hgroup,"Button",{SetText="Leave",SetRelativeWidth=0.5,SetHeight=20,SetDisabled=not IsInGroup()},true,{OnClick=LeaveParty}) - - addon:AddUI(hgroup,"Heading",{SetText="Recent realms"}) - recrealm = addon:AddUI(hgroup,"SimpleGroup"); - addon:AddUI(hgroup,"Button",{SetText="Clear",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ClearRecentRealms}) - - gui:DoLayout() - gui:PauseLayout() - - tabgroup:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT", -200, 0) - hgroupc:SetPoint("TOPLEFT", gui.content, "TOPRIGHT", -200, 0) - hgroupc:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT") - - if curRealmStat then addon:updateCurrentRealm() end - addon:updatePartyInfo() - addon:updateRecentRealms() -end - --- LFG scanning routine - -function addon.refreshLfgCurrent() - addon.LfgScan(nil,nil,curLfgGroup) -end - -function addon.LfgScan(widget, callback, tab) - if not tab then return end - lfgScanInProgress = true - if lfgContainer then lfgContainer:ReleaseChildren() end - curLfgGroup = tab - C_LFGList.Search(curLfgGroup,"") -end - -function addon:LfgScanFailed(event, reason) - print("scan failed "..reason) - if reason == "throttled" then - addon:ScheduleTimer(addon.LfgScan, 2, nil, nil, curLfgGroup) - end -end - -local function WeightLfgItem(item) - local leaderRealm = 3 - if (item.realm ~= "???") then leaderRealm = (5 - (recentRealms[item.realm] or 0)) end - local weight = - (item.autoinv and 5 or 2) * - ((item.friends > 0) and 2 or 3) * - ((item.ilvl > 0) and 2 or 3) * - ((item.voice ~= "") and 2 or 4) - local count = item.pcount; - local countWeight - if count >= 39 or count <= 1 then countWeight = 1 - elseif count >= 35 or count <= 4 then countWeight = 2 - elseif count >= 30 or count <= 10 then countWeight = 3 - else countWeight = 4 end - return weight * leaderRealm * countWeight; -end - -function addon:LfgResponseData() - lfgScanInProgress = false; - addon:UpdateCurrentLfgInfo() -end - -function addon:UpdateCurrentLfgInfo(repeated) - if lfgScanInProgress then return end - local count, list = C_LFGList.GetSearchResults() - local lfgList = {} - local lfgEntries = 0 - local hasUnknowns = false - for i = 1,count do - local rid = list[i]; - if not rid then break end - local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid) - if not fullname then - fullname = "???-???" - hasUnknowns = true - end - if not delisted then - local pname, realm = strsplit(realmSep, fullname) - realm = realm or homeRealm - local item = { - rid=rid, - action=action, - caption=caption, - desc=desc, - ilvl=ilvl, - voice=voice, - time=time, - friends=bnetfr+charfr+guild, - name=pname, - realm = realm, - pcount=pcount, - autoinv=autoinv - } - item.weight = WeightLfgItem(item) - table.insert(lfgList, item) - lfgEntries = lfgEntries + 1 - end - end - addon:refreshLFGList(lfgList, lfgEntries); - if hasUnknowns and repeated ~= true then addon:ScheduleTimer("UpdateCurrentLfgInfo", 1, true) end -end - -function addon:refreshLFGList(list, count) - if not lfgContainer then return end - lfgContainer:PauseLayout() - lfgContainer:ReleaseChildren() - table.sort(list, addon.SortLfgItems) - - local canJoin = addon.canJoinGroup() - - for i=1,count do - local data = list[i]; - local renderer = addon:AddUI(lfgContainer,"SimpleGroup",{SetLayout="Flow",SetHeight=20,SetAutoAdjustHeight=false}); - - addon:AddUI(renderer,"Label",{SetText=data.caption,SetRelativeWidth=0.4},true) - addon:AddUI(renderer,"Label",{SetText=data.pcount,SetRelativeWidth=0.05},true) - local realm = addon:AddUI(renderer,"Label",{SetText=data.realm,SetRelativeWidth=0.25},true) - if recentRealms[data.realm] then - local r,g,b = GetItemQualityColor(recentRealms[data.realm]); - realm:SetColor(r,g,b) - end - - local tooltip = {} - if data.voice ~= "" then table.insert(tooltip,"Voice: "..data.voice) end - if data.friends > 0 then table.insert(tooltip,"Friends: "..data.friends) end - if data.ilvl > 0 then table.insert(tooltip,"Min. Ilvl: "..data.ilvl) end - addon:AddIcon(renderer, "Interface/GossipFrame/ActiveQuestIcon", 16, tooltip[1] ~= nil, tooltip) - addon:AddIcon(renderer, READY_CHECK_READY_TEXTURE, 16, data.autoinv, {"Auto invite!"}) - local btn = addon:AddUI(renderer,"Button",{SetText="Join",SetRelativeWidth=0.2,SetHeight=20,SetDisabled=not canJoin},true,{OnClick=addon.joinGroup}) - btn:SetUserData('rid',data.rid) - end - addon:AddUI(lfgContainer,"Button",{SetText="Refresh",SetWidth=100,SetHeight=20},true,{OnClick=addon.refreshLfgCurrent}) - - lfgContainer:ResumeLayout() - lfgContainer:DoLayout() -end - -function addon.SortLfgItems(a,b) - return a.weight > b.weight -end - -function addon.canJoinGroup() - return (not IsInGroup()) or (UnitIsGroupLeader('player') and not IsInRaid()) -end - -function addon.joinGroup(widget) - if not addon.canJoinGroup() then return end - local rid = widget:GetUserData('rid'); - widget:SetDisabled(true) - C_LFGList.ApplyToGroup(rid, "", C_LFGList.GetAvailableRoles()) -end - -function addon:updateAppStatus(event, id, status, oldstatus) - if status == "invited" then - LFGListInviteDialog_Accept(LFGListInviteDialog) - end -end - --- Zone scanning routine - -function addon:LeaveCombat() - addon:UnregisterEvent("PLAYER_REGEN_ENABLED") - scanstate = 0 - addon:ScanRealm(); -end - -function addon:ScanRealm() - if scanstate > 0 then return end - if InCombatLockdown() then - addon:RegisterEvent("PLAYER_REGEN_ENABLED","LeaveCombat") - scanstate = 1 - addon:AddLabel(currealm, "Scan sheduled after combat...", 3); - return - end - scanstate = 2 - addon:AddLabel(currealm, "Scanning...", 3); - local searchString = _G.WHO_TAG_ZONE .. '"' .. GetZoneText() .. '"'; - wholib:Who(searchString, {callback = "ScanResult", handler=addon}) -end - -function addon:ScanResult(query, results, complete) - local realms = {} - for _, player in ipairs(results) do - addon:AddRealmStat(player.Name, realms); - end - curRealmStat = addon:GetRealmStat(realms); - addon:updateCurrentRealm(); - local rescan = scanstate == 3 - scanstate = 0; - if rescan then addon:ScanRealm() end -end - -function addon:AddRealmStat(name, realms) - local _, realm = strsplit(realmSep, name) -- TODO exclude self - realm = realm or homeRealm - realms[realm] = (realms[realm] or 0) + 1 -end - -function addon:AddUnitIdStat(unitid, realms) - local name, realm = UnitName(unitid); - if not name then return end - if realm == "" then realm = homeRealm end - realm = realm or homeRealm - realms[realm] = (realms[realm] or 0) + 1 -end - -function addon:GetRealmStat(realms) - local rcount = 0; - local stat = {}; - local pcount = 0; - for realm,count in pairs(realms) do - table.insert(stat,{realm=realm,count=count}) - rcount = rcount + 1; - pcount = pcount + count; - end - if rcount > 1 then - table.sort(stat, function(a,b) return a.count > b.count end) - stat.max = stat[1].count - else stat.max = 0 end - stat.players = pcount; - stat.realms = rcount; - return stat; -end - -function addon:updateCurrentRealm() - if not currealm then return end - currealm:ReleaseChildren() - if curRealmStat.players < 5 then - addon:AddLabel(currealm, "Not enough players", 0); - end - local sureplayers = curRealmStat.players/2 - local maybeplayers = math.max(curRealmStat.max/4, 3) - local recentRealmUpdated = false - for i=1,curRealmStat.realms do - local data = curRealmStat[i] - if data.count >= maybeplayers then - local realm = data.realm - local rvalue = (data.count >= sureplayers) and 4 or 2 - if (rvalue > (recentRealms[realm] or 0)) then - recentRealmUpdated = true - recentRealms[realm] = rvalue - end - end - end - addon:addLabels(currealm, curRealmStat, sureplayers, maybeplayers, 3, "Realm unknown"); - if recentRealmUpdated then - addon:UpdateCurrentLfgInfo() - addon:updateRecentRealms() - end -end - -function addon:addLabels(container, stats, epict, whitet, grayt, emptytext) - if stats.realms == 0 then - addon:AddLabel(container, emptytext) - else - local players = stats.players - local pleft = players; - for i=1,stats.realms do - local data = stats[i] - local count = data.count; - local percent = math.ceil(100 * count / players - 0.5) - local label = data.realm .. " (" .. percent .. "%)"; - local color - if count < grayt then break - elseif count < whitet then color = 1 - elseif count < epict then color = 2 - else color = 4 end - pleft = pleft - count - addon:AddLabel(container, label, color); - end - if pleft > 0 then - addon:AddLabel(container, "Other" .. " (" .. math.ceil(100 * pleft / players - 0.5) .. "%)", 0); - end - end -end - -function addon:updateRecentRealms() - if not recrealm then return end - recrealm:ReleaseChildren() - local nothing = true; - for realm,color in pairs(recentRealms) do - addon:AddLabel(recrealm, realm,color); - nothing = false; - end - if nothing then - addon:AddLabel(recrealm, "No recent realms"); - end -end - -function addon:ClearRecentRealms() - recentRealms = {} - addon:UpdateCurrentLfgInfo() - addon:updateRecentRealms() -end - -function addon:SheduleScan() - if scanstate == 0 then - addon:ScanRealm() - elseif scanstate == 2 then - scanstate = 3 - end -end - -function addon:updatePartyInfo() - if not partyrealm then return end - partyrealm:ReleaseChildren() - local realms = {} - local inGroup = IsInGroup() - if IsInGroup() then - if IsInRaid() then - for i=1, MAX_RAID_MEMBERS do - addon:AddUnitIdStat("raid"..i, realms) - end - else - for i=1, MAX_PARTY_MEMBERS do - addon:AddUnitIdStat("party"..i, realms) - end - end - end - if inGroup ~= wasInGroup then - addon:SheduleScan() - wasInGroup = inGroup - addon:UpdateCurrentLfgInfo() - leavebtn:SetDisabled(not inGroup) - end - local partyStat = addon:GetRealmStat(realms); - addon:addLabels(partyrealm, partyStat, partyStat.players/2, 2, 0, "Not in party"); -end - --- Utils functions - -function addon:AddUI(owner, type, parameters, manual, callbacks) - local ui = AceGUI:Create(type) - if parameters then - for key,value in pairs(parameters) do ui[key](ui,value) end - end - if callbacks then - for key,value in pairs(callbacks) do ui:SetCallback(key,value) end - end - if not manual then ui:SetFullWidth(true) end - if owner then owner:AddChild(ui) end - return ui -end - -function addon:AddLabel(owner, text, color, icon) - local label = AceGUI:Create("Label") - label:SetText(text) - label:SetFullWidth(true) - if color ~= nil then - local r,g,b = GetItemQualityColor(color); - label:SetColor(r,g,b) - end - owner:AddChild(label) - return label -end - -function addon:AddIcon(owner, image, size, visible, tooltip) - if visible ~= false then - local icon = addon:AddUI(owner,"Icon",{SetWidth=size,SetHeight=size},true) - icon:SetImage(image) - icon:SetImageSize(size,size) - if tooltip then - icon:SetUserData('tooltip',tooltip) - icon:SetCallback("OnEnter",addon.ShowTooltip) - icon:SetCallback("OnLeave",addon.HideTooltip) - end - else -- add placeholder - addon:AddUI(owner,"Label",{SetWidth=size,SetHeight=size},true) - end -end - -function addon.ShowTooltip(widget) - GameTooltip:SetOwner(widget.frame, "ANCHOR_TOP") - local tooltip = widget:GetUserData('tooltip') - for i=1,#tooltip do - GameTooltip:AddLine(tooltip[i], 1, 1, 1) - end - GameTooltip:Show() -end - -function addon.HideTooltip(widget) - GameTooltip:Hide() -end \ No newline at end of file
--- a/CrossRealmAssist.toc Wed Mar 04 21:37:31 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -## Interface: 60100 -## Title: Cross Realm Assist -## Notes: Easy tool for cross-realm hoping -## Author: ShadowTheAge -## Version: 0.1 - -embeds.xml -CrossRealmAssist.lua \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CrossRealmAssist/CrossRealmAssist.lua Wed Mar 04 21:54:21 2015 +0300 @@ -0,0 +1,472 @@ +CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") +local AceGUI = LibStub("AceGUI-3.0") +local addon = CrossRealmAssist; +local wholib = LibStub:GetLibrary('LibWho-2.0'):Library() + +local hgroup, lfgContainer, currealm, partyrealm, recrealm, curRealmStat, homeRealm, realmSep, gui, leavebtn + +local scanstate=0 +local recentRealms={} +local active=false + +local lfgGroups={ + 6, -- Custom + 10, -- Ashran + 1, -- Quests + 3, -- Raids + 8 -- BGs +} + +local lfgTabs +local curLfgGroup +local sheduledScan +local wasInGroup +local lfgScanInProgress=false + +function addon:OnInitialize() + +end + +function addon:OnEnable() + local tabCount = table.getn(lfgGroups) + lfgTabs = {} + for i=1,tabCount do + local cat = lfgGroups[i] + table.insert(lfgTabs,{value=cat,text=(C_LFGList.GetCategoryInfo(cat))}) + end + realmSep = _G.REALM_SEPARATORS + homeRealm = GetRealmName() + addon:RegisterChatCommand("cra", "Activate") + addon:RegisterChatCommand("crossrealmassist", "Activate") +end + +function addon:OnDisable() + addon:Deactivate() +end + +function addon:Activate() + if active then return end + active=true + wasInGroup = IsInGroup() + addon:CreateUI() + addon:ScanRealm() + addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "SheduleScan") + addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData") + addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed") + addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo") + addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus") +end + +function addon:Deactivate() + if not active then return end + active = false + scanstate = 0 + lfgScanInProgress = false + gui:Release(); + gui, lfgContainer, hgroup, currealm, partyrealm, recrealm, leavebtn = nil,nil,nil,nil,nil,nil,nil + addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA") + addon:UnregisterEvent("PLAYER_REGEN_ENABLED") + addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED") + addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED") + addon:UnregisterEvent("GROUP_ROSTER_UPDATE") + addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED") +end + +function addon:CreateUI() + gui = addon:AddUI(nil,"Window",{SetTitle="Cross Realm Assist",EnableResize=false,SetLayout="Flow"},true,{OnClose=addon.Deactivate}) + + local tabgroup = addon:AddUI(gui,"TabGroup",{SetFullHeight=true,SetTabs=lfgTabs,SetLayout="Fill"},true,{OnGroupSelected=addon.LfgScan}) + tabgroup:SelectTab(lfgGroups[1]) + lfgContainer = addon:AddUI(tabgroup,"ScrollFrame") + + local hgroupc = addon:AddUI(gui,"InlineGroup",{SetLayout="Fill",SetFullHeight=true,SetTitle="Realm info"},true) + hgroup = addon:AddUI(hgroupc,"ScrollFrame") + + addon:AddUI(hgroup,"Heading",{SetText="Current realm"}) + currealm = addon:AddUI(hgroup,"SimpleGroup"); + addon:AddUI(hgroup,"Button",{SetText="Refresh",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ScanRealm}) + + addon:AddUI(hgroup,"Heading",{SetText="Party statistics"}) + partyrealm = addon:AddUI(hgroup,"SimpleGroup"); + leavebtn = addon:AddUI(hgroup,"Button",{SetText="Leave",SetRelativeWidth=0.5,SetHeight=20,SetDisabled=not IsInGroup()},true,{OnClick=LeaveParty}) + + addon:AddUI(hgroup,"Heading",{SetText="Recent realms"}) + recrealm = addon:AddUI(hgroup,"SimpleGroup"); + addon:AddUI(hgroup,"Button",{SetText="Clear",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ClearRecentRealms}) + + gui:DoLayout() + gui:PauseLayout() + + tabgroup:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT", -200, 0) + hgroupc:SetPoint("TOPLEFT", gui.content, "TOPRIGHT", -200, 0) + hgroupc:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT") + + if curRealmStat then addon:updateCurrentRealm() end + addon:updatePartyInfo() + addon:updateRecentRealms() +end + +-- LFG scanning routine + +function addon.refreshLfgCurrent() + addon.LfgScan(nil,nil,curLfgGroup) +end + +function addon.LfgScan(widget, callback, tab) + if not tab then return end + lfgScanInProgress = true + if lfgContainer then lfgContainer:ReleaseChildren() end + curLfgGroup = tab + C_LFGList.Search(curLfgGroup,"") +end + +function addon:LfgScanFailed(event, reason) + print("scan failed "..reason) + if reason == "throttled" then + addon:ScheduleTimer(addon.LfgScan, 2, nil, nil, curLfgGroup) + end +end + +local function WeightLfgItem(item) + local leaderRealm = 3 + if (item.realm ~= "???") then leaderRealm = (5 - (recentRealms[item.realm] or 0)) end + local weight = + (item.autoinv and 5 or 2) * + ((item.friends > 0) and 2 or 3) * + ((item.ilvl > 0) and 2 or 3) * + ((item.voice ~= "") and 2 or 4) + local count = item.pcount; + local countWeight + if count >= 39 or count <= 1 then countWeight = 1 + elseif count >= 35 or count <= 4 then countWeight = 2 + elseif count >= 30 or count <= 10 then countWeight = 3 + else countWeight = 4 end + return weight * leaderRealm * countWeight; +end + +function addon:LfgResponseData() + lfgScanInProgress = false; + addon:UpdateCurrentLfgInfo() +end + +function addon:UpdateCurrentLfgInfo(repeated) + if lfgScanInProgress then return end + local count, list = C_LFGList.GetSearchResults() + local lfgList = {} + local lfgEntries = 0 + local hasUnknowns = false + for i = 1,count do + local rid = list[i]; + if not rid then break end + local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid) + if not fullname then + fullname = "???-???" + hasUnknowns = true + end + if not delisted then + local pname, realm = strsplit(realmSep, fullname) + realm = realm or homeRealm + local item = { + rid=rid, + action=action, + caption=caption, + desc=desc, + ilvl=ilvl, + voice=voice, + time=time, + friends=bnetfr+charfr+guild, + name=pname, + realm = realm, + pcount=pcount, + autoinv=autoinv + } + item.weight = WeightLfgItem(item) + table.insert(lfgList, item) + lfgEntries = lfgEntries + 1 + end + end + addon:refreshLFGList(lfgList, lfgEntries); + if hasUnknowns and repeated ~= true then addon:ScheduleTimer("UpdateCurrentLfgInfo", 1, true) end +end + +function addon:refreshLFGList(list, count) + if not lfgContainer then return end + lfgContainer:PauseLayout() + lfgContainer:ReleaseChildren() + table.sort(list, addon.SortLfgItems) + + local canJoin = addon.canJoinGroup() + + for i=1,count do + local data = list[i]; + local renderer = addon:AddUI(lfgContainer,"SimpleGroup",{SetLayout="Flow",SetHeight=20,SetAutoAdjustHeight=false}); + + addon:AddUI(renderer,"Label",{SetText=data.caption,SetRelativeWidth=0.4},true) + addon:AddUI(renderer,"Label",{SetText=data.pcount,SetRelativeWidth=0.05},true) + local realm = addon:AddUI(renderer,"Label",{SetText=data.realm,SetRelativeWidth=0.25},true) + if recentRealms[data.realm] then + local r,g,b = GetItemQualityColor(recentRealms[data.realm]); + realm:SetColor(r,g,b) + end + + local tooltip = {} + if data.voice ~= "" then table.insert(tooltip,"Voice: "..data.voice) end + if data.friends > 0 then table.insert(tooltip,"Friends: "..data.friends) end + if data.ilvl > 0 then table.insert(tooltip,"Min. Ilvl: "..data.ilvl) end + addon:AddIcon(renderer, "Interface/GossipFrame/ActiveQuestIcon", 16, tooltip[1] ~= nil, tooltip) + addon:AddIcon(renderer, READY_CHECK_READY_TEXTURE, 16, data.autoinv, {"Auto invite!"}) + local btn = addon:AddUI(renderer,"Button",{SetText="Join",SetRelativeWidth=0.2,SetHeight=20,SetDisabled=not canJoin},true,{OnClick=addon.joinGroup}) + btn:SetUserData('rid',data.rid) + end + addon:AddUI(lfgContainer,"Button",{SetText="Refresh",SetWidth=100,SetHeight=20},true,{OnClick=addon.refreshLfgCurrent}) + + lfgContainer:ResumeLayout() + lfgContainer:DoLayout() +end + +function addon.SortLfgItems(a,b) + return a.weight > b.weight +end + +function addon.canJoinGroup() + return (not IsInGroup()) or (UnitIsGroupLeader('player') and not IsInRaid()) +end + +function addon.joinGroup(widget) + if not addon.canJoinGroup() then return end + local rid = widget:GetUserData('rid'); + widget:SetDisabled(true) + C_LFGList.ApplyToGroup(rid, "", C_LFGList.GetAvailableRoles()) +end + +function addon:updateAppStatus(event, id, status, oldstatus) + if status == "invited" then + LFGListInviteDialog_Accept(LFGListInviteDialog) + end +end + +-- Zone scanning routine + +function addon:LeaveCombat() + addon:UnregisterEvent("PLAYER_REGEN_ENABLED") + scanstate = 0 + addon:ScanRealm(); +end + +function addon:ScanRealm() + if scanstate > 0 then return end + if InCombatLockdown() then + addon:RegisterEvent("PLAYER_REGEN_ENABLED","LeaveCombat") + scanstate = 1 + addon:AddLabel(currealm, "Scan sheduled after combat...", 3); + return + end + scanstate = 2 + addon:AddLabel(currealm, "Scanning...", 3); + local searchString = _G.WHO_TAG_ZONE .. '"' .. GetZoneText() .. '"'; + wholib:Who(searchString, {callback = "ScanResult", handler=addon}) +end + +function addon:ScanResult(query, results, complete) + local realms = {} + for _, player in ipairs(results) do + addon:AddRealmStat(player.Name, realms); + end + curRealmStat = addon:GetRealmStat(realms); + addon:updateCurrentRealm(); + local rescan = scanstate == 3 + scanstate = 0; + if rescan then addon:ScanRealm() end +end + +function addon:AddRealmStat(name, realms) + local _, realm = strsplit(realmSep, name) -- TODO exclude self + realm = realm or homeRealm + realms[realm] = (realms[realm] or 0) + 1 +end + +function addon:AddUnitIdStat(unitid, realms) + local name, realm = UnitName(unitid); + if not name then return end + if realm == "" then realm = homeRealm end + realm = realm or homeRealm + realms[realm] = (realms[realm] or 0) + 1 +end + +function addon:GetRealmStat(realms) + local rcount = 0; + local stat = {}; + local pcount = 0; + for realm,count in pairs(realms) do + table.insert(stat,{realm=realm,count=count}) + rcount = rcount + 1; + pcount = pcount + count; + end + if rcount > 1 then + table.sort(stat, function(a,b) return a.count > b.count end) + stat.max = stat[1].count + else stat.max = 0 end + stat.players = pcount; + stat.realms = rcount; + return stat; +end + +function addon:updateCurrentRealm() + if not currealm then return end + currealm:ReleaseChildren() + if curRealmStat.players < 5 then + addon:AddLabel(currealm, "Not enough players", 0); + end + local sureplayers = curRealmStat.players/2 + local maybeplayers = math.max(curRealmStat.max/4, 3) + local recentRealmUpdated = false + for i=1,curRealmStat.realms do + local data = curRealmStat[i] + if data.count >= maybeplayers then + local realm = data.realm + local rvalue = (data.count >= sureplayers) and 4 or 2 + if (rvalue > (recentRealms[realm] or 0)) then + recentRealmUpdated = true + recentRealms[realm] = rvalue + end + end + end + addon:addLabels(currealm, curRealmStat, sureplayers, maybeplayers, 3, "Realm unknown"); + if recentRealmUpdated then + addon:UpdateCurrentLfgInfo() + addon:updateRecentRealms() + end +end + +function addon:addLabels(container, stats, epict, whitet, grayt, emptytext) + if stats.realms == 0 then + addon:AddLabel(container, emptytext) + else + local players = stats.players + local pleft = players; + for i=1,stats.realms do + local data = stats[i] + local count = data.count; + local percent = math.ceil(100 * count / players - 0.5) + local label = data.realm .. " (" .. percent .. "%)"; + local color + if count < grayt then break + elseif count < whitet then color = 1 + elseif count < epict then color = 2 + else color = 4 end + pleft = pleft - count + addon:AddLabel(container, label, color); + end + if pleft > 0 then + addon:AddLabel(container, "Other" .. " (" .. math.ceil(100 * pleft / players - 0.5) .. "%)", 0); + end + end +end + +function addon:updateRecentRealms() + if not recrealm then return end + recrealm:ReleaseChildren() + local nothing = true; + for realm,color in pairs(recentRealms) do + addon:AddLabel(recrealm, realm,color); + nothing = false; + end + if nothing then + addon:AddLabel(recrealm, "No recent realms"); + end +end + +function addon:ClearRecentRealms() + recentRealms = {} + addon:UpdateCurrentLfgInfo() + addon:updateRecentRealms() +end + +function addon:SheduleScan() + if scanstate == 0 then + addon:ScanRealm() + elseif scanstate == 2 then + scanstate = 3 + end +end + +function addon:updatePartyInfo() + if not partyrealm then return end + partyrealm:ReleaseChildren() + local realms = {} + local inGroup = IsInGroup() + if IsInGroup() then + if IsInRaid() then + for i=1, MAX_RAID_MEMBERS do + addon:AddUnitIdStat("raid"..i, realms) + end + else + for i=1, MAX_PARTY_MEMBERS do + addon:AddUnitIdStat("party"..i, realms) + end + end + end + if inGroup ~= wasInGroup then + addon:SheduleScan() + wasInGroup = inGroup + addon:UpdateCurrentLfgInfo() + leavebtn:SetDisabled(not inGroup) + end + local partyStat = addon:GetRealmStat(realms); + addon:addLabels(partyrealm, partyStat, partyStat.players/2, 2, 0, "Not in party"); +end + +-- Utils functions + +function addon:AddUI(owner, type, parameters, manual, callbacks) + local ui = AceGUI:Create(type) + if parameters then + for key,value in pairs(parameters) do ui[key](ui,value) end + end + if callbacks then + for key,value in pairs(callbacks) do ui:SetCallback(key,value) end + end + if not manual then ui:SetFullWidth(true) end + if owner then owner:AddChild(ui) end + return ui +end + +function addon:AddLabel(owner, text, color, icon) + local label = AceGUI:Create("Label") + label:SetText(text) + label:SetFullWidth(true) + if color ~= nil then + local r,g,b = GetItemQualityColor(color); + label:SetColor(r,g,b) + end + owner:AddChild(label) + return label +end + +function addon:AddIcon(owner, image, size, visible, tooltip) + if visible ~= false then + local icon = addon:AddUI(owner,"Icon",{SetWidth=size,SetHeight=size},true) + icon:SetImage(image) + icon:SetImageSize(size,size) + if tooltip then + icon:SetUserData('tooltip',tooltip) + icon:SetCallback("OnEnter",addon.ShowTooltip) + icon:SetCallback("OnLeave",addon.HideTooltip) + end + else -- add placeholder + addon:AddUI(owner,"Label",{SetWidth=size,SetHeight=size},true) + end +end + +function addon.ShowTooltip(widget) + GameTooltip:SetOwner(widget.frame, "ANCHOR_TOP") + local tooltip = widget:GetUserData('tooltip') + for i=1,#tooltip do + GameTooltip:AddLine(tooltip[i], 1, 1, 1) + end + GameTooltip:Show() +end + +function addon.HideTooltip(widget) + GameTooltip:Hide() +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CrossRealmAssist/CrossRealmAssist.toc Wed Mar 04 21:54:21 2015 +0300 @@ -0,0 +1,8 @@ +## Interface: 60100 +## Title: Cross Realm Assist +## Notes: Easy tool for cross-realm hoping +## Author: ShadowTheAge +## Version: 0.1 + +embeds.xml +CrossRealmAssist.lua \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CrossRealmAssist/embeds.xml Wed Mar 04 21:54:21 2015 +0300 @@ -0,0 +1,9 @@ +<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> + <Script file="libs\LibStub\LibStub.lua"/> + <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/> + <Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/> + <Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/> + <Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/> + <Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml"/> + <Script file="Libs\LibWho-2.0\LibWho-2.0\LibWho-2.0.lua"/> +</Ui> \ No newline at end of file
--- a/embeds.xml Wed Mar 04 21:37:31 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> - <Script file="libs\LibStub\LibStub.lua"/> - <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/> - <Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/> - <Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/> - <Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/> - <Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml"/> - <Script file="Libs\LibWho-2.0\LibWho-2.0\LibWho-2.0.lua"/> -</Ui> \ No newline at end of file
