修复猎人野兽训练展示技能所需训练点数错误问题
修复拾取问题 修复其他已知问题 修复自动下马问题以及带来的猎人守护自动关闭问题 彻底修复拾取界面问题 修复目标框架的施法条监控 修复其他已知问题 调整dps插件对仇恨的估算方式 优化dps插件 修复远程攻击条问题
This commit is contained in:
264
Chat.lua
264
Chat.lua
@@ -374,12 +374,23 @@ function SFrames:RefreshClassColorCache()
|
||||
PersistClassCache()
|
||||
end
|
||||
|
||||
SFrames._classMissCache = {}
|
||||
SFrames._classMissCacheTime = 0
|
||||
|
||||
function SFrames:GetClassHexForName(name)
|
||||
if not name or name == "" then return nil end
|
||||
local cache = self.PlayerClassColorCache
|
||||
if cache[name] then return cache[name] end
|
||||
if self._classMissCache[name] then return nil end
|
||||
self:RefreshClassColorCache()
|
||||
return cache[name]
|
||||
if cache[name] then return cache[name] end
|
||||
self._classMissCache[name] = true
|
||||
local now = GetTime()
|
||||
if now - self._classMissCacheTime > 30 then
|
||||
self._classMissCacheTime = now
|
||||
self._classMissCache = {}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SFrames:GetLevelForName(name)
|
||||
@@ -730,27 +741,24 @@ end
|
||||
|
||||
local function ParseHardcoreDeathMessage(text)
|
||||
if type(text) ~= "string" or text == "" then return nil end
|
||||
if not string.find(text, "硬核") and not string.find(text, "死亡") then
|
||||
local lower = string.lower(text)
|
||||
if not string.find(lower, "hc news") and not string.find(lower, "has fallen")
|
||||
and not string.find(lower, "died") and not string.find(lower, "slain") then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local clean = string.gsub(text, "|c%x%x%x%x%x%x%x%x", "")
|
||||
clean = string.gsub(clean, "|r", "")
|
||||
|
||||
-- Check for Hardcore death signatures
|
||||
if string.find(string.lower(clean), "hc news") or string.find(clean, "硬核") or string.find(clean, "死亡") or string.find(string.lower(clean), "has fallen") or string.find(string.lower(clean), "died") or string.find(string.lower(clean), "slain") then
|
||||
-- Turtle English "Level 14"
|
||||
local _, _, lvlStr = string.find(clean, "Level%s+(%d+)")
|
||||
if lvlStr then return tonumber(lvlStr) end
|
||||
|
||||
-- Chinese "14级"
|
||||
local _, _, lvlStr2 = string.find(clean, "(%d+)%s*级")
|
||||
if lvlStr2 then return tonumber(lvlStr2) end
|
||||
|
||||
-- Fallback
|
||||
local _, _, lvlStr3 = string.find(clean, "Level:%s+(%d+)")
|
||||
if lvlStr3 then return tonumber(lvlStr3) end
|
||||
|
||||
-- If it matches death signatures but no level is found, return 1 as a baseline to trigger the filter.
|
||||
if string.find(string.lower(clean), "hc news") or (string.find(clean, "硬核") and (string.find(clean, "死亡") or string.find(clean, "has fallen"))) then
|
||||
return 1
|
||||
end
|
||||
local _, _, lvlStr = string.find(clean, "Level%s+(%d+)")
|
||||
if lvlStr then return tonumber(lvlStr) end
|
||||
local _, _, lvlStr2 = string.find(clean, "(%d+)%s*级")
|
||||
if lvlStr2 then return tonumber(lvlStr2) end
|
||||
local _, _, lvlStr3 = string.find(clean, "Level:%s+(%d+)")
|
||||
if lvlStr3 then return tonumber(lvlStr3) end
|
||||
local lower = string.lower(clean)
|
||||
if string.find(lower, "hc news") or (string.find(clean, "硬核") and (string.find(clean, "死亡") or string.find(lower, "has fallen"))) then
|
||||
return 1
|
||||
end
|
||||
return nil
|
||||
end
|
||||
@@ -1527,6 +1535,8 @@ local function EnsureDB()
|
||||
if type(db.editBoxPosition) ~= "string" then db.editBoxPosition = DEFAULTS.editBoxPosition end
|
||||
if type(db.editBoxX) ~= "number" then db.editBoxX = DEFAULTS.editBoxX end
|
||||
if type(db.editBoxY) ~= "number" then db.editBoxY = DEFAULTS.editBoxY end
|
||||
if db.translateEnabled == nil then db.translateEnabled = true end
|
||||
if db.chatMonitorEnabled == nil then db.chatMonitorEnabled = true end
|
||||
if type(db.layoutVersion) ~= "number" then db.layoutVersion = 1 end
|
||||
if db.layoutVersion < 2 then
|
||||
db.topPadding = DEFAULTS.topPadding
|
||||
@@ -3137,6 +3147,7 @@ function SFrames.Chat:ToggleConfigFrame()
|
||||
end
|
||||
|
||||
local CONFIG_PAGE_ORDER = {
|
||||
{ key = "general", label = "通用", title = "通用设置", desc = "翻译引擎和聊天消息监控的总开关。", icon = "settings" },
|
||||
{ key = "window", label = "窗口", title = "聊天窗口", desc = "尺寸、缩放、边框和输入框位置。", icon = "settings" },
|
||||
{ key = "tabs", label = "标签", title = "标签管理", desc = "切换、重命名、新建和删除聊天标签。", icon = "chat" },
|
||||
{ key = "filters", label = "过滤", title = "消息过滤", desc = "为当前标签设置消息类型和频道接收规则。", icon = "settings" },
|
||||
@@ -3442,6 +3453,57 @@ function SFrames.Chat:EnsureConfigFrame()
|
||||
return page
|
||||
end
|
||||
|
||||
local generalPage = CreatePage("general")
|
||||
do
|
||||
local engineSection = CreateCfgSection(generalPage, "翻译引擎", 0, 0, 584, 120, fontPath)
|
||||
|
||||
AddControl(CreateCfgCheck(engineSection, "启用 AI 翻译引擎", 16, -30,
|
||||
function() return EnsureDB().translateEnabled ~= false end,
|
||||
function(checked)
|
||||
EnsureDB().translateEnabled = (checked == true)
|
||||
end,
|
||||
function()
|
||||
SFrames.Chat:RefreshConfigFrame()
|
||||
end
|
||||
))
|
||||
|
||||
local transDesc = engineSection:CreateFontString(nil, "OVERLAY")
|
||||
transDesc:SetFont(fontPath, 10, "OUTLINE")
|
||||
transDesc:SetPoint("TOPLEFT", engineSection, "TOPLEFT", 38, -50)
|
||||
transDesc:SetWidth(520)
|
||||
transDesc:SetJustifyH("LEFT")
|
||||
transDesc:SetText("关闭后将完全停止调用 STranslateAPI 翻译接口,所有标签的自动翻译均不生效。")
|
||||
transDesc:SetTextColor(0.7, 0.7, 0.74)
|
||||
|
||||
local monitorSection = CreateCfgSection(generalPage, "聊天消息监控", 0, -136, 584, 160, fontPath)
|
||||
|
||||
AddControl(CreateCfgCheck(monitorSection, "启用聊天消息监控与收集", 16, -30,
|
||||
function() return EnsureDB().chatMonitorEnabled ~= false end,
|
||||
function(checked)
|
||||
EnsureDB().chatMonitorEnabled = (checked == true)
|
||||
end,
|
||||
function()
|
||||
SFrames.Chat:RefreshConfigFrame()
|
||||
end
|
||||
))
|
||||
|
||||
local monDesc = monitorSection:CreateFontString(nil, "OVERLAY")
|
||||
monDesc:SetFont(fontPath, 10, "OUTLINE")
|
||||
monDesc:SetPoint("TOPLEFT", monitorSection, "TOPLEFT", 38, -50)
|
||||
monDesc:SetWidth(520)
|
||||
monDesc:SetJustifyH("LEFT")
|
||||
monDesc:SetText("启用后将拦截聊天消息,提供消息历史缓存、右键复制 [+] 标记、频道翻译触发等功能。\n关闭后消息将原样通过,不做任何处理(翻译、复制等功能不可用)。")
|
||||
monDesc:SetTextColor(0.7, 0.7, 0.74)
|
||||
|
||||
local reloadHint = monitorSection:CreateFontString(nil, "OVERLAY")
|
||||
reloadHint:SetFont(fontPath, 10, "OUTLINE")
|
||||
reloadHint:SetPoint("TOPLEFT", monitorSection, "TOPLEFT", 38, -86)
|
||||
reloadHint:SetWidth(520)
|
||||
reloadHint:SetJustifyH("LEFT")
|
||||
reloadHint:SetText("提示:更改监控开关后建议 /reload 以确保完全生效。")
|
||||
reloadHint:SetTextColor(0.9, 0.75, 0.5)
|
||||
end
|
||||
|
||||
local windowPage = CreatePage("window")
|
||||
do
|
||||
local appearance = CreateCfgSection(windowPage, "窗口外观", 0, 0, 584, 274, fontPath)
|
||||
@@ -6562,26 +6624,42 @@ function SFrames.Chat:Initialize()
|
||||
end
|
||||
end
|
||||
|
||||
-- Helper: save a message to the persistent cache ring buffer
|
||||
local _persistWriteIdx = table.getn(db.messageCache)
|
||||
local function PersistMessage(msgID, text, r, g, b, frameIndex)
|
||||
local cache = EnsureDB().messageCache
|
||||
if not cache then
|
||||
EnsureDB().messageCache = {}
|
||||
cache = EnsureDB().messageCache
|
||||
end
|
||||
table.insert(cache, {
|
||||
id = msgID,
|
||||
text = text,
|
||||
r = r,
|
||||
g = g,
|
||||
b = b,
|
||||
frame = frameIndex or 1,
|
||||
time = date("%H:%M:%S"),
|
||||
})
|
||||
-- Trim to MAX_CACHE
|
||||
while table.getn(cache) > MAX_CACHE do
|
||||
table.remove(cache, 1)
|
||||
_persistWriteIdx = _persistWriteIdx + 1
|
||||
if _persistWriteIdx > MAX_CACHE then
|
||||
_persistWriteIdx = 1
|
||||
end
|
||||
local entry = cache[_persistWriteIdx]
|
||||
if entry then
|
||||
entry.id = msgID
|
||||
entry.text = text
|
||||
entry.r = r
|
||||
entry.g = g
|
||||
entry.b = b
|
||||
entry.frame = frameIndex or 1
|
||||
entry.time = date("%H:%M:%S")
|
||||
else
|
||||
cache[_persistWriteIdx] = {
|
||||
id = msgID,
|
||||
text = text,
|
||||
r = r,
|
||||
g = g,
|
||||
b = b,
|
||||
frame = frameIndex or 1,
|
||||
time = date("%H:%M:%S"),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local _cfTabCache = {}
|
||||
for i = 1, 7 do
|
||||
_cfTabCache[_G["ChatFrame" .. i]] = i
|
||||
end
|
||||
|
||||
for i = 1, 7 do
|
||||
@@ -6594,13 +6672,28 @@ function SFrames.Chat:Initialize()
|
||||
origAddMessage(self, text, r, g, b, alpha, holdTime)
|
||||
return
|
||||
end
|
||||
if string.sub(text, 1, 10) ~= "|Hsfchat:" and string.sub(text, 1, 12) ~= "|cff888888|H" then
|
||||
if EnsureDB().chatMonitorEnabled == false then
|
||||
origAddMessage(self, text, r, g, b, alpha, holdTime)
|
||||
return
|
||||
end
|
||||
local b1 = string.byte(text, 1)
|
||||
if b1 == 124 then
|
||||
local b2 = string.byte(text, 2)
|
||||
if b2 == 72 and string.find(text, "^|Hsfchat:") then
|
||||
origAddMessage(self, text, r, g, b, alpha, holdTime)
|
||||
return
|
||||
end
|
||||
if b2 == 99 and string.find(text, "^|cff888888|H") then
|
||||
origAddMessage(self, text, r, g, b, alpha, holdTime)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local db = EnsureDB()
|
||||
-- Universal catch for Turtle WoW custom chat channels like [硬核]
|
||||
local chanName = GetChannelNameFromChatLine(text)
|
||||
|
||||
if chanName and IsIgnoredChannelByDefault(chanName) then
|
||||
-- Global HC kill switch override check
|
||||
if db.hcGlobalDisable then
|
||||
local lowerChan = string.lower(chanName)
|
||||
if string.find(lowerChan, "hc") or string.find(chanName, "硬核") or string.find(lowerChan, "hardcore") then
|
||||
@@ -6608,46 +6701,32 @@ function SFrames.Chat:Initialize()
|
||||
end
|
||||
end
|
||||
|
||||
local frameName = self:GetName()
|
||||
local matchedTabIdx = nil
|
||||
if type(frameName) == "string" and string.find(frameName, "^ChatFrame%d+$") then
|
||||
matchedTabIdx = SFrames.Chat:GetTabIndexForChatFrame(self)
|
||||
if not matchedTabIdx then
|
||||
local _, _, frameNumStr = string.find(frameName, "^ChatFrame(%d+)$")
|
||||
local frameNum = tonumber(frameNumStr)
|
||||
if frameNum then
|
||||
local db = EnsureDB()
|
||||
if frameNum <= table.getn(db.tabs) then
|
||||
matchedTabIdx = frameNum
|
||||
end
|
||||
end
|
||||
end
|
||||
local matchedTabIdx = _cfTabCache[self]
|
||||
or SFrames.Chat:GetTabIndexForChatFrame(self)
|
||||
if not matchedTabIdx then
|
||||
return
|
||||
end
|
||||
if matchedTabIdx then
|
||||
local tab = EnsureDB().tabs[matchedTabIdx]
|
||||
if tab then
|
||||
if not SFrames.Chat:GetTabChannelFilter(matchedTabIdx, chanName) then
|
||||
return
|
||||
local tabs = db.tabs
|
||||
local tab = tabs and tabs[matchedTabIdx]
|
||||
if tab then
|
||||
if not SFrames.Chat:GetTabChannelFilter(matchedTabIdx, chanName) then
|
||||
return
|
||||
end
|
||||
local shouldTranslate = SFrames.Chat:GetTabChannelTranslateFilter(matchedTabIdx, chanName)
|
||||
if shouldTranslate then
|
||||
local cleanText = CleanTextForTranslation(text)
|
||||
cleanText = string.gsub(cleanText, "^%[.-%]%s*", "")
|
||||
local _, _, senderName = string.find(cleanText, "^%[([^%]]+)%]:%s*")
|
||||
if senderName then
|
||||
cleanText = string.gsub(cleanText, "^%[[^%]]+%]:%s*", "")
|
||||
end
|
||||
-- If it passed channel filter, allow translation for these bypassed channels
|
||||
local shouldTranslate = SFrames.Chat:GetTabChannelTranslateFilter(matchedTabIdx, chanName)
|
||||
if shouldTranslate then
|
||||
local cleanText = CleanTextForTranslation(text)
|
||||
-- Remove the channel prefix from translation text to be clean
|
||||
cleanText = string.gsub(cleanText, "^%[.-%]%s*", "")
|
||||
-- It might also have [PlayerName]:
|
||||
local _, _, senderName = string.find(cleanText, "^%[([^%]]+)%]:%s*")
|
||||
if senderName then
|
||||
cleanText = string.gsub(cleanText, "^%[[^%]]+%]:%s*", "")
|
||||
end
|
||||
if cleanText ~= "" then
|
||||
local tabId = tab.id
|
||||
SFrames.Chat:RequestAutoTranslation(cleanText, function(result)
|
||||
if result and result ~= "" then
|
||||
SFrames.Chat:AppendAutoTranslatedLine(tabId, "channel", chanName, cleanText, result, senderName)
|
||||
end
|
||||
end)
|
||||
end
|
||||
if cleanText ~= "" then
|
||||
local tabId = tab.id
|
||||
SFrames.Chat:RequestAutoTranslation(cleanText, function(result)
|
||||
if result and result ~= "" then
|
||||
SFrames.Chat:AppendAutoTranslatedLine(tabId, "channel", chanName, cleanText, result, senderName)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -6655,7 +6734,6 @@ function SFrames.Chat:Initialize()
|
||||
end
|
||||
end
|
||||
|
||||
-- Hardcore Death Event Overrides
|
||||
if db.hcDeathDisable or (db.hcDeathLevelMin and db.hcDeathLevelMin > 1) then
|
||||
local deathLvl = ParseHardcoreDeathMessage(text)
|
||||
if deathLvl then
|
||||
@@ -6667,47 +6745,13 @@ function SFrames.Chat:Initialize()
|
||||
SFrames.Chat.MessageIndex = SFrames.Chat.MessageIndex + 1
|
||||
local msgID = SFrames.Chat.MessageIndex
|
||||
|
||||
-- Store in runtime lookup
|
||||
SFrames.Chat.MessageHistory[msgID] = text
|
||||
|
||||
-- Persist to SavedVariables
|
||||
local frameIdx = nil
|
||||
for fi = 1, 7 do
|
||||
if self == _G["ChatFrame" .. fi] then
|
||||
frameIdx = fi
|
||||
break
|
||||
end
|
||||
end
|
||||
PersistMessage(msgID, text, r, g, b, frameIdx)
|
||||
PersistMessage(msgID, text, r, g, b, _cfTabCache[self])
|
||||
|
||||
-- Apply class color to player names in message
|
||||
local coloredText = ColorPlayerNamesInText(text)
|
||||
-- Insert the clickable button [+] at the beginning
|
||||
local modifiedText = "|cff888888|Hsfchat:" .. msgID .. "|h[+]|h|r " .. coloredText
|
||||
origAddMessage(self, modifiedText, r, g, b, alpha, holdTime)
|
||||
|
||||
-- Legacy auto-translate disabled; handled by per-tab routing above.
|
||||
if false then
|
||||
if self == ChatFrame1 and not string.find(text, "%[翻译%]") then
|
||||
if string.find(text, "%[.-硬核.-%]") or string.find(string.lower(text), "%[.-hc.-%]") or string.find(string.lower(text), "%[.-hardcore.-%]") then
|
||||
local cleanText = string.gsub(text, "|c%x%x%x%x%x%x%x%x", "")
|
||||
cleanText = string.gsub(cleanText, "|r", "")
|
||||
cleanText = string.gsub(cleanText, "|H.-|h(.-)|h", "%1")
|
||||
|
||||
if _G.STranslateAPI and _G.STranslateAPI.IsReady and _G.STranslateAPI.IsReady() then
|
||||
_G.STranslateAPI.Translate(cleanText, "auto", "zh", function(result, err, meta)
|
||||
if result then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff[翻译] |cffffff00" .. tostring(result) .. "|r")
|
||||
end
|
||||
end, "Nanami-UI")
|
||||
elseif _G.STranslate and _G.STranslate.SendIO then
|
||||
_G.STranslate:SendIO(cleanText, "IN", "auto", "zh")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
origAddMessage(self, text, r, g, b, alpha, holdTime)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user