Browse Source

fix encode

dev
Jørgen Lien Sellæg 4 months ago
parent
commit
505f2304d4
  1. 70
      TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua

70
TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua

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

Loading…
Cancel
Save