WOW_Collection_System/SM_Events.lua

580 lines
22 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- SM_Events.lua
-- 斜杠命令
SLASH_SM_COLLECTIONS1 = "/smcollections"
SLASH_SM_COLLECTIONS2 = "/sm收藏"
SlashCmdList["SM_COLLECTIONS"] = function()
if SM_Collections.MainFrame:IsVisible() then
SM_Collections.MainFrame:Hide()
else
SM_Collections.MainFrame:Show()
if not SM_Collections.CurrentTab then
SM_Collections:ShowTab(1)
end
end
end
-- 处理坐骑数据
function SM_Collections:HandleMountsData(msg)
local data = self:MessageSplit(msg, "|")
for i = 1, math.min(20, #data) do
end
local mounts = {}
for i = 1, #data, 4 do
if data[i] and data[i + 1] and data[i + 2] and data[i + 3] then
local mountID = tonumber(data[i])
-- 获取正确的显示ID
local displayID = nil
if SM_Collections.SpellToDisplayIDMap and SM_Collections.SpellToDisplayIDMap[mountID] then
displayID = SM_Collections.SpellToDisplayIDMap[mountID].effectMiscValue
end
-- 尝试从游戏中获取技能信息,添加错误处理
local spellName, spellRank, spellIcon
if mountID and type(mountID) == "number" and mountID > 0 then
-- 使用pcall安全地调用GetSpellInfo防止错误导致整个函数崩溃
local success, result = pcall(function()
return GetSpellInfo(mountID)
end)
if success and result then
spellName = result
_, _, spellIcon = GetSpellInfo(mountID) -- 再次调用获取图标
else
spellName = nil
spellIcon = nil
end
else
spellName = nil
spellIcon = nil
end
table.insert(mounts, {
id = mountID,
name = data[i + 1] or spellName or ("坐骑 #" .. mountID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
description = data[i + 2],
obtained = data[i + 3] == "1",
displayID = displayID, -- 存储正确的显示ID
spellName = spellName, -- 存储从GetSpellInfo获取的名称作为备用
icon = spellIcon -- 存储图标
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.mounts then
-- 创建假的response对象标记成功获取了数据
local response = {
success = true,
data = mounts
}
self.pendingCallbacks.mounts(response)
self.pendingCallbacks.mounts = nil
else
end
end
-- 处理属性数据
function SM_Collections:HandleAttributesData(msg)
local data = self:MessageSplit(msg, "|")
local attributes = {}
for i = 1, #data, 3 do
if data[i] and data[i + 1] and data[i + 2] then
table.insert(attributes, {
Name = data[i],
value = tonumber(data[i + 1]),
isPositive = data[i + 2] == "1"
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.attributes then
local response = {
success = true,
data = attributes
}
self.pendingCallbacks.attributes(response)
self.pendingCallbacks.attributes = nil
else
end
end
-- 处理物品属性数据
function SM_Collections:HandleItemAttributesData(msg)
local data = self:MessageSplit(msg, "|")
local attributes = {}
for i = 1, #data, 3 do
if data[i] and data[i + 1] and data[i + 2] then
table.insert(attributes, {
Name = data[i],
value = tonumber(data[i + 1]),
isPositive = data[i + 2] == "1"
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.item_attributes then
local response = {
success = true,
data = attributes
}
self.pendingCallbacks.item_attributes(response)
self.pendingCallbacks.item_attributes = nil
else
--
end
end
-- 处理小伙伴数据
function SM_Collections:HandleCompanionsData(msg)
local data = self:MessageSplit(msg, "|")
local companions = {}
for i = 1, #data, 4 do
if data[i] and data[i + 1] and data[i + 2] and data[i + 3] then
local companionID = tonumber(data[i])
-- 获取正确的显示ID
local displayID = nil
if SM_Collections.Companions and SM_Collections.Companions[companionID] then
displayID = SM_Collections.Companions[companionID].effectMiscValue
end
-- 尝试从游戏中获取技能信息,添加错误处理
local spellName, spellRank, spellIcon
if companionID and type(companionID) == "number" and companionID > 0 then
-- 使用pcall安全地调用GetSpellInfo防止错误导致整个函数崩溃
local success, result = pcall(function()
return GetSpellInfo(companionID)
end)
if success and result then
spellName = result
_, _, spellIcon = GetSpellInfo(companionID) -- 再次调用获取图标
else
spellName = nil
spellIcon = nil
end
else
--
spellName = nil
spellIcon = nil
end
table.insert(companions, {
id = companionID,
name = data[i + 1] or spellName or ("小伙伴 #" .. companionID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
description = data[i + 2],
obtained = data[i + 3] == "1",
displayID = displayID, -- 存储正确的显示ID
spellName = spellName, -- 存储从GetSpellInfo获取的名称作为备用
icon = spellIcon -- 存储图标
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.companions then
-- 创建假的response对象标记成功获取了数据
local response = {
success = true,
data = companions
}
self.pendingCallbacks.companions(response)
self.pendingCallbacks.companions = nil
else
--
end
end
-- 处理卡牌数据
function SM_Collections:HandleCardsData(msg)
local data = self:MessageSplit(msg, "|")
local cards = {}
-- 检查数据格式,尝试修复不规则的数据
if #data >= 4 then
local i = 1
while i <= #data do
local id, name, description, obtained
-- 尝试解析ID必须是数字
id = tonumber(data[i])
if id then
-- 获取名称
name = data[i + 1] or ""
-- 获取描述,如果描述不存在,尝试使用下一个字段
description = data[i + 2] or ""
-- 获取获得状态,尝试查找"1"或"0"
local obtainedStr = data[i + 3] or "0"
obtained = (obtainedStr == "1")
-- 创建卡牌对象
table.insert(cards, {
id = id,
name = name,
description = description,
obtained = obtained
})
-- 输出调试信息
end
-- 移动到下一组数据
i = i + 4
end
end
if self.pendingCallbacks and self.pendingCallbacks.cards then
local response = {
success = true,
data = cards
}
self.pendingCallbacks.cards(response)
self.pendingCallbacks.cards = nil
else
--
end
end
-- 处理物品数据
function SM_Collections:HandleItemsData(msg)
-- 缓存机制:如果不存在,初始化缓存
if not self.itemDataCache then
self.itemDataCache = ""
end
-- 将新收到的数据追加到缓存
self.itemDataCache = self.itemDataCache .. msg
-- 显示获取的原始数据
--print("[物品收藏] 收到服务器物品数据: " .. msg:sub(1, 100) .. "...")
--print("[物品收藏] 当前数据缓存总长度: " .. #self.itemDataCache)
-- 我们暂时不处理数据,而是等待更多批次数据到达
-- 只有当收到回调请求或者达到一定大小时才处理
if not self.pendingCallbacks or not self.pendingCallbacks.items then
--print("[物品收藏] 等待更多数据或回调请求...")
return
end
-- 确保所有服务器数据都已接收等待2秒再处理
if not self.itemDataProcessTimer then
--print("[物品收藏] 开始等待2秒处理服务器数据...")
self.itemDataProcessTimer = true
local processFrame = CreateFrame("Frame")
processFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 2 then
self:SetScript("OnUpdate", nil)
self:Hide()
-- 处理缓存中的所有数据
SM_Collections:ProcessItemsData()
end
end)
processFrame:Show()
return
end
-- 如果已经设置了定时器,不重复处理
--print("[物品收藏] 已设置处理定时器,等待处理...")
end
-- 新增:处理缓存中的所有物品数据
function SM_Collections:ProcessItemsData()
local data = self:MessageSplit(self.itemDataCache, "|")
local items = {}
-- 显示获取的原始数据总量
--print("[物品收藏] 处理全部缓存数据,共 " .. #data .. " 个字段")
-- 确认每组数据的字段数 - 每个物品固定为5个字段
local fieldsPerItem = 5 -- ID、名称、描述、是否获得、类型
-- 记录处理过程详情
--print("[物品收藏] 服务器数据格式: 每个物品 " .. fieldsPerItem .. " 个字段")
--print("[物品收藏] 理论上应该有 " .. math.floor(#data / fieldsPerItem) .. " 个物品")
-- 循环处理数据严格按照5个字段一组来解析
local validItemCount = 0
local slotItems = {} -- 按物品类型统计数量
for i = 1, #data, fieldsPerItem do
-- 确保有完整的5个字段
if i + fieldsPerItem - 1 <= #data then
local itemID = tonumber(data[i])
local itemName = data[i + 1]
local itemDesc = data[i + 2]
local obtained = data[i + 3] == "1"
local itemType = data[i + 4]
if itemID and itemID > 0 then
-- 记录每个解析的物品
--print(string.format("[物品收藏] 获取到物品ID%s名称%s类型%s是否获得%s",
-- itemID, itemName or "未知", itemType or "未知", obtained and "是" or "否"))
-- 统计不同类型物品的数量
if itemType and itemType ~= "" then
slotItems[itemType] = (slotItems[itemType] or 0) + 1
end
table.insert(items, {
id = itemID,
name = itemName or "",
description = itemDesc or "",
obtained = obtained,
itemType = itemType or ""
})
validItemCount = validItemCount + 1
end
end
end
-- 显示各类型物品数量统计
--print("[物品收藏] 物品类型统计:")
for itemType, count in pairs(slotItems) do
--print(string.format(" - %s: %d个", itemType, count))
end
if self.pendingCallbacks and self.pendingCallbacks.items then
local response = {
success = true,
data = items
}
--print(string.format("[物品收藏] 处理完成,共解析了%d个物品", #items))
self.pendingCallbacks.items(response)
self.pendingCallbacks.items = nil
-- 重置缓存和定时器
self.itemDataCache = ""
self.itemDataProcessTimer = nil
else
--print("[物品收藏] 错误: 没有找到回调函数")
end
end
-- 处理收藏状态更新
function SM_Collections:HandleCollectionUpdate(msg)
local data = self:MessageSplit(msg, "|")
if #data >= 3 then
local itemType = data[1]
local itemID = tonumber(data[2])
local isObtained = (data[3] == "1")
if itemID and itemType then
-- 更新本地数据
if itemType == "mount" then
self.DataManager:UpdateMountStatus(itemID, isObtained)
-- 如果是新获得的坐骑记录到NewItems表中
if isObtained then
self.NewItems.mount[itemID] = true
end
elseif itemType == "companion" then
self.DataManager:UpdateCompanionStatus(itemID, isObtained)
-- 如果是新获得的小伙伴记录到NewItems表中
if isObtained then
self.NewItems.companion[itemID] = true
end
elseif itemType == "card" then
self.DataManager:UpdateCardStatus(itemID, isObtained)
-- 如果是新获得的卡牌记录到NewItems表中
if isObtained then
self.NewItems.card[itemID] = true
end
elseif itemType == "item" then
self.DataManager:UpdateItemStatus(itemID, isObtained)
-- 如果是新获得的物品记录到NewItems表中
if isObtained then
self.NewItems.item[itemID] = true
end
end
-- 检查当前是否显示了对应类型的面板
local isCurrentPanel = false
if self.MainFrame then
-- 如果tabID为nil尝试从CurrentPanel推断当前面板类型
local inferredTabID = nil
if not self.MainFrame.tabID and self.CurrentPanel then
-- 检查当前面板中的按钮数据类型
if self.CurrentPanel.scrollChild and self.CurrentPanel.scrollChild.buttons and #self.CurrentPanel.scrollChild.buttons > 0 then
local firstButton = self.CurrentPanel.scrollChild.buttons[1]
if firstButton then
end
if firstButton and firstButton.itemType then
if firstButton.itemType == "mount" then
inferredTabID = 1
elseif firstButton.itemType == "companion" then
inferredTabID = 2
elseif firstButton.itemType == "card" then
inferredTabID = 3
elseif firstButton.itemType == "item" then
inferredTabID = 4
end
end
end
end
local effectiveTabID = self.MainFrame.tabID or inferredTabID
if effectiveTabID then
if (itemType == "mount" and effectiveTabID == 1) or
(itemType == "companion" and effectiveTabID == 2) or
(itemType == "card" and effectiveTabID == 3) or
(itemType == "item" and effectiveTabID == 4) then
isCurrentPanel = true
end
end
end
-- 无论当前面板是什么都尝试刷新UI
-- 如果不是当前面板RefreshCollectionStatus函数内部会自己处理
self:RefreshCollectionStatus(itemType, itemID, isObtained)
-- 如果是卡牌且当前显示的是卡牌面板,强制重新加载
if itemType == "card" and isCurrentPanel then
-- 使用 3.3.5 支持的延迟执行方法
local cardReloadFrame = CreateFrame("Frame")
cardReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
SM_Collections:ShowCards()
end
end)
cardReloadFrame:Show()
end
-- 如果是卡牌且获得了新卡牌,强制重新加载卡牌面板
if itemType == "card" and isObtained and not isCurrentPanel then
-- 更新本地数据,但不切换面板
local cardDataReloadFrame = CreateFrame("Frame")
cardDataReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
-- 重新获取卡牌数据,但不显示
SM_Collections.DataManager:GetCards(function(cards)
end)
end
end)
cardDataReloadFrame:Show()
end
-- 如果是小伙伴且获得了新的小伙伴,强制重新加载小伙伴面板
if itemType == "companion" and isObtained then
-- 使用 3.3.5 支持的延迟执行方法
local companionReloadFrame = CreateFrame("Frame")
companionReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
if SM_Collections.MainFrame and SM_Collections.MainFrame.tabID == 2 then
SM_Collections:ShowCompanions()
end
end
end)
companionReloadFrame:Show()
end
end
else
end
end
-- 消息处理函数
function SM_Collections_MessageEvent(self, event, prefix, msg, type, sender)
if event == 'CHAT_MSG_WHISPER' or event == 'CHAT_MSG_ADDON' then
if prefix == 'SM_S_COLLECTIONS_MOUNTS' then
SM_Collections:HandleMountsData(msg) -- 坐骑
elseif prefix == 'SM_S_COLLECTIONS_COMPANIONS' then
SM_Collections:HandleCompanionsData(msg) -- 小伙伴
elseif prefix == 'SM_S_COLLECTIONS_CARDS' then
SM_Collections:HandleCardsData(msg) -- 卡牌
elseif prefix == 'SM_S_COLLECTIONS_ITEMS' then
SM_Collections:HandleItemsData(msg) -- 物品
elseif prefix == 'SM_S_COLLECTIONS_ATTRIBUTES' then
SM_Collections:HandleAttributesData(msg) -- 属性
elseif prefix == 'SM_S_COLLECTIONS_ITEM_ATTRIBUTES' then
SM_Collections:HandleItemAttributesData(msg) -- 物品属性
elseif prefix == "SM_S_COLLECTION_UPDATE" then
SM_Collections:HandleCollectionUpdate(msg) --404行
end
end
end
-- 事件监听框架
local SM_Collections_EventFrame = CreateFrame('Frame', 'SM_Collections_EventFrame')
SM_Collections_EventFrame:RegisterEvent('CHAT_MSG_WHISPER')
SM_Collections_EventFrame:RegisterEvent('CHAT_MSG_ADDON')
SM_Collections_EventFrame:RegisterEvent('ADDON_LOADED')
SM_Collections_EventFrame:SetScript('OnEvent', function(self, event, ...)
if event == 'ADDON_LOADED' then
local addonName = ...
if addonName == "SM_CollectionSystem" then
end
elseif event == 'CHAT_MSG_ADDON' then
SM_Collections_MessageEvent(self, event, ...)
if not SM_Collections.MainFrame then
SM_Collections:CreateMainFrame()
-- 确保设置了默认的tabID
if SM_Collections.MainFrame then
SM_Collections.MainFrame.tabID = SM_Collections.MainFrame.tabID or 1
end
SM_Collections.MainFrame:Hide()
end
elseif event == 'CHAT_MSG_WHISPER' then
local msg, sender, _, _, _, _, _, _, _, _, _, guid, bnSenderID, isMobile, isSubtitle, hideSenderInLetterbox, supressRaidIcons = ...
-- 检查消息格式,判断是否是我们的插件消息
local prefix, content = strsplit("\t", msg, 2)
if content and (prefix == "SM_S_COLLECTIONS_MOUNTS" or
prefix == "SM_S_COLLECTIONS_COMPANIONS" or
prefix == "SM_S_COLLECTIONS_CARDS" or
prefix == "SM_S_COLLECTIONS_ITEMS" or
prefix == "SM_S_COLLECTIONS_ATTRIBUTES" or
prefix == "SM_S_COLLECTIONS_ITEM_ATTRIBUTES") then
SM_Collections_MessageEvent(self, "CHAT_MSG_WHISPER", prefix, content)
end
end
end)