LINK_HANDLER = ZO_CallbackObject:New() LINK_HANDLER.INSERT_LINK_EVENT = "ZO_LinkHandler_InsertLinkEvent" LINK_HANDLER.LINK_CLICKED_EVENT = "ZO_LinkHandler_LinkClickedEvent" LINK_HANDLER.LINK_MOUSE_UP_EVENT = "ZO_LinkHandler_LinkMouseUpEvent" LINK_HANDLER.LINK_NOT_HANDLED_EVENT = "ZO_LinkHandler_NotHandledEvent" ITEM_LINK_TYPE = "item" ACHIEVEMENT_LINK_TYPE = "achievement" CHARACTER_LINK_TYPE = "character" CHANNEL_LINK_TYPE = "channel" BOOK_LINK_TYPE = "book" DISPLAY_NAME_LINK_TYPE = "display" URL_LINK_TYPE = "url" COLLECTIBLE_LINK_TYPE = "collectible" GUILD_LINK_TYPE = "guild" HELP_LINK_TYPE = "help" HOUSING_LINK_TYPE = "housing" ABILITY_LINK_TYPE = "ability" CRAFTED_ABILITY_LINK_TYPE = "crafted_ability" ZO_VALID_LINK_TYPES_CHAT = { [ACHIEVEMENT_LINK_TYPE] = true, [COLLECTIBLE_LINK_TYPE] = true, [GUILD_LINK_TYPE] = true, [HELP_LINK_TYPE] = true, [HOUSING_LINK_TYPE] = true, [ITEM_LINK_TYPE] = true, [ABILITY_LINK_TYPE] = true, [CRAFTED_ABILITY_LINK_TYPE] = true, } function ZO_LinkHandler_InsertLink(link) if type(link) == "string" and #link > 0 then local text, color, linkType = ZO_LinkHandler_ParseLink(link) --todo: handle other link type sound cases if linkType == ITEM_LINK_TYPE then local soundCategory = GetItemSoundCategoryFromLink(link) if soundCategory then PlayItemSound(soundCategory, ITEM_SOUND_ACTION_SLOT) end end return LINK_HANDLER:FireCallbacks(LINK_HANDLER.INSERT_LINK_EVENT, link) end end function ZO_LinkHandler_InsertLinkAndSubmit(link) ZO_LinkHandler_InsertLink(link) local chatSystem = ZO_GetChatSystem() chatSystem:SubmitTextEntry() chatSystem:Maximize() end local function HandleLinkMouseEvent(link, button, control, eventType) if type(link) == "string" and #link > 0 then local handled = LINK_HANDLER:FireCallbacks(eventType, link, button, ZO_LinkHandler_ParseLink(link)) if not handled then LINK_HANDLER:FireCallbacks(LINK_HANDLER.LINK_NOT_HANDLED_EVENT, link, button, ZO_LinkHandler_ParseLink(link)) end end end function ZO_LinkHandler_OnLinkClicked(link, button, control) HandleLinkMouseEvent(link, button, control, LINK_HANDLER.LINK_CLICKED_EVENT) end function ZO_LinkHandler_OnLinkMouseUp(link, button, control) HandleLinkMouseEvent(link, button, control, LINK_HANDLER.LINK_MOUSE_UP_EVENT) end function ZO_LinkHandler_CreateLinkWithFormat(text, color, linkType, linkStyle, stringFormat, ...) --where ... is the data to encode if linkType then return (stringFormat):format(linkStyle, zo_strjoin(':', linkType, ...), text) end end function ZO_LinkHandler_CreateLink(text, color, linkType, ...) --where ... is the data to encode return ZO_LinkHandler_CreateLinkWithFormat(text, color, linkType, LINK_STYLE_BRACKETS, "|H%d:%s|h[%s]|h", ...) end function ZO_LinkHandler_CreateLinkWithoutBrackets(text, color, linkType, ...) --where ... is the data to encode return ZO_LinkHandler_CreateLinkWithFormat(text, color, linkType, LINK_STYLE_DEFAULT, "|H%d:%s|h%s|h", ...) end function ZO_LinkHandler_ParseLink(link) if type(link) == "string" then local linkStyle, data, text = link:match("|H(.-):(.-)|h(.-)|h") return text, linkStyle, zo_strsplit(':', data) end end function ZO_LinkHandler_ParseLinkData(link) -- Discard the return values for link text, link style and link type return select(4, ZO_LinkHandler_ParseLink(link)) end function ZO_LinkHandler_CreatePlayerLink(displayOrCharacterName) if(IsDecoratedDisplayName(displayOrCharacterName)) then return ZO_LinkHandler_CreateDisplayNameLink(displayOrCharacterName) else return ZO_LinkHandler_CreateCharacterLink(displayOrCharacterName) end end function ZO_LinkHandler_CreateDisplayNameLink(displayName) local undecoratedDisplayName if(not IsDecoratedDisplayName(displayName)) then undecoratedDisplayName = displayName displayName = DecorateDisplayName(displayName) else undecoratedDisplayName = UndecorateDisplayName(displayName) end local userFacingDisplayName = ZO_IsConsoleOrGameCoreUI() and undecoratedDisplayName or displayName return ZO_LinkHandler_CreateLink(userFacingDisplayName, nil, DISPLAY_NAME_LINK_TYPE, undecoratedDisplayName) end function ZO_LinkHandler_CreateCharacterLink(characterName) if ZO_IsConsoleOrGameCoreUI() then return string.format("[%s]", ZO_FormatUserFacingCharacterName(characterName)) else return ZO_LinkHandler_CreateLink(characterName, nil, CHARACTER_LINK_TYPE, characterName) end end function ZO_LinkHandler_CreateChannelLink(channelName) return ZO_LinkHandler_CreateLink(channelName, nil, CHANNEL_LINK_TYPE, channelName) end function ZO_LinkHandler_CreateURLLink(url, displayText) return ZO_LinkHandler_CreateLinkWithoutBrackets(displayText, nil, URL_LINK_TYPE, url) end local function AppendHelper(thingToAppend, size, nextElement, ...) if size == 0 then return thingToAppend end return nextElement, AppendHelper(thingToAppend, size - 1, ...) end local function Append(thingToAppend, ...) return AppendHelper(thingToAppend, select('#', ...), ...) end -- where ... are arguments to pass to linkFunction function ZO_LinkHandler_CreateChatLink(linkFunction, ...) return linkFunction(Append(LINK_STYLE_BRACKETS, ...)) end do local LINK_GMATCH_PATTERN = "|H.-|h.-|h" local LINK_TYPE_MATCH_PATTERN = "|H%d:(.-):" function ZO_ExtractLinksFromText(text, validLinkTypes, linksTable) for link in zo_strgmatch(text, LINK_GMATCH_PATTERN) do local linkType = zo_strmatch(link, LINK_TYPE_MATCH_PATTERN) if validLinkTypes[linkType] then table.insert(linksTable, { linkType = linkType, link = link }) end end end end