536 lines
12 KiB
Lua
536 lines
12 KiB
Lua
local mod = Chatter:NewModule("URL Copy", "AceHook-3.0")
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
|
mod.modName = L["URL Copy"]
|
|
|
|
local gsub = _G.string.gsub
|
|
local ipairs = _G.ipairs
|
|
local pairs = _G.pairs
|
|
local fmt = _G.string.format
|
|
local sub = _G.string.sub
|
|
|
|
local tlds
|
|
local style = "|cffffffff|Hurl:%s|h[%s]|h|r"
|
|
local function Link(link, ...)
|
|
if link == nil then
|
|
return ""
|
|
end
|
|
return mod:RegisterMatch(fmt(style, link, link))
|
|
end
|
|
local function Link_TLD(link, tld, ...)
|
|
if link == nil or tld == nil then
|
|
return ""
|
|
end
|
|
if tlds[tld:upper()] then
|
|
return mod:RegisterMatch(fmt(style, link, link))
|
|
else
|
|
return mod:RegisterMatch(link)
|
|
end
|
|
end
|
|
|
|
local patterns = {
|
|
-- X://Y url
|
|
{ pattern = "^(%a[%w%.+-]+://%S+)", matchfunc=Link},
|
|
{ pattern = "%f[%S](%a[%w%.+-]+://%S+)", matchfunc=Link},
|
|
-- www.X.Y url
|
|
{ pattern = "^(www%.[-%w_%%]+%.%S+)", matchfunc=Link},
|
|
{ pattern = "%f[%S](www%.[-%w_%%]+%.%S+)", matchfunc=Link},
|
|
-- "W X"@Y.Z email (this is seriously a valid email)
|
|
--{ pattern = '^(%"[^%"]+%"@[-%w_%%%.]+%.(%a%a+))', matchfunc=Link_TLD},
|
|
--{ pattern = '%f[%S](%"[^%"]+%"@[-%w_%%%.]+%.(%a%a+))', matchfunc=Link_TLD},
|
|
-- X@Y.Z email
|
|
{ pattern = "(%S+@[-%w_%%%.]+%.(%a%a+))", matchfunc=Link_TLD},
|
|
-- XXX.YYY.ZZZ.WWW:VVVV/UUUUU IPv4 address with port and path
|
|
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link},
|
|
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link},
|
|
-- XXX.YYY.ZZZ.WWW:VVVV IPv4 address with port (IP of ts server for example)
|
|
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link},
|
|
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link},
|
|
-- XXX.YYY.ZZZ.WWW/VVVVV IPv4 address with path
|
|
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%/%S+)", matchfunc=Link},
|
|
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%/%S+)", matchfunc=Link},
|
|
-- XXX.YYY.ZZZ.WWW IPv4 address
|
|
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%)%f[%D]", matchfunc=Link},
|
|
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%)%f[%D]", matchfunc=Link},
|
|
-- X.Y.Z:WWWW/VVVVV url with port and path
|
|
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link_TLD},
|
|
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link_TLD},
|
|
-- X.Y.Z:WWWW url with port (ts server for example)
|
|
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link_TLD},
|
|
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link_TLD},
|
|
-- X.Y.Z/WWWWW url with path
|
|
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+)/%S+)", matchfunc=Link_TLD},
|
|
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+)/%S+)", matchfunc=Link_TLD},
|
|
-- X.Y.Z url
|
|
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+))", matchfunc=Link_TLD},
|
|
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+))", matchfunc=Link_TLD},
|
|
}
|
|
|
|
local options = {
|
|
mangleMumble = {
|
|
type = "toggle",
|
|
name = L["Parse Mumble links"],
|
|
desc = L["Automatically inject your character's name into Mumble links, so you connect with your username prefilled."],
|
|
get = function() return mod.db.profile.mangleMumble end,
|
|
set = function(info, v) mod.db.profile.mangleMumble = v end
|
|
},
|
|
mangleTeamspeak = {
|
|
type = "toggle",
|
|
name = L["Parse Teamspeak 3 links"],
|
|
desc = L["Automatically inject your character's name into Teamspeak 3 links, so you connect with your username prefilled."],
|
|
get = function() return mod.db.profile.mangleTeamspeak end,
|
|
set = function(info, v) mod.db.profile.mangleTeamspeak = v end
|
|
}
|
|
}
|
|
|
|
do
|
|
|
|
local defaults = {
|
|
profile = {
|
|
mangleMumble = true,
|
|
mangleTeamspeak = true
|
|
}
|
|
}
|
|
local events = {
|
|
"CHAT_MSG_BATTLEGROUND", "CHAT_MSG_BATTLEGROUND_LEADER",
|
|
"CHAT_MSG_CHANNEL", "CHAT_MSG_EMOTE",
|
|
"CHAT_MSG_GUILD", "CHAT_MSG_OFFICER",
|
|
"CHAT_MSG_PARTY", "CHAT_MSG_RAID",
|
|
"CHAT_MSG_RAID_LEADER", "CHAT_MSG_RAID_WARNING", "CHAT_MSG_PARTY_LEADER",
|
|
"CHAT_MSG_SAY", "CHAT_MSG_WHISPER","CHAT_MSG_BN_WHISPER",
|
|
"CHAT_MSG_WHISPER_INFORM", "CHAT_MSG_YELL", "CHAT_MSG_BN_WHISPER_INFORM","CHAT_MSG_BN_CONVERSATION"
|
|
}
|
|
function mod:OnInitialize()
|
|
self.db = Chatter.db:RegisterNamespace("UrlCopy", defaults)
|
|
end
|
|
function mod:OnEnable()
|
|
for _,event in ipairs(events) do
|
|
ChatFrame_AddMessageEventFilter(event, self.filterFunc)
|
|
end
|
|
self:RawHook("SetItemRef", true)
|
|
end
|
|
function mod:OnDisable()
|
|
for _,event in ipairs(events) do
|
|
ChatFrame_RemoveMessageEventFilter(event, self.filterFunc)
|
|
end
|
|
end
|
|
end
|
|
|
|
do
|
|
local tokennum, matchTable = 1, {}
|
|
mod.filterFunc = function(frame, event, msg, ...)
|
|
if not msg then return false, msg, ... end
|
|
for i, v in ipairs(patterns) do
|
|
msg = gsub(msg, v.pattern, v.matchfunc)
|
|
end
|
|
for k,v in pairs(matchTable) do
|
|
msg = gsub(msg, k, v)
|
|
matchTable[k] = nil
|
|
end
|
|
return false, msg, ...
|
|
end
|
|
function mod:RegisterMatch(text)
|
|
local token = "\255\254\253"..tokennum.."\253\254\255"
|
|
matchTable[token] = gsub(text, "%%", "%%%%")
|
|
tokennum = tokennum + 1
|
|
return token
|
|
end
|
|
end
|
|
|
|
--[[ Popup Box ]]--
|
|
local currentLink
|
|
|
|
StaticPopupDialogs["ChatterUrlCopyDialog"] = {
|
|
text = "URL - Ctrl-C to copy",
|
|
button2 = CLOSE,
|
|
hasEditBox = 1,
|
|
hasWideEditBox = 1,
|
|
OnShow = function()
|
|
local editBox = _G[this:GetName().."WideEditBox"]
|
|
if editBox then
|
|
editBox:SetText(currentLink)
|
|
editBox:SetFocus()
|
|
editBox:HighlightText(0)
|
|
end
|
|
local button = _G[this:GetName().."Button2"]
|
|
if button then
|
|
button:ClearAllPoints()
|
|
button:SetWidth(200)
|
|
button:SetPoint("CENTER", editBox, "CENTER", 0, -30)
|
|
end
|
|
end,
|
|
EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
|
|
timeout = 0,
|
|
whileDead = 1,
|
|
hideOnEscape = 1,
|
|
maxLetters=1024, -- this otherwise gets cached from other dialogs which caps it at 10..20..30...
|
|
}
|
|
|
|
local mangleLinkForVoiceChat
|
|
do
|
|
--[[
|
|
mumble://192.168.1.102:50008?version=1.2.0
|
|
mumble://foo:bar@192.168.1.102:50008?version=1.2.0
|
|
mumble://:bar@192.168.1.102:50008?version=1.2.0
|
|
]]--
|
|
|
|
-- Messes with Mumble links to inject our own username. Nifty magical!
|
|
local function injectCharacterNameForMumble(scheme, connstr)
|
|
local pre, post = strsplit("@", connstr, 2)
|
|
local new
|
|
if post then
|
|
local user, password = strsplit(":", pre, 2)
|
|
if password then
|
|
new = UnitName("player") .. ":" .. password
|
|
else
|
|
new = UnitName("player")
|
|
end
|
|
new = new .. "@" .. post
|
|
else
|
|
new = UnitName("player") .. "@" .. pre
|
|
end
|
|
return scheme .. new
|
|
end
|
|
|
|
local buff = {}
|
|
local function addTS3Nickname(...)
|
|
wipe(buff)
|
|
for i = 1, select("#", ...) do
|
|
local chunk = select(i, ...)
|
|
local key, val = strsplit("=", chunk, 2)
|
|
if val then
|
|
if strlower(key) ~= "nickname" then
|
|
tinsert(buff, chunk)
|
|
end
|
|
end
|
|
end
|
|
if not gotName then
|
|
local nick = "nickname=" .. UnitName("player")
|
|
tinsert(buff, nick)
|
|
end
|
|
return table.concat(buff, "&")
|
|
end
|
|
|
|
--[[
|
|
ts3server://ts3.hoster.com
|
|
ts3server://ts3.hoster.com?
|
|
ts3server://ts3.hoster.com?port=9987&
|
|
ts3server://ts3.hoster.com?port=9987&nickname=UserNickname&password=serverPassword
|
|
]]--
|
|
|
|
local function injectCharacterNameForTeamspeak(scheme, connstr)
|
|
local url, query = strsplit("?", connstr, 2)
|
|
if query then
|
|
query = addTS3Nickname(strsplit("&", query))
|
|
else
|
|
query = "nickname=" .. UnitName("player")
|
|
end
|
|
return scheme .. url .. "?" .. query
|
|
end
|
|
|
|
function mangleLinkForVoiceChat(text)
|
|
if mod.db.profile.mangleMumble then
|
|
text = text:gsub("^(mumble://)([^/?]+)", injectCharacterNameForMumble)
|
|
end
|
|
if mod.db.profile.mangleTeamspeak then
|
|
text = text:gsub("^(ts3server://)(.+)", injectCharacterNameForTeamspeak)
|
|
end
|
|
return text
|
|
end
|
|
end
|
|
|
|
|
|
function mod:SetItemRef(link, text, button)
|
|
if sub(link, 1, 3) == "url" then
|
|
currentLink = sub(link, 5)
|
|
currentLink = mangleLinkForVoiceChat(currentLink)
|
|
|
|
StaticPopup_Show("ChatterUrlCopyDialog")
|
|
return
|
|
end
|
|
return self.hooks.SetItemRef(link, text, button)
|
|
end
|
|
|
|
function mod:Info()
|
|
return L["Lets you copy URLs out of chat."]
|
|
end
|
|
|
|
function mod:GetOptions()
|
|
return options
|
|
end
|
|
|
|
tlds = {
|
|
ONION = true,
|
|
-- Copied from http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
|
-- Version 2008041301, Last Updated Mon Apr 21 08:07:00 2008 UTC
|
|
AC = true,
|
|
AD = true,
|
|
AE = true,
|
|
AERO = true,
|
|
AF = true,
|
|
AG = true,
|
|
AI = true,
|
|
AL = true,
|
|
AM = true,
|
|
AN = true,
|
|
AO = true,
|
|
AQ = true,
|
|
AR = true,
|
|
ARPA = true,
|
|
AS = true,
|
|
ASIA = true,
|
|
AT = true,
|
|
AU = true,
|
|
AW = true,
|
|
AX = true,
|
|
AZ = true,
|
|
BA = true,
|
|
BB = true,
|
|
BD = true,
|
|
BE = true,
|
|
BF = true,
|
|
BG = true,
|
|
BH = true,
|
|
BI = true,
|
|
BIZ = true,
|
|
BJ = true,
|
|
BM = true,
|
|
BN = true,
|
|
BO = true,
|
|
BR = true,
|
|
BS = true,
|
|
BT = true,
|
|
BV = true,
|
|
BW = true,
|
|
BY = true,
|
|
BZ = true,
|
|
CA = true,
|
|
CAT = true,
|
|
CC = true,
|
|
CD = true,
|
|
CF = true,
|
|
CG = true,
|
|
CH = true,
|
|
CI = true,
|
|
CK = true,
|
|
CL = true,
|
|
CM = true,
|
|
CN = true,
|
|
CO = true,
|
|
COM = true,
|
|
COOP = true,
|
|
CR = true,
|
|
CU = true,
|
|
CV = true,
|
|
CX = true,
|
|
CY = true,
|
|
CZ = true,
|
|
DE = true,
|
|
DJ = true,
|
|
DK = true,
|
|
DM = true,
|
|
DO = true,
|
|
DZ = true,
|
|
EC = true,
|
|
EDU = true,
|
|
EE = true,
|
|
EG = true,
|
|
ER = true,
|
|
ES = true,
|
|
ET = true,
|
|
EU = true,
|
|
FI = true,
|
|
FJ = true,
|
|
FK = true,
|
|
FM = true,
|
|
FO = true,
|
|
FR = true,
|
|
GA = true,
|
|
GB = true,
|
|
GD = true,
|
|
GE = true,
|
|
GF = true,
|
|
GG = true,
|
|
GH = true,
|
|
GI = true,
|
|
GL = true,
|
|
GM = true,
|
|
GN = true,
|
|
GOV = true,
|
|
GP = true,
|
|
GQ = true,
|
|
GR = true,
|
|
GS = true,
|
|
GT = true,
|
|
GU = true,
|
|
GW = true,
|
|
GY = true,
|
|
HK = true,
|
|
HM = true,
|
|
HN = true,
|
|
HR = true,
|
|
HT = true,
|
|
HU = true,
|
|
ID = true,
|
|
IE = true,
|
|
IL = true,
|
|
IM = true,
|
|
IN = true,
|
|
INFO = true,
|
|
INT = true,
|
|
IO = true,
|
|
IQ = true,
|
|
IR = true,
|
|
IS = true,
|
|
IT = true,
|
|
JE = true,
|
|
JM = true,
|
|
JO = true,
|
|
JOBS = true,
|
|
JP = true,
|
|
KE = true,
|
|
KG = true,
|
|
KH = true,
|
|
KI = true,
|
|
KM = true,
|
|
KN = true,
|
|
KP = true,
|
|
KR = true,
|
|
KW = true,
|
|
KY = true,
|
|
KZ = true,
|
|
LA = true,
|
|
LB = true,
|
|
LC = true,
|
|
LI = true,
|
|
LK = true,
|
|
LR = true,
|
|
LS = true,
|
|
LT = true,
|
|
LU = true,
|
|
LV = true,
|
|
LY = true,
|
|
MA = true,
|
|
MC = true,
|
|
MD = true,
|
|
ME = true,
|
|
MG = true,
|
|
MH = true,
|
|
MIL = true,
|
|
MK = true,
|
|
ML = true,
|
|
MM = true,
|
|
MN = true,
|
|
MO = true,
|
|
MOBI = true,
|
|
MP = true,
|
|
MQ = true,
|
|
MR = true,
|
|
MS = true,
|
|
MT = true,
|
|
MU = true,
|
|
MUSEUM = true,
|
|
MV = true,
|
|
MW = true,
|
|
MX = true,
|
|
MY = true,
|
|
MZ = true,
|
|
NA = true,
|
|
NAME = true,
|
|
NC = true,
|
|
NE = true,
|
|
NET = true,
|
|
NF = true,
|
|
NG = true,
|
|
NI = true,
|
|
NL = true,
|
|
NO = true,
|
|
NP = true,
|
|
NR = true,
|
|
NU = true,
|
|
NZ = true,
|
|
OM = true,
|
|
ORG = true,
|
|
PA = true,
|
|
PE = true,
|
|
PF = true,
|
|
PG = true,
|
|
PH = true,
|
|
PK = true,
|
|
PL = true,
|
|
PM = true,
|
|
PN = true,
|
|
PR = true,
|
|
PRO = true,
|
|
PS = true,
|
|
PT = true,
|
|
PW = true,
|
|
PY = true,
|
|
QA = true,
|
|
RE = true,
|
|
RO = true,
|
|
RS = true,
|
|
RU = true,
|
|
RW = true,
|
|
SA = true,
|
|
SB = true,
|
|
SC = true,
|
|
SD = true,
|
|
SE = true,
|
|
SG = true,
|
|
SH = true,
|
|
SI = true,
|
|
SJ = true,
|
|
SK = true,
|
|
SL = true,
|
|
SM = true,
|
|
SN = true,
|
|
SO = true,
|
|
SR = true,
|
|
ST = true,
|
|
SU = true,
|
|
SV = true,
|
|
SY = true,
|
|
SZ = true,
|
|
TC = true,
|
|
TD = true,
|
|
TEL = true,
|
|
TF = true,
|
|
TG = true,
|
|
TH = true,
|
|
TJ = true,
|
|
TK = true,
|
|
TL = true,
|
|
TM = true,
|
|
TN = true,
|
|
TO = true,
|
|
TP = true,
|
|
TR = true,
|
|
TRAVEL = true,
|
|
TT = true,
|
|
TV = true,
|
|
TW = true,
|
|
TZ = true,
|
|
UA = true,
|
|
UG = true,
|
|
UK = true,
|
|
UM = true,
|
|
US = true,
|
|
UY = true,
|
|
UZ = true,
|
|
VA = true,
|
|
VC = true,
|
|
VE = true,
|
|
VG = true,
|
|
VI = true,
|
|
VN = true,
|
|
VU = true,
|
|
WF = true,
|
|
WS = true,
|
|
YE = true,
|
|
YT = true,
|
|
YU = true,
|
|
ZA = true,
|
|
ZM = true,
|
|
ZW = true,
|
|
}
|