diff --git a/TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua b/TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua index 539202b..0b22006 100644 --- a/TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua +++ b/TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua @@ -12,8 +12,8 @@ local TSM = select(2, ...) local ChannelSync = TSM:NewModule("ChannelSync", "AceEvent-3.0") local CHANNEL_NAME = "TSM_AuctionDB" -local COMM_PREFIX = "TSMAuctionDB" -local CHUNK_SIZE = 180 +local COMM_PREFIX = "TSMADB1" +local CHUNK_SIZE = 200 local BUNDLE_TIMEOUT = 45 local private = { @@ -26,16 +26,16 @@ local private = { local strbyte = string.byte local libS = LibStub:GetLibrary("AceSerializer-3.0") -local libC = LibStub:GetLibrary("LibCompress") -local libCE - -local function GetCodec() - if libCE then return libCE end - libCE = libC:GetChatEncodeTable("", "\031") - if not libCE then - libCE = libC:GetChatEncodeTable() +local libD = LibStub("LibDeflate", true) +local warnedNoDeflate + +local function CanEncode() + if libD then return true end + if not warnedNoDeflate then + warnedNoDeflate = true + TSM:Print("AuctionDB channel sync requires LibDeflate. Install or enable an addon that provides it.") end - return libCE + return false end local function HashString(str) @@ -43,7 +43,7 @@ local function HashString(str) for i = 1, #str do hash = (hash * 31 + strbyte(str, i)) % 4294967296 end - return tostring(hash) + return hash end local function EnsureChannel() @@ -58,7 +58,7 @@ end local function ChatFilter(_, _, msg, _, _, _, _, _, channelName) if channelName ~= CHANNEL_NAME then return end - if strsub(msg, 1, #COMM_PREFIX + 1) == COMM_PREFIX .. "|" then + if strsub(msg, 1, #COMM_PREFIX) == COMM_PREFIX then return true end end @@ -82,25 +82,18 @@ function ChannelSync:OnChannelNotice() end local function EncodePayload(payload) + if not CanEncode() then return end local serialized = libS:Serialize(payload) - local codec = GetCodec() - if not codec then return end - local encoded = codec:Encode(libC:CompressHuffman(serialized)) - if not encoded then - encoded = codec:Encode(libC:CompressLZW(serialized)) - end - if not encoded then - encoded = codec:Encode("\001" .. serialized) - end - return encoded + local compressed = libD:CompressDeflate(serialized, { level = 7 }) + if not compressed then return end + return libD:EncodeForPrint(compressed) end local function DecodePayload(encoded) - local codec = GetCodec() - if not codec then return end - local decoded = codec:Decode(encoded) + if not CanEncode() then return end + local decoded = libD:DecodeForPrint(encoded) if not decoded then return end - local decompressed = libC:Decompress(decoded) + local decompressed = libD:DecompressDeflate(decoded) if not decompressed then return end local ok, payload = libS:Deserialize(decompressed) if not ok then return end @@ -131,11 +124,11 @@ function ChannelSync:BroadcastScanData(scanType) local hash = HashString(encoded) if hash == private.lastBroadcastHash then return end private.lastBroadcastHash = hash - local total = ceil(#encoded / CHUNK_SIZE) + if total > 65535 then return end for i = 1, total do local chunk = strsub(encoded, (i - 1) * CHUNK_SIZE + 1, i * CHUNK_SIZE) - local msg = strjoin("|", COMM_PREFIX, hash, i .. "/" .. total, chunk) + local msg = COMM_PREFIX .. string.format("%08x%04x%04x", tonumber(hash), i, total) .. chunk SendChatMessage(msg, "CHANNEL", nil, private.channelId) end end @@ -166,17 +159,22 @@ end function ChannelSync:OnChannelMessage(_, msg, source, _, _, _, _, _, channelName) if channelName ~= CHANNEL_NAME then return end - if strsub(msg or "", 1, #COMM_PREFIX + 1) ~= COMM_PREFIX .. "|" then return end + if strsub(msg or "", 1, #COMM_PREFIX) ~= COMM_PREFIX then return end source = ("-"):split(source or "") if strlower(source or "") == strlower(UnitName("player") or "") then return end - local header, hash, seqInfo, chunk = msg:match("^(.-)|([^|]+)|([^|]+)|(.+)$") - if header ~= COMM_PREFIX or not hash or not seqInfo or not chunk then return end - - local seq, total = seqInfo:match("^(%d+)%/(%d+)$") - seq, total = tonumber(seq), tonumber(total) - if not seq or not total then return end + local headerLen = #COMM_PREFIX + 16 + if #msg <= headerLen then return end + local meta = strsub(msg, #COMM_PREFIX + 1, headerLen) + local chunk = strsub(msg, headerLen + 1) + local hashHex = strsub(meta, 1, 8) + local seqHex = strsub(meta, 9, 12) + local totalHex = strsub(meta, 13, 16) + local hash = tonumber(hashHex, 16) + local seq = tonumber(seqHex, 16) + local total = tonumber(totalHex, 16) + if not hash or not seq or not total then return end local bundle = private.incoming[hash] if not bundle or (time() - bundle.time) > BUNDLE_TIMEOUT then