Compare commits

...

5 Commits

Author SHA1 Message Date
Jørgen Lien Sellæg efff9329fa Add AuctionDB channel sync options and controls. 3 months ago
Jørgen Lien Sellæg df429912a0 Ignore archive directories in gitignore. 3 months ago
Jørgen Lien Sellæg e433f9b530 prioritize small/older mail stacks in gather 3 months ago
Jørgen Lien Sellæg 1732439a5c Fix roundup custom price parsing. 3 months ago
Jørgen Lien Sellæg 510a2bd018 guard custom price eval and slider value 3 months ago
  1. 1
      .gitignore
  2. 13
      TradeSkillMaster/Core/Prices.lua
  3. 7
      TradeSkillMaster/GUI/TSMWidgets/TSMSlider.lua
  4. 2
      TradeSkillMaster/TradeSkillMaster.toc
  5. 11
      TradeSkillMaster_AuctionDB/Locale/enUS.lua
  6. 67
      TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua
  7. 62
      TradeSkillMaster_AuctionDB/Modules/config.lua
  8. 4
      TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.lua
  9. 38
      TradeSkillMaster_Mailing/Modules/Inbox.lua

1
.gitignore vendored

@ -6,6 +6,7 @@
.lua/*
.vscode
.idea.
archive-*/
02a7e8db-fd8d-4213-8d9c-ab66009a487d.zip
408e9dd4-e03b-4a89-b1f1-a488136d6283.zip
4a37aaf8-9aa6-4246-8c0d-1cafc6b994a1.zip

13
TradeSkillMaster/Core/Prices.lua

@ -324,7 +324,7 @@ local function ParsePriceString(str, badPriceSource)
-- replace math functions special custom function names
for word, funcName in pairs(MATH_FUNCTIONS) do
str = gsub(str, word, funcName)
str = gsub(str, "([^%w_])"..word.."([^%w_])", "%1"..funcName.."%2")
end
-- remove any unused values
@ -514,8 +514,15 @@ function TSMAPI:ParseCustomPrice(priceString, badPriceSource)
return nil, err
end
customPriceCache[priceString] = func
return func
local function safeFunc(itemString)
local success, value = pcall(func, itemString)
if success then
return value
end
end
customPriceCache[priceString] = safeFunc
return safeFunc
end
function TSMAPI:GetCustomPriceSourceValue(itemString, key)

7
TradeSkillMaster/GUI/TSMWidgets/TSMSlider.lua

@ -158,6 +158,13 @@ local methods = {
end,
["SetValue"] = function(self, value)
if value == nil then
value = self.min or 0
end
value = tonumber(value)
if not value then
return
end
self.slider.setup = true
self.slider:SetValue(value)
self.value = value

2
TradeSkillMaster/TradeSkillMaster.toc

@ -2,7 +2,7 @@
## Title: |cff00fe00TradeSkillMaster: Revived|r
## Notes: Core addon for the TradeSkillMaster suite, revived for Wrath of the Lich King. Does nothing without modules installed.
## Author: Sapu94, Bart39, Gnomezilla [Warmane-Icecrown(A)], BlueAo [Warmane], andrew6180, Yoshiyuka, DimaSheiko, and other contributors...
## Version: 2.3.45
## Version: 2.3.46
## SavedVariables: TradeSkillMasterAppDB, AscensionTSMDB
## OptionalDeps: AccurateTime, Ace3, LibDataBroker-1.1, LibDBIcon-1.0, LibExtraTip, TipHelper, LibParse, LibCompress, LibGraph-2.0, SharedMedia, TheUndermineJournal, TheUndermineJournalGE
## X-Embeds: AccurateTime, Ace3, LibDataBroker-1.1, LibDBIcon-1.0, LibExtraTip, TipHelper, LibParse, LibCompress, LibGraph-2.0

11
TradeSkillMaster_AuctionDB/Locale/enUS.lua

@ -23,12 +23,20 @@ L["AuctionDB - Market Value"] = true
L["AuctionDB - Minimum Buyout"] = true
L["Descending"] = true
L["Display lowest buyout value seen in the last scan in tooltip."] = true
L["Channel Sync"] = true
L["Channel sync name"] = true
L["Display market value in tooltip."] = true
L["Enable channel sync"] = true
L["Done Scanning"] = true
L["Download the FREE TSM desktop application which will automatically update your TSM_AuctionDB prices using Blizzard's online APIs (and does MUCH more). Visit %s for more info and never scan the AH again! This is the best way to update your AuctionDB prices."] = true
L["Enable channel sync debug messages"] = true
L["Enable display of AuctionDB data in tooltip."] = true
L["The channel name used to share AuctionDB data."] = true
L["Hide poor quality items"] = true
L["If checked, AuctionDB will add a tab to the AH to allow for in-game scans. If you are using the TSM app exclusively for your scans, you may want to hide it by unchecking this option. This option requires a reload to take effect."] = true
L["If checked, AuctionDB will print channel sync debug messages to chat."] = true
L["If checked, AuctionDB will sync scan data over the configured channel."] = true
L["If checked, AuctionDB will only receive channel sync data and will not broadcast scan data."] = true
L["If checked, poor quality items won't be shown in the search results."] = true
L["If checked, the lowest buyout value seen in the last scan of the item will be displayed."] = true
L["If checked, the market value of the item will be displayed"] = true
@ -66,6 +74,9 @@ L["Refreshes the current search results."] = true
L["Removed %s from AuctionDB."] = true
L["Reset Data"] = true
L["Resets AuctionDB's scan data"] = true
L["Reset"] = true
L["Resets the channel name to the default."] = true
L["Receive-only mode"] = true
L["Resume"] = true
L["Resuming Scan..."] = true
L["Result Order:"] = true

67
TradeSkillMaster_AuctionDB/Modules/ChannelSync.lua

@ -12,7 +12,14 @@ local TSM = select(2, ...)
local ChannelSync = TSM:NewModule("ChannelSync", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_AuctionDB")
local CHANNEL_NAME = "TSM_AuctionDB"
local DEFAULT_CHANNEL_NAME = "TSM_AuctionDB"
local function GetChannelConfigName()
if TSM.db and TSM.db.profile and TSM.db.profile.channelSyncName and TSM.db.profile.channelSyncName ~= "" then
return TSM.db.profile.channelSyncName
end
return DEFAULT_CHANNEL_NAME
end
local COMM_PREFIX = "TSMADB1"
local CHUNK_SIZE = 220
local BUNDLE_TIMEOUT = 45
@ -36,7 +43,6 @@ local strbyte = string.byte
local libS = LibStub:GetLibrary("AceSerializer-3.0")
local libD = LibStub("LibDeflate", true)
local warnedNoDeflate
local debugEnabled = true
local function GetAddonVersion()
local version = GetAddOnMetadata("TradeSkillMaster_AuctionDB", "X-Curse-Packaged-Version")
@ -59,7 +65,7 @@ private.addonVersion = GetAddonVersion()
private.addonVersionKey = VersionKey(private.addonVersion)
local function DebugPrint(msg)
if debugEnabled then
if TSM.db and TSM.db.profile and TSM.db.profile.channelSyncDebug then
TSM:Print("ChannelSync: " .. msg)
end
end
@ -82,13 +88,24 @@ local function HashString(str)
end
local function EnsureChannel()
local channelId = GetChannelName(CHANNEL_NAME)
if private.channelId and private.channelName and private.channelName ~= GetChannelConfigName() then
LeaveChannelByName(private.channelName)
private.channelId = nil
private.channelName = nil
end
if not TSM.db or not TSM.db.profile or not TSM.db.profile.channelSyncEnabled then
private.channelId = nil
private.channelName = nil
return
end
local channelName = GetChannelConfigName()
local channelId = GetChannelName(channelName)
if channelId == 0 then
JoinChannelByName(CHANNEL_NAME)
channelId = GetChannelName(CHANNEL_NAME)
JoinChannelByName(channelName)
channelId = GetChannelName(channelName)
end
private.channelId = channelId > 0 and channelId or nil
private.channelName = private.channelId and CHANNEL_NAME or nil
private.channelName = private.channelId and channelName or nil
end
local function GetChannelDisplayName(channelName, channelString, channelNumber, channelBaseName)
@ -111,8 +128,9 @@ local function GetChannelDisplayName(channelName, channelString, channelNumber,
end
local function ChatFilter(_, _, msg, _, channelString, _, channelNumber, channelName, channelBaseName)
local channelNameKey = GetChannelConfigName()
local displayName = GetChannelDisplayName(channelName, channelString, channelNumber, channelBaseName)
if displayName ~= CHANNEL_NAME then return end
if displayName ~= channelNameKey then return end
if strsub(msg, 1, #COMM_PREFIX) == COMM_PREFIX then
return true
end
@ -136,6 +154,10 @@ function ChannelSync:OnChannelNotice()
EnsureChannel()
end
function ChannelSync:ReloadConfig()
EnsureChannel()
end
local function EncodePayload(payload)
if not CanEncode() then return end
local serialized = libS:Serialize(payload)
@ -192,6 +214,8 @@ function ChannelSync:BroadcastScanData(scanType, items)
return
end
EnsureChannel()
if not TSM.db or not TSM.db.profile or not TSM.db.profile.channelSyncEnabled then return end
if TSM.db.profile.channelSyncReceiveOnly then return end
if not private.channelName or not private.channelId then return end
local itemIDs = ChannelSync:CollectItemIDs(items)
@ -199,10 +223,10 @@ function ChannelSync:BroadcastScanData(scanType, items)
local function QueueEncoded(encoded)
local hash = HashString(encoded)
if hash == private.lastBroadcastHash then return end
private.lastBroadcastHash = hash
local total = ceil(#encoded / CHUNK_SIZE)
if total > MAX_TOTAL_CHUNKS then return false end
if hash == private.lastBroadcastHash then return end
private.lastBroadcastHash = hash
local total = ceil(#encoded / CHUNK_SIZE)
if total > MAX_TOTAL_CHUNKS then return false end
tinsert(private.sendQueue, {hash = hash, encoded = encoded, total = total})
if not private.isSending then
private.isSending = true
@ -228,7 +252,9 @@ function ChannelSync:BroadcastScanData(scanType, items)
return
end
if total > MAX_TOTAL_CHUNKS then
TSM:Print("AuctionDB channel sync payload too large; skipping batch.")
if TSM.db and TSM.db.profile and TSM.db.profile.channelSyncDebug then
TSM:Print("AuctionDB channel sync payload too large; skipping batch.")
end
return
end
QueueEncoded(encoded)
@ -349,18 +375,21 @@ local function MergeIncomingData(payload, sender)
if updated == 0 and sender then
DebugPrint("No items updated from " .. sender .. ".")
elseif updated > 0 and sender then
if updated == 1 and lastItemID then
local link = select(2, GetItemInfo(lastItemID)) or ("item:" .. tostring(lastItemID))
TSM:Printf("AuctionDB updated %s from %s.", link, sender)
else
TSM:Printf("AuctionDB updated %d items from %s.", updated, sender)
if TSM.db and TSM.db.profile and TSM.db.profile.channelSyncDebug then
if updated == 1 and lastItemID then
local link = select(2, GetItemInfo(lastItemID)) or ("item:" .. tostring(lastItemID))
TSM:Printf("AuctionDB updated %s from %s.", link, sender)
else
TSM:Printf("AuctionDB updated %d items from %s.", updated, sender)
end
end
end
end
function ChannelSync:OnChannelMessage(_, msg, source, _, channelString, _, channelNumber, channelName, channelBaseName)
local channelNameKey = GetChannelConfigName()
local displayName = GetChannelDisplayName(channelName, channelString, channelNumber, channelBaseName)
if displayName ~= CHANNEL_NAME then
if displayName ~= channelNameKey then
if strsub(msg or "", 1, #COMM_PREFIX) == COMM_PREFIX then
DebugPrint("Prefix received; displayName=" .. tostring(displayName) .. " channelNumber=" .. tostring(channelNumber) .. " channelString=" .. tostring(channelString) .. " channelName=" .. tostring(channelName) .. " channelBaseName=" .. tostring(channelBaseName))
end

62
TradeSkillMaster_AuctionDB/Modules/config.lua

@ -392,6 +392,68 @@ function Config:LoadOptions(container)
},
},
},
{
type = "InlineGroup",
title = L["Channel Sync"],
layout = "Flow",
children = {
{
type = "CheckBox",
label = L["Enable channel sync"],
settingInfo = { TSM.db.profile, "channelSyncEnabled" },
relativeWidth = 1,
callback = function() TSM.ChannelSync:ReloadConfig() container:ReloadTab() end,
tooltip = L["If checked, AuctionDB will sync scan data over the configured channel."],
},
{
type = "EditBox",
label = L["Channel sync name"],
settingInfo = { TSM.db.profile, "channelSyncName" },
relativeWidth = 0.5,
disabled = not TSM.db.profile.channelSyncEnabled,
callback = function(_, _, value)
value = strtrim(value or "")
if value == "" then
TSM.db.profile.channelSyncName = "TSM_AuctionDB"
else
TSM.db.profile.channelSyncName = value
end
TSM.ChannelSync:ReloadConfig()
container:ReloadTab()
end,
tooltip = L["The channel name used to share AuctionDB data."],
},
{
type = "Button",
text = L["Reset"],
relativeWidth = 0.2,
disabled = not TSM.db.profile.channelSyncEnabled,
callback = function()
TSM.db.profile.channelSyncName = "TSM_AuctionDB"
TSM.ChannelSync:ReloadConfig()
container:ReloadTab()
end,
tooltip = L["Resets the channel name to the default."],
},
{
type = "CheckBox",
label = L["Receive-only mode"],
settingInfo = { TSM.db.profile, "channelSyncReceiveOnly" },
relativeWidth = 1,
disabled = not TSM.db.profile.channelSyncEnabled,
callback = function() TSM.ChannelSync:ReloadConfig() end,
tooltip = L["If checked, AuctionDB will only receive channel sync data and will not broadcast scan data."],
},
{
type = "CheckBox",
label = L["Enable channel sync debug messages"],
settingInfo = { TSM.db.profile, "channelSyncDebug" },
relativeWidth = 1,
disabled = not TSM.db.profile.channelSyncEnabled,
tooltip = L["If checked, AuctionDB will print channel sync debug messages to chat."],
},
},
},
{
type = "InlineGroup",
title = L["Search Options"],

4
TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.lua

@ -36,6 +36,10 @@ local savedDBDefaults = {
marketValueTooltip = true,
minBuyoutTooltip = true,
showAHTab = true,
channelSyncEnabled = true,
channelSyncName = "TSM_AuctionDB",
channelSyncReceiveOnly = false,
channelSyncDebug = false,
},
}

38
TradeSkillMaster_Mailing/Modules/Inbox.lua

@ -499,6 +499,7 @@ function Inbox:CollectItems(items, callback)
local remaining = CopyTable(items)
local collected = false
local candidates = {}
for i = GetInboxNumItems(), 1, -1 do
local _, _, _, _, _, cod, _, hasItem = GetInboxHeaderInfo(i)
if hasItem and hasItem > 0 and (not cod or cod == 0) then
@ -508,21 +509,42 @@ function Inbox:CollectItems(items, callback)
local need = itemString and remaining[itemString]
if need and need > 0 then
local quantity = select(3, GetInboxItem(i, j)) or 0
if quantity > 0 and (quantity <= need or not HasFittableStack(itemString, need)) then
if CanLootItem(itemString, quantity) then
TakeInboxItem(i, j)
remaining[itemString] = max(need - quantity, 0)
collected = true
elseif callback then
callback(L["Cannot finish auto looting, inventory is full or too many unique items."])
return
if quantity > 0 then
if not candidates[itemString] then
candidates[itemString] = {}
end
tinsert(candidates[itemString], { index = i, itemIndex = j, quantity = quantity })
end
end
end
end
end
for itemString, entries in pairs(candidates) do
table.sort(entries, function(a, b)
if a.quantity ~= b.quantity then
return a.quantity < b.quantity
end
return a.index > b.index
end)
for _, entry in ipairs(entries) do
local need = remaining[itemString]
if not need or need <= 0 then
break
end
if entry.quantity > 0 and (entry.quantity <= need or not HasFittableStack(itemString, need)) then
if CanLootItem(itemString, entry.quantity) then
TakeInboxItem(entry.index, entry.itemIndex)
remaining[itemString] = max(need - entry.quantity, 0)
collected = true
elseif callback then
callback(L["Cannot finish auto looting, inventory is full or too many unique items."])
return
end
end
end
end
-- Keep looting as new mail indexes shift, while preserving 1 free slot.
if collected then
TSMAPI:CreateTimeDelay("craftingGatherMailLoop", 0.4, function()

Loading…
Cancel
Save