Enhance version management features and localization for HMGT
This commit is contained in:
@@ -3,6 +3,212 @@ local HMGT = _G[ADDON_NAME]
|
||||
if not HMGT then return end
|
||||
|
||||
local L = HMGT.L or LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME)
|
||||
local AceGUI = LibStub("AceGUI-3.0", true)
|
||||
local CLASS_ICON_TCOORDS = CLASS_ICON_TCOORDS or {}
|
||||
|
||||
local function NormalizeName(name)
|
||||
if HMGT.NormalizePlayerName then
|
||||
return HMGT:NormalizePlayerName(name)
|
||||
end
|
||||
return tostring(name or "")
|
||||
end
|
||||
|
||||
local function GetRosterRows()
|
||||
local rows = {}
|
||||
local seen = {}
|
||||
|
||||
local function addUnit(unitId)
|
||||
if not unitId or not UnitExists(unitId) then
|
||||
return
|
||||
end
|
||||
local name = NormalizeName(UnitName(unitId))
|
||||
if not name or name == "" or seen[name] then
|
||||
return
|
||||
end
|
||||
seen[name] = true
|
||||
rows[#rows + 1] = {
|
||||
name = name,
|
||||
class = select(2, UnitClass(unitId)),
|
||||
isLeader = UnitIsGroupLeader and UnitIsGroupLeader(unitId) or false,
|
||||
isAssistant = UnitIsGroupAssistant and UnitIsGroupAssistant(unitId) or false,
|
||||
connected = UnitIsConnected and UnitIsConnected(unitId) ~= false or true,
|
||||
isPlayer = UnitIsUnit and UnitIsUnit(unitId, "player") or unitId == "player",
|
||||
}
|
||||
end
|
||||
|
||||
if IsInRaid() then
|
||||
for i = 1, GetNumGroupMembers() do
|
||||
addUnit("raid" .. i)
|
||||
end
|
||||
elseif IsInGroup() then
|
||||
addUnit("player")
|
||||
for i = 1, GetNumSubgroupMembers() do
|
||||
addUnit("party" .. i)
|
||||
end
|
||||
else
|
||||
addUnit("player")
|
||||
end
|
||||
|
||||
table.sort(rows, function(a, b)
|
||||
if a.isLeader ~= b.isLeader then
|
||||
return a.isLeader
|
||||
end
|
||||
if a.isPlayer ~= b.isPlayer then
|
||||
return a.isPlayer
|
||||
end
|
||||
return tostring(a.name or "") < tostring(b.name or "")
|
||||
end)
|
||||
|
||||
return rows
|
||||
end
|
||||
|
||||
local function GetPlayerVersionText(name)
|
||||
local normalized = NormalizeName(name)
|
||||
if normalized == NormalizeName(UnitName("player")) then
|
||||
return tostring(HMGT.ADDON_VERSION or "dev"), tonumber(HMGT.PROTOCOL_VERSION) or 0, true
|
||||
end
|
||||
|
||||
local version = HMGT.peerVersions and HMGT.peerVersions[normalized] or nil
|
||||
local protocol = HMGT.GetPeerProtocolVersion and HMGT:GetPeerProtocolVersion(normalized) or 0
|
||||
if version and version ~= "" then
|
||||
return tostring(version), tonumber(protocol) or 0, true
|
||||
end
|
||||
return nil, tonumber(protocol) or 0, false
|
||||
end
|
||||
|
||||
local function ApplyClassIcon(texture, classTag)
|
||||
if not texture then
|
||||
return
|
||||
end
|
||||
|
||||
local coords = classTag and CLASS_ICON_TCOORDS[classTag]
|
||||
if coords then
|
||||
texture:SetTexture("Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES")
|
||||
texture:SetTexCoord(coords[1], coords[2], coords[3], coords[4])
|
||||
texture:Show()
|
||||
else
|
||||
texture:SetTexture(nil)
|
||||
texture:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function AcquireVersionRow(window, index)
|
||||
window.versionRows = window.versionRows or {}
|
||||
local row = window.versionRows[index]
|
||||
if row then
|
||||
return row
|
||||
end
|
||||
|
||||
local parent = window.scrollChild
|
||||
row = CreateFrame("Frame", nil, parent)
|
||||
row:SetHeight(22)
|
||||
|
||||
row.background = row:CreateTexture(nil, "BACKGROUND")
|
||||
row.background:SetAllPoints(row)
|
||||
row.background:SetColorTexture(1, 1, 1, 0.03)
|
||||
|
||||
row.classIcon = row:CreateTexture(nil, "ARTWORK")
|
||||
row.classIcon:SetSize(16, 16)
|
||||
row.classIcon:SetPoint("LEFT", row, "LEFT", 4, 0)
|
||||
|
||||
row.nameText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
row.nameText:SetPoint("LEFT", row.classIcon, "RIGHT", 6, 0)
|
||||
row.nameText:SetJustifyH("LEFT")
|
||||
|
||||
row.versionText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
row.versionText:SetPoint("LEFT", row, "LEFT", 250, 0)
|
||||
row.versionText:SetWidth(150)
|
||||
row.versionText:SetJustifyH("LEFT")
|
||||
|
||||
row.protocolText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
row.protocolText:SetPoint("LEFT", row, "LEFT", 410, 0)
|
||||
row.protocolText:SetWidth(100)
|
||||
row.protocolText:SetJustifyH("LEFT")
|
||||
|
||||
window.versionRows[index] = row
|
||||
return row
|
||||
end
|
||||
|
||||
function HMGT:RefreshVersionNoticeWindow()
|
||||
local window = self.versionNoticeWindow
|
||||
if not window then
|
||||
return
|
||||
end
|
||||
|
||||
local roster = GetRosterRows()
|
||||
local localName = NormalizeName(UnitName("player"))
|
||||
|
||||
for index, info in ipairs(roster) do
|
||||
local row = AcquireVersionRow(window, index)
|
||||
row:ClearAllPoints()
|
||||
if index == 1 then
|
||||
row:SetPoint("TOPLEFT", window.scrollChild, "TOPLEFT", 0, 0)
|
||||
row:SetPoint("TOPRIGHT", window.scrollChild, "TOPRIGHT", 0, 0)
|
||||
else
|
||||
row:SetPoint("TOPLEFT", window.versionRows[index - 1], "BOTTOMLEFT", 0, -2)
|
||||
row:SetPoint("TOPRIGHT", window.versionRows[index - 1], "BOTTOMRIGHT", 0, -2)
|
||||
end
|
||||
|
||||
ApplyClassIcon(row.classIcon, info.class)
|
||||
|
||||
local nameLabel = tostring(info.name or UNKNOWN)
|
||||
if info.isLeader then
|
||||
nameLabel = string.format("%s %s", nameLabel, L["VERSION_WINDOW_LEADER_TAG"] or "(Leader)")
|
||||
elseif info.isAssistant then
|
||||
nameLabel = string.format("%s %s", nameLabel, L["VERSION_WINDOW_ASSISTANT_TAG"] or "(Assist)")
|
||||
end
|
||||
if info.isPlayer or info.name == localName then
|
||||
nameLabel = string.format("%s %s", nameLabel, L["VERSION_WINDOW_SELF_TAG"] or "(You)")
|
||||
end
|
||||
|
||||
row.nameText:SetText(nameLabel)
|
||||
row.nameText:SetTextColor(1, 0.82, 0.1, 1)
|
||||
|
||||
local versionText, protocol, hasAddon = GetPlayerVersionText(info.name)
|
||||
if hasAddon then
|
||||
row.versionText:SetText(versionText or "?")
|
||||
row.versionText:SetTextColor(0.9, 0.9, 0.9, 1)
|
||||
row.protocolText:SetText(protocol > 0 and tostring(protocol) or "-")
|
||||
row.protocolText:SetTextColor(0.75, 0.75, 0.75, 1)
|
||||
else
|
||||
row.versionText:SetText(L["VERSION_WINDOW_MISSING_ADDON"] or "Addon not installed")
|
||||
row.versionText:SetTextColor(1, 0.25, 0.25, 1)
|
||||
row.protocolText:SetText("-")
|
||||
row.protocolText:SetTextColor(1, 0.25, 0.25, 1)
|
||||
end
|
||||
|
||||
row:Show()
|
||||
end
|
||||
|
||||
if window.versionRows then
|
||||
for index = #roster + 1, #window.versionRows do
|
||||
window.versionRows[index]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local contentHeight = math.max(1, (#roster * 24))
|
||||
window.scrollChild:SetHeight(contentHeight)
|
||||
|
||||
local known = 0
|
||||
for _, info in ipairs(roster) do
|
||||
local _, _, hasAddon = GetPlayerVersionText(info.name)
|
||||
if hasAddon then
|
||||
known = known + 1
|
||||
end
|
||||
end
|
||||
|
||||
window.messageText:SetText(L["VERSION_WINDOW_MESSAGE"] or "Hail Mary Guild Tools versions in your current group")
|
||||
window.detailText:SetText(string.format(
|
||||
L["VERSION_WINDOW_CURRENT"] or "Current version: %s | Protocol: %s",
|
||||
tostring(HMGT.ADDON_VERSION or "dev"),
|
||||
tostring(HMGT.PROTOCOL_VERSION or "?")
|
||||
))
|
||||
window:SetStatusText(string.format(
|
||||
L["VERSION_WINDOW_STATUS"] or "Detected HMGT on %d/%d players",
|
||||
tonumber(known) or 0,
|
||||
tonumber(#roster) or 0
|
||||
))
|
||||
end
|
||||
|
||||
function HMGT:EnsureVersionNoticeWindow()
|
||||
if self.versionNoticeWindow then
|
||||
@@ -10,21 +216,21 @@ function HMGT:EnsureVersionNoticeWindow()
|
||||
end
|
||||
|
||||
self.versionNoticeWindowStatus = self.versionNoticeWindowStatus or {
|
||||
width = 560,
|
||||
height = 240,
|
||||
width = 640,
|
||||
height = 420,
|
||||
}
|
||||
|
||||
local window = self:CreateAceWindow("versionNotice", {
|
||||
title = L["VERSION_WINDOW_TITLE"] or "HMGT Version Check",
|
||||
statusText = "",
|
||||
statusTable = self.versionNoticeWindowStatus,
|
||||
width = self.versionNoticeWindowStatus.width or 560,
|
||||
height = self.versionNoticeWindowStatus.height or 240,
|
||||
width = self.versionNoticeWindowStatus.width or 640,
|
||||
height = self.versionNoticeWindowStatus.height or 420,
|
||||
backgroundTexture = "Interface\\AddOns\\HailMaryGuildTools\\Media\\HailMaryLogo.png",
|
||||
backgroundWidth = 220,
|
||||
backgroundHeight = 120,
|
||||
backgroundOffsetY = -8,
|
||||
backgroundAlpha = 0.12,
|
||||
backgroundAlpha = 0.08,
|
||||
strata = "FULLSCREEN_DIALOG",
|
||||
})
|
||||
if not window then
|
||||
@@ -32,26 +238,64 @@ function HMGT:EnsureVersionNoticeWindow()
|
||||
end
|
||||
|
||||
local content = window:GetContent()
|
||||
|
||||
local messageText = content:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
|
||||
messageText:SetPoint("TOPLEFT", content, "TOPLEFT", 28, -28)
|
||||
messageText:SetPoint("TOPRIGHT", content, "TOPRIGHT", -28, -28)
|
||||
messageText:SetJustifyH("CENTER")
|
||||
messageText:SetJustifyV("MIDDLE")
|
||||
messageText:SetPoint("TOPLEFT", content, "TOPLEFT", 24, -22)
|
||||
messageText:SetPoint("TOPRIGHT", content, "TOPRIGHT", -24, -22)
|
||||
messageText:SetJustifyH("LEFT")
|
||||
messageText:SetTextColor(1, 0.82, 0.1, 1)
|
||||
messageText:SetText(L["VERSION_WINDOW_MESSAGE"] or "A new version of Hail Mary Guild Tools is available.")
|
||||
window.messageText = messageText
|
||||
|
||||
local detailText = content:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
detailText:SetPoint("TOPLEFT", messageText, "BOTTOMLEFT", 0, -18)
|
||||
detailText:SetPoint("TOPRIGHT", messageText, "BOTTOMRIGHT", 0, -18)
|
||||
detailText:SetJustifyH("CENTER")
|
||||
detailText:SetJustifyV("TOP")
|
||||
if detailText.SetSpacing then
|
||||
detailText:SetSpacing(2)
|
||||
end
|
||||
detailText:SetPoint("TOPLEFT", messageText, "BOTTOMLEFT", 0, -8)
|
||||
detailText:SetPoint("TOPRIGHT", messageText, "BOTTOMRIGHT", 0, -8)
|
||||
detailText:SetJustifyH("LEFT")
|
||||
detailText:SetTextColor(0.9, 0.9, 0.9, 1)
|
||||
window.detailText = detailText
|
||||
|
||||
local refreshButton = AceGUI and AceGUI:Create("Button") or nil
|
||||
if refreshButton then
|
||||
refreshButton:SetText(L["VERSION_WINDOW_REFRESH"] or "Refresh")
|
||||
refreshButton:SetWidth(120)
|
||||
refreshButton:SetCallback("OnClick", function()
|
||||
HMGT:RequestSync("VersionWindow")
|
||||
HMGT:RefreshVersionNoticeWindow()
|
||||
end)
|
||||
refreshButton.frame:SetParent(window.frame)
|
||||
refreshButton.frame:ClearAllPoints()
|
||||
refreshButton.frame:SetPoint("TOPRIGHT", content, "TOPRIGHT", -24, -68)
|
||||
refreshButton.frame:Show()
|
||||
window.refreshButton = refreshButton
|
||||
end
|
||||
|
||||
local header = CreateFrame("Frame", nil, content)
|
||||
header:SetPoint("TOPLEFT", detailText, "BOTTOMLEFT", 0, -14)
|
||||
header:SetPoint("TOPRIGHT", content, "TOPRIGHT", -24, -96)
|
||||
header:SetHeight(18)
|
||||
window.header = header
|
||||
|
||||
local nameHeader = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
nameHeader:SetPoint("LEFT", header, "LEFT", 24, 0)
|
||||
nameHeader:SetText(L["VERSION_WINDOW_COLUMN_PLAYER"] or "Player")
|
||||
|
||||
local versionHeader = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
versionHeader:SetPoint("LEFT", header, "LEFT", 250, 0)
|
||||
versionHeader:SetText(L["VERSION_WINDOW_COLUMN_VERSION"] or "Version")
|
||||
|
||||
local protocolHeader = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
protocolHeader:SetPoint("LEFT", header, "LEFT", 410, 0)
|
||||
protocolHeader:SetText(L["VERSION_WINDOW_COLUMN_PROTOCOL"] or "Protocol")
|
||||
|
||||
local scrollFrame = CreateFrame("ScrollFrame", nil, content, "UIPanelScrollFrameTemplate")
|
||||
scrollFrame:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -6)
|
||||
scrollFrame:SetPoint("BOTTOMRIGHT", content, "BOTTOMRIGHT", -28, 24)
|
||||
window.scrollFrame = scrollFrame
|
||||
|
||||
local scrollChild = CreateFrame("Frame", nil, scrollFrame)
|
||||
scrollChild:SetSize(1, 1)
|
||||
scrollFrame:SetScrollChild(scrollChild)
|
||||
window.scrollChild = scrollChild
|
||||
|
||||
self.versionNoticeWindow = window
|
||||
return window
|
||||
end
|
||||
@@ -67,36 +311,16 @@ function HMGT:ShowVersionMismatchPopup(playerName, detail, sourceTag, opts)
|
||||
}
|
||||
end
|
||||
|
||||
local info = self.latestVersionMismatch or {}
|
||||
local window = self:EnsureVersionNoticeWindow()
|
||||
if not window then
|
||||
return
|
||||
end
|
||||
local hasMismatch = info.playerName or info.detail
|
||||
|
||||
window:SetTitle(L["VERSION_WINDOW_TITLE"] or "HMGT Version Check")
|
||||
|
||||
if hasMismatch then
|
||||
window.messageText:SetText(L["VERSION_WINDOW_MESSAGE"] or "A new version of Hail Mary Guild Tools is available.")
|
||||
window.detailText:SetText(string.format(
|
||||
L["VERSION_WINDOW_DETAIL"] or "Detected via %s from %s.\n%s",
|
||||
tostring(info.sourceTag or "?"),
|
||||
tostring(info.playerName or UNKNOWN),
|
||||
tostring(info.detail or "")
|
||||
))
|
||||
else
|
||||
window.messageText:SetText(L["VERSION_WINDOW_NO_MISMATCH"] or "No newer HMGT version has been detected in your current group.")
|
||||
window.detailText:SetText(string.format(
|
||||
L["VERSION_WINDOW_CURRENT"] or "Current version: %s | Protocol: %s",
|
||||
tostring(HMGT.ADDON_VERSION or "dev"),
|
||||
tostring(HMGT.PROTOCOL_VERSION or "?")
|
||||
))
|
||||
end
|
||||
|
||||
self:DevTrace("Version", hasMismatch and "window_show_mismatch" or "window_show_current", {
|
||||
player = info.playerName,
|
||||
source = info.sourceTag,
|
||||
detail = info.detail,
|
||||
self:RefreshVersionNoticeWindow()
|
||||
self:DevTrace("Version", "window_show", {
|
||||
player = playerName,
|
||||
source = sourceTag,
|
||||
detail = detail,
|
||||
})
|
||||
window:Show()
|
||||
window:Raise()
|
||||
|
||||
Reference in New Issue
Block a user