42dbe9d526
* Enchanting fixes, reverted Crafting module to previous version that supports Ascension specific crafts and Vellums. * Updated enchanting names from DB * Added the remaining Ascension specific recipes * Replace SpellNames2IDs.lua with UnitCastingSpellID * Bugfix: Ascension uses exact quality QueryAuctionItems, TSM was designed for quality or higher * Bugfix: Properly get list of Professions via index * Replaced factionrealm with realm Ascension does not have strict faction seperation * GetTradeSkillCooldown -> SpellHasBaseCooldown GetTradeSkillCooldown only tells you if a spell is on CD, not if it has a CD Data is from DB, which isn't populated fully yet. * Implement backported API GetSpellBaseCooldown * bugfix: hasCD is nil if no cd, not 0
205 lines
6.7 KiB
Lua
205 lines
6.7 KiB
Lua
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- http://www.curse.com/addons/wow/tradeskill-master --
|
|
-- --
|
|
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
|
-- All Rights Reserved* - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
-- This file handled multi-account syncing and communication
|
|
|
|
-- register this file with Ace libraries
|
|
local TSM = select(2, ...)
|
|
local Sync = TSM:NewModule("Sync", "AceComm-3.0", "AceEvent-3.0")
|
|
TSMAPI.Sync = {}
|
|
local private = {callbacks={}, addedFriends={}, invalidPlayers={}}
|
|
TSMAPI:RegisterForTracing(private, "TradeSkillMaster.Sync_private")
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
|
|
|
-- Request friend info from the server
|
|
ShowFriends()
|
|
|
|
|
|
function Sync:OnEnable()
|
|
Sync:RegisterComm("TSMSyncData")
|
|
Sync:RegisterEvent("CHAT_MSG_SYSTEM")
|
|
|
|
local data = {characters={}, accountKey=TSMAPI.Sync:GetAccountKey()}
|
|
for name in pairs(TSM.db.realm.characters) do
|
|
data.characters[name] = TSMAPI.Sync:GetAccountKey()
|
|
end
|
|
TSMAPI:CreateTimeDelay("syncSetupDelay", 3, function() TSMAPI.Sync:BroadcastData("TradeSkillMaster", "SETUP", data) end)
|
|
end
|
|
|
|
--Load the libraries
|
|
local libS = LibStub:GetLibrary("AceSerializer-3.0")
|
|
local libC = LibStub:GetLibrary("LibCompress")
|
|
local libCE = libC:GetAddonEncodeTable()
|
|
|
|
function Sync:OnCommReceived(_, data, _, source)
|
|
-- remove realm name from source
|
|
source = ("-"):split(source)
|
|
|
|
-- Decode the compressed data
|
|
data = libCE:Decode(data)
|
|
|
|
-- Decompress the decoded data
|
|
local data = libC:Decompress(data)
|
|
if not data then return end
|
|
|
|
-- Deserialize the decompressed data
|
|
local success
|
|
local tmpData = data
|
|
success, data = libS:Deserialize(data)
|
|
if not success or not data then return end
|
|
|
|
-- data is good, do callback
|
|
local key = data.__key
|
|
local module = data.__module
|
|
local account = data.__account
|
|
if not key or not module or not private.callbacks[module] then return end
|
|
data.__key = nil
|
|
data.__module = nil
|
|
data.__account = nil
|
|
|
|
-- make sure we are getting this from a known source
|
|
if not TSM.db.realm.syncAccounts[account] and (module ~= "TradeSkillMaster" and not data.isSetup) then return end
|
|
private.callbacks[module](key, data, source)
|
|
end
|
|
|
|
function Sync:CHAT_MSG_SYSTEM(_, msg)
|
|
if #private.addedFriends == 0 then return end
|
|
if msg == ERR_FRIEND_NOT_FOUND then
|
|
tremove(private.addedFriends, 1)
|
|
else
|
|
for i, v in ipairs(private.addedFriends) do
|
|
if format(ERR_FRIEND_ADDED_S, v) == msg then
|
|
tremove(private.addedFriends, i)
|
|
private.invalidPlayers[strlower(v)] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function TSMAPI.Sync:GetAccountKey()
|
|
return TSM.db.realm.accountKey
|
|
end
|
|
|
|
function TSM:RegisterSyncCallback(module, callback)
|
|
private.callbacks[module] = callback
|
|
end
|
|
|
|
function private:IsPlayerOnline(target, noAdd)
|
|
for i=1, GetNumFriends() do
|
|
local name, _, _, _, connected = GetFriendInfo(i)
|
|
if name and strlower(name) == strlower(target) then
|
|
return connected
|
|
end
|
|
end
|
|
|
|
if not noAdd and not private.invalidPlayers[strlower(target)] and GetNumFriends() ~= 50 then
|
|
-- add them as a friend
|
|
AddFriend(target)
|
|
tinsert(private.addedFriends, target)
|
|
for i=1, GetNumFriends() do
|
|
local name, _, _, _, connected = GetFriendInfo(i)
|
|
if name and strlower(name) == strlower(target) then
|
|
return connected
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function TSMAPI.Sync:SendData(module, key, data, target)
|
|
local playerOnline = private:IsPlayerOnline(target)
|
|
if not playerOnline then return end
|
|
|
|
data.__module = module
|
|
data.__key = key
|
|
data.__account = TSMAPI.Sync:GetAccountKey()
|
|
|
|
-- we will encode using Huffman, LZW, and no compression separately
|
|
-- this is to deal with a bug in the compression code
|
|
local orig = data
|
|
local serialized = libS:Serialize(data)
|
|
local encodedData = {}
|
|
encodedData[1] = libCE:Encode(libC:CompressHuffman(serialized))
|
|
encodedData[2] = libCE:Encode(libC:CompressLZW(serialized))
|
|
encodedData[3] = libCE:Encode("\001"..serialized)
|
|
|
|
-- verify each compresion and pick the shorted valid one
|
|
local minIndex = -1
|
|
local minLen = math.huge
|
|
for i=#encodedData, 1, -1 do
|
|
local test = libC:Decompress(libCE:Decode(encodedData[i]))
|
|
if test and test == serialized and #encodedData[i] < minLen then
|
|
minLen = #encodedData[i]
|
|
minIndex = i
|
|
end
|
|
end
|
|
|
|
-- sanity check
|
|
if not encodedData[minIndex] then error("Could not encode data.") end
|
|
-- send off the serialized, compressed, and encoded data
|
|
Sync:SendCommMessage("TSMSyncData", encodedData[minIndex], "WHISPER", target)
|
|
end
|
|
|
|
|
|
function TSMAPI.Sync:BroadcastData(module, key, data)
|
|
for account, players in pairs(TSM.db.realm.syncAccounts) do
|
|
if account ~= TSMAPI.Sync:GetAccountKey() then
|
|
local sent
|
|
for player in pairs(players) do
|
|
if private:IsPlayerOnline(player, true) then
|
|
TSMAPI.Sync:SendData(module, key, data, player)
|
|
sent = true
|
|
break
|
|
end
|
|
end
|
|
if not sent then
|
|
for player in pairs(players) do
|
|
if private:IsPlayerOnline(player) then
|
|
TSMAPI.Sync:SendData(module, key, data, player)
|
|
sent = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function private:SendSetupData(target, isResponse, isSetup)
|
|
local data = {isResponse=isResponse, isSetup=isSetup, characters={}, accountKey=TSMAPI.Sync:GetAccountKey()}
|
|
for name in pairs(TSM.db.realm.characters) do
|
|
data.characters[name] = true
|
|
end
|
|
TSMAPI.Sync:SendData("TradeSkillMaster", "SETUP", data, target)
|
|
end
|
|
|
|
function TSM:DoSyncSetup(target)
|
|
if target == "" then
|
|
private.syncSetupTarget = nil
|
|
return
|
|
end
|
|
private.syncSetupTarget = target
|
|
private:SendSetupData(target, nil, true)
|
|
end
|
|
|
|
function TSM:SyncCallback(key, data, source)
|
|
if key == "SETUP" then
|
|
if (data.isSetup and strlower(source) ~= strlower(private.syncSetupTarget or "")) or (not data.isSetup and not TSM.db.realm.syncAccounts[data.accountKey]) then
|
|
return
|
|
end
|
|
TSMAPI:Verify(data.accountKey ~= TSMAPI.Sync:GetAccountKey(), "It appears that you've manually copied your saved variables between accounts which will cause TSM's automatic sync'ing to not work. You'll need to undo this, and/or delete the TradeSkillMaster, TSM_Crafting, and TSM_ItemTracker saved variables files on both accounts (with WoW closed) in order to fix this.")
|
|
TSM.db.realm.syncAccounts[data.accountKey] = data.characters
|
|
if data.isSetup then
|
|
TSMAPI:CloseFrame()
|
|
TSM:Printf(L["Setup account sync'ing with the account which '%s' is on."], source)
|
|
end
|
|
if data.isResponse then return end -- already responded
|
|
private:SendSetupData(source, true, data.isSetup)
|
|
end
|
|
end |