You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
474 lines
14 KiB
474 lines
14 KiB
local _, addon = ...
|
|
|
|
local DataProvider = {};
|
|
addon.PerksProgramDataProvider = DataProvider;
|
|
|
|
local PerksProgramAPI = C_PerksProgram;
|
|
local C_TransmogCollection = C_TransmogCollection;
|
|
|
|
if PerksProgramAPI then
|
|
DataProvider.programExisted = true;
|
|
else
|
|
PerksProgramAPI = {};
|
|
end
|
|
|
|
local CURRENCY_ID = Constants.CurrencyConsts.CURRENCY_ID_PERKS_PROGRAM_DISPLAY_INFO or 2032;
|
|
|
|
local GetVendorItemInfo = PerksProgramAPI.GetVendorItemInfo;
|
|
local GetTimeRemaining = PerksProgramAPI.GetTimeRemaining;
|
|
local GetCurrencyAmount = PerksProgramAPI.GetCurrencyAmount; --Returns the amount of Trader's Tendor (2032) Constants.CurrencyConsts.CURRENCY_ID_PERKS_PROGRAM_DISPLAY_INFO
|
|
|
|
local GetCurrentCalendarTime = C_DateAndTime.GetCurrentCalendarTime;
|
|
local type = type;
|
|
|
|
|
|
|
|
local VendorItemDataCache = {};
|
|
local DB;
|
|
|
|
local IGNORED_KEYS = {
|
|
purchased = true,
|
|
perksVendorItemID = true,
|
|
timeRemaining = true,
|
|
refundable = true,
|
|
};
|
|
|
|
local DELIMITER = "::";
|
|
|
|
local function CompressTable(tbl)
|
|
local output = DELIMITER;
|
|
|
|
for k, v in pairs(tbl) do
|
|
if not IGNORED_KEYS[k] then
|
|
if v ~= 0 and v ~= "" then
|
|
output = output ..k ..DELIMITER.. v ..DELIMITER;
|
|
end
|
|
end
|
|
end
|
|
|
|
return output
|
|
end
|
|
|
|
local function DecompressData(dataString)
|
|
local key, value, seg;
|
|
local numericVal;
|
|
local tonumber = tonumber;
|
|
local find = string.find;
|
|
local strsub = string.sub;
|
|
|
|
local tbl = {};
|
|
local isKey = true;
|
|
local stringLen = string.len(dataString);
|
|
|
|
local initPos = 3;
|
|
local fromIndex, toIndex = find(dataString, DELIMITER, initPos);
|
|
|
|
while fromIndex and toIndex do
|
|
seg = strsub(dataString, initPos, fromIndex - 1);
|
|
initPos = toIndex + 1;
|
|
fromIndex, toIndex = find(dataString, DELIMITER, initPos);
|
|
if isKey then
|
|
key = seg;
|
|
else
|
|
value = seg;
|
|
numericVal = tonumber(value);
|
|
if numericVal then
|
|
tbl[key] = numericVal;
|
|
else
|
|
tbl[key] = value;
|
|
end
|
|
end
|
|
isKey = not isKey;
|
|
end
|
|
|
|
return tbl
|
|
end
|
|
|
|
function DataProvider:DoesPerksProgramExist()
|
|
return self.programExisted
|
|
end
|
|
|
|
function DataProvider:IsNewVendorItem(vendorItemID)
|
|
return vendorItemID and DB.VendorItems[vendorItemID] == nil
|
|
end
|
|
|
|
function DataProvider:SaveVendorItemData(vendorItemID, overwrite)
|
|
if vendorItemID and (overwrite or self:IsNewVendorItem(vendorItemID)) then
|
|
local info = GetVendorItemInfo(vendorItemID);
|
|
if info and info.perksVendorItemID and info.perksVendorItemID ~= 0 then
|
|
if info.name == "" or info.description == "" then
|
|
return false
|
|
end
|
|
local dataString = CompressTable(info);
|
|
local month, year = self:GetActivePerksDate();
|
|
local date = year.."/"..month;
|
|
dataString = dataString .. "addedDate" ..DELIMITER.. date ..DELIMITER;
|
|
|
|
VendorItemDataCache[vendorItemID] = info;
|
|
info.addedInYear = year;
|
|
info.addedInMonth = month;
|
|
|
|
DB.VendorItems[vendorItemID] = dataString;
|
|
|
|
return dataString
|
|
end
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetVendorItemInfoFromDatabase(vendorItemID)
|
|
local info;
|
|
if DB.VendorItems[vendorItemID] then
|
|
info = DecompressData( DB.VendorItems[vendorItemID] );
|
|
info.isCache = true;
|
|
return info
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetAndCacheVendorItemInfo(vendorItemID)
|
|
if not VendorItemDataCache[vendorItemID] then
|
|
local info = GetVendorItemInfo(vendorItemID);
|
|
if info and info.perksVendorItemID ~= 0 then
|
|
if info.name and info.name ~= "" then
|
|
VendorItemDataCache[vendorItemID] = info;
|
|
end
|
|
return info
|
|
else
|
|
VendorItemDataCache[vendorItemID] = self:GetVendorItemInfoFromDatabase(vendorItemID);
|
|
end
|
|
end
|
|
return VendorItemDataCache[vendorItemID]
|
|
end
|
|
|
|
function DataProvider:GetVendorItemName(vendorItemID)
|
|
local info = self:GetAndCacheVendorItemInfo(vendorItemID);
|
|
if info then
|
|
return info.name
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetVendorItemCategory(vendorItemID)
|
|
local info = self:GetAndCacheVendorItemInfo(vendorItemID);
|
|
if info then
|
|
return info.perksVendorCategoryID
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetVendorItemDescription(vendorItemID)
|
|
local info = self:GetAndCacheVendorItemInfo(vendorItemID);
|
|
if info then
|
|
return info.description
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetVendorItemPrice(vendorItemID)
|
|
local info = self:GetAndCacheVendorItemInfo(vendorItemID);
|
|
if info then
|
|
if info.isCache then
|
|
return info.price or 0
|
|
else
|
|
local cachedData = self:GetVendorItemInfoFromDatabase(vendorItemID);
|
|
local price = cachedData and cachedData.price;
|
|
if price then
|
|
return price
|
|
end
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function DataProvider:IsVendorItemPurchased(vendorItemID)
|
|
local info = self:GetAndCacheVendorItemInfo(vendorItemID);
|
|
if info then
|
|
if info.isCache or (info.price == 0) then
|
|
--Player didn't visit Trading Post during this session, use cache
|
|
--[[
|
|
1 Transmog
|
|
2 Mount
|
|
3 Pet
|
|
5 Toy
|
|
7 Illusion
|
|
8 Transmogset
|
|
--]]
|
|
local itemID = info.itemID;
|
|
local category = info.perksVendorCategoryID;
|
|
|
|
if category == 1 then
|
|
local appearanceID;
|
|
local sourceID = info.itemModifiedAppearanceID;
|
|
if (not sourceID) or sourceID == 0 then
|
|
appearanceID, sourceID = C_TransmogCollection.GetItemInfo(itemID);
|
|
end
|
|
if sourceID and sourceID ~= 0 then
|
|
return C_TransmogCollection.PlayerKnowsSource(sourceID);
|
|
end
|
|
|
|
elseif category == 2 then
|
|
local mountID = C_MountJournal.GetMountFromItem(itemID);
|
|
if mountID then
|
|
local isCollected = select(11, C_MountJournal.GetMountInfoByID(mountID));
|
|
return isCollected
|
|
end
|
|
|
|
elseif category == 3 then
|
|
local petName = C_PetJournal.GetPetInfoByItemID(itemID);
|
|
if petName then
|
|
local _, petGUID = C_PetJournal.FindPetIDByName(petName);
|
|
return petGUID ~= nil
|
|
end
|
|
|
|
elseif category == 5 then
|
|
return PlayerHasToy(itemID);
|
|
|
|
elseif category == 7 then
|
|
local illusionID = info.illusionID;
|
|
if illusionID then
|
|
local tbl = C_TransmogCollection.GetIllusionInfo(illusionID);
|
|
return tbl and tbl.isCollected
|
|
end
|
|
|
|
elseif category == 8 then
|
|
local transmogSetID = info.transmogSetID;
|
|
if transmogSetID == 0 then
|
|
local itemInfo = DataProvider:GetVendorItemInfoFromDatabase(vendorItemID);
|
|
transmogSetID = itemInfo and itemInfo.transmogSetID;
|
|
end
|
|
if transmogSetID then
|
|
local sourceIDs = C_TransmogSets.GetAllSourceIDs(transmogSetID);
|
|
if sourceIDs and sourceIDs[1] then
|
|
return C_TransmogCollection.PlayerKnowsSource( sourceIDs[1] );
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return info.purchased
|
|
end
|
|
end
|
|
|
|
function DataProvider:UpdateActivePerksMonthInfo()
|
|
if not (self.month and self.currentMonthName) then
|
|
local activitiesInfo = C_PerksActivities.GetPerksActivitiesInfo();
|
|
local month = activitiesInfo.activePerksMonth;
|
|
local currentCalendarTime = GetCurrentCalendarTime();
|
|
local year = currentCalendarTime.year;
|
|
self.currentMonthName = activitiesInfo.displayMonthName;
|
|
self.year = year;
|
|
self.month = month;
|
|
|
|
for _, monthInfo in ipairs(DB.MonthNames) do
|
|
if month == monthInfo.m and year == monthInfo.y then
|
|
return
|
|
end
|
|
end
|
|
|
|
table.insert(DB.MonthNames, {
|
|
y = year,
|
|
m = month,
|
|
n = activitiesInfo.displayMonthName,
|
|
});
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetActivePerksDate()
|
|
self:UpdateActivePerksMonthInfo();
|
|
return self.month, self.year
|
|
end
|
|
|
|
function DataProvider:GetCurrentDisplayMonthName()
|
|
self:UpdateActivePerksMonthInfo();
|
|
return self.currentMonthName;
|
|
end
|
|
|
|
function DataProvider:GetDisplayMonthName(year, month)
|
|
if type(year) == "string" then
|
|
year, month = string.match(year, "(%d+)/(%d+)");
|
|
year = tonumber(year);
|
|
month = tonumber(month);
|
|
end
|
|
|
|
if not self.monthNames then
|
|
--[year] = {[month] = name},
|
|
self.monthNames = {};
|
|
for _, monthInfo in ipairs(DB.MonthNames) do
|
|
if not self.monthNames[monthInfo.y] then
|
|
self.monthNames[monthInfo.y] = {};
|
|
end
|
|
self.monthNames[monthInfo.y][monthInfo.m] = monthInfo.n;
|
|
end
|
|
end
|
|
|
|
if not self.monthNames[year] then
|
|
self.monthNames[year] = {};
|
|
end
|
|
|
|
if not self.monthNames[year][month] then
|
|
self.monthNames[year][month] = self:GetCurrentDisplayMonthName();
|
|
end
|
|
|
|
return self.monthNames[year][month]
|
|
end
|
|
|
|
|
|
local EventListener = CreateFrame("Frame");
|
|
|
|
if DataProvider:DoesPerksProgramExist() then
|
|
EventListener:RegisterEvent("PERKS_ACTIVITIES_UPDATED");
|
|
EventListener:RegisterEvent("PERKS_ACTIVITY_COMPLETED");
|
|
EventListener:RegisterEvent("PERKS_PROGRAM_DATA_REFRESH");
|
|
EventListener:RegisterEvent("PERKS_PROGRAM_CURRENCY_REFRESH");
|
|
EventListener:RegisterEvent("PERKS_PROGRAM_REFUND_SUCCESS");
|
|
EventListener:RegisterEvent("PERKS_PROGRAM_PURCHASE_SUCCESS");
|
|
end
|
|
|
|
EventListener:SetScript("OnEvent", function(self, event, ...)
|
|
if event == "PERKS_ACTIVITIES_UPDATED" or event == "PERKS_ACTIVITY_COMPLETED" then
|
|
DataProvider:ClearActivityCache();
|
|
elseif event == "PERKS_PROGRAM_DATA_REFRESH" then
|
|
local vendorItemIDs = C_PerksProgram.GetAvailableVendorItemIDs();
|
|
|
|
for _, vendorItemID in pairs(vendorItemIDs) do
|
|
GetVendorItemInfo(vendorItemID);
|
|
end
|
|
|
|
C_Timer.After(1, function()
|
|
for _, vendorItemID in pairs(vendorItemIDs) do
|
|
GetVendorItemInfo(vendorItemID);
|
|
DataProvider:SaveVendorItemData(vendorItemID);
|
|
end
|
|
end);
|
|
|
|
DataProvider:UpdateActivePerksMonthInfo();
|
|
DataProvider:SaveCurrentMonthItems(vendorItemIDs);
|
|
elseif event == "PERKS_PROGRAM_CURRENCY_REFRESH" then
|
|
DataProvider.ownedCurrencyAmount = nil;
|
|
elseif event == "PERKS_PROGRAM_REFUND_SUCCESS" or event == "PERKS_PROGRAM_PURCHASE_SUCCESS" then
|
|
local vendorItemID = ...;
|
|
local isOwned = event == "PERKS_PROGRAM_PURCHASE_SUCCESS";
|
|
if vendorItemID and VendorItemDataCache[vendorItemID] then
|
|
VendorItemDataCache[vendorItemID].purchased = isOwned;
|
|
VendorItemDataCache[vendorItemID].refundable = isOwned;
|
|
end
|
|
DataProvider.ownedCurrencyAmount = nil;
|
|
end
|
|
end);
|
|
|
|
function DataProvider:ClearActivityCache()
|
|
self.unclaimedPoints = nil;
|
|
self.unearnedPoints = nil;
|
|
self.currentMonthName = nil;
|
|
self.month = nil;
|
|
end
|
|
|
|
function DataProvider:CacheActivityInfo()
|
|
if not self.unclaimedPoints then
|
|
local pendingRewards = PerksProgramAPI.GetPendingChestRewards();
|
|
local numUnclaimed = 0;
|
|
|
|
if pendingRewards then
|
|
for _, reward in pairs(pendingRewards) do
|
|
numUnclaimed = numUnclaimed + (reward.rewardAmount or 0);
|
|
end
|
|
end
|
|
|
|
self.unclaimedPoints = numUnclaimed;
|
|
end
|
|
|
|
if not self.unearnedPoints then
|
|
local activitiesInfo = C_PerksActivities.GetPerksActivitiesInfo();
|
|
local currentPoints = 0;
|
|
local numUnearned = 0;
|
|
|
|
for _, activityInfo in pairs(activitiesInfo.activities) do
|
|
if activityInfo.completed then
|
|
currentPoints = currentPoints + activityInfo.thresholdContributionAmount;
|
|
end
|
|
end
|
|
|
|
for _, thresholdInfo in pairs(activitiesInfo.thresholds) do
|
|
if thresholdInfo.requiredContributionAmount > currentPoints then
|
|
numUnearned = numUnearned + thresholdInfo.currencyAwardAmount;
|
|
end
|
|
end
|
|
|
|
self.unearnedPoints = numUnearned;
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetAvailableCurrency()
|
|
--Returns the amounts of unclaimed and unearned token
|
|
self:CacheActivityInfo();
|
|
return self.unclaimedPoints or 0, self.unearnedPoints or 0;
|
|
end
|
|
|
|
function DataProvider:GetCurrencyAmount()
|
|
if not self.ownedCurrencyAmount then
|
|
self.ownedCurrencyAmount = GetCurrencyAmount() or 0;
|
|
end
|
|
return self.ownedCurrencyAmount
|
|
end
|
|
|
|
function DataProvider:SaveCurrentMonthItems(vendorItemIDs)
|
|
local month = self:GetActivePerksDate();
|
|
if month ~= DB.CurrentMonthData.month then
|
|
local tbl = {};
|
|
local total = 0;
|
|
for i, id in ipairs(vendorItemIDs) do
|
|
if id ~= 0 then
|
|
total = total + 1;
|
|
tbl[total] = id;
|
|
end
|
|
end
|
|
DB.CurrentMonthData.items = tbl;
|
|
DB.CurrentMonthData.month = month;
|
|
end
|
|
end
|
|
|
|
function DataProvider:GetCurrentMonthItems()
|
|
local month = self:GetActivePerksDate();
|
|
if month and month == DB.CurrentMonthData.month then
|
|
return DB.CurrentMonthData.items
|
|
else
|
|
DB.CurrentMonthData = {};
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
local function LoadDatabase()
|
|
if not NarcissusDB.PerksProgramDB then
|
|
NarcissusDB.PerksProgramDB = {};
|
|
end
|
|
|
|
DB = NarcissusDB.PerksProgramDB;
|
|
|
|
if not DB.VendorItems then
|
|
DB.VendorItems = {};
|
|
end
|
|
|
|
if not DB.MonthNames then
|
|
DB.MonthNames = {};
|
|
end
|
|
|
|
if not DB.CurrentMonthData then
|
|
DB.CurrentMonthData = {};
|
|
end
|
|
end
|
|
|
|
addon.AddInitializationCallback(LoadDatabase);
|
|
|
|
|
|
--[[
|
|
local activitiesInfo = C_PerksActivities.GetPerksActivitiesInfo();
|
|
[thresholds]
|
|
[displayMonthName]
|
|
|
|
|
|
Enum.PerksVendorCategoryType
|
|
1 Transmog
|
|
2 Mount
|
|
3 Pet
|
|
5 Toy
|
|
7 Illusion
|
|
8 Transmogset
|
|
--]]
|
|
|