init
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- 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.factionrealm.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.factionrealm.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.factionrealm.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.factionrealm.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.factionrealm.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.factionrealm.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.factionrealm.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
|
||||
Reference in New Issue
Block a user