From 265f0ef25d110960ecaaef7e0a9077e69e17c22c Mon Sep 17 00:00:00 2001 From: Lauren Hinnen Date: Sat, 15 Aug 2026 16:01:02 -0500 Subject: [PATCH] initial commit --- .gitignore | 2 + TargetScanner/TargetScanner.lua | 233 ++++++++++++++++++++++++ TargetScanner/TargetScanner.toc | 7 + TargetScanner/alchemyIngredientPage.php | 12 ++ TargetScanner/img/alchemy.png | Bin 0 -> 7356 bytes TargetScanner/index.html | 25 +++ TargetScanner/nav.html | 53 ++++++ TargetScanner/style.css | 27 +++ 8 files changed, 359 insertions(+) create mode 100644 .gitignore create mode 100755 TargetScanner/TargetScanner.lua create mode 100755 TargetScanner/TargetScanner.toc create mode 100644 TargetScanner/alchemyIngredientPage.php create mode 100644 TargetScanner/img/alchemy.png create mode 100755 TargetScanner/index.html create mode 100644 TargetScanner/nav.html create mode 100644 TargetScanner/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4befed3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.idea diff --git a/TargetScanner/TargetScanner.lua b/TargetScanner/TargetScanner.lua new file mode 100755 index 0000000..68da5bf --- /dev/null +++ b/TargetScanner/TargetScanner.lua @@ -0,0 +1,233 @@ +-- ============================================================================ +-- Addon Name: TargetScanner +-- Description: Item scanner tailored for the +-- Anniversary Edition Auction House API. +-- API Version: Compatible with Anniversary Realms (1.15.x) +-- ============================================================================ + +local addonName, addonTable = ... + +-- 1. CONFIGURATION: Define target item names and your maximum unit buyout threshold. +-- Server-side queries accept item names as search filters rather than raw IDs. +-- WoW Anniversary Edition Alchemy Consumables Configuration (Max Price in Copper) +local TargetItems = { + -- Restoration Potions (Health) + ["Minor Healing Potion"] = { maxPrice = 500 }, + ["Lesser Healing Potion"] = { maxPrice = 1500 }, + ["Healing Potion"] = { maxPrice = 5000 }, + ["Greater Healing Potion"] = { maxPrice = 20000 }, + ["Superior Healing Potion"] = { maxPrice = 50000 }, + ["Major Healing Potion"] = { maxPrice = 150000 }, + + -- Restoration Potions (Mana) + ["Lesser Mana Potion"] = { maxPrice = 2000 }, + ["Mana Potion"] = { maxPrice = 6000 }, + ["Greater Mana Potion"] = { maxPrice = 25000 }, + ["Superior Mana Potion"] = { maxPrice = 75000 }, + ["Major Mana Potion"] = { maxPrice = 200000 }, + ["Combat Mana Potion"] = { maxPrice = 100000 }, + + -- Utility & Defensive Potions + ["Swiftness Potion"] = { maxPrice = 80000 }, + ["Swim Speed Potion"] = { maxPrice = 15000 }, + ["Free Action Potion"] = { maxPrice = 150000 }, + ["Living Action Potion"] = { maxPrice = 250000 }, + ["Limited Invulnerability Potion"] = { maxPrice = 180000 }, + ["Restorative Potion"] = { maxPrice = 120000 }, + ["Invisibility Potion"] = { maxPrice = 100000 }, + ["Lesser Invisibility Potion"] = { maxPrice = 40000 }, + ["Potion of Dreamless Sleep"] = { maxPrice = 60000 }, + ["Purification Potion"] = { maxPrice = 50000 }, + ["Wildvine Potion"] = { maxPrice = 90000 }, + + -- Elemental Protection Potions + ["Fire Protection Potion"] = { maxPrice = 30000 }, + ["Greater Fire Protection Potion"] = { maxPrice = 250000 }, + ["Mighty Fire Protection Potion"] = { maxPrice = 400000 }, + ["Frost Protection Potion"] = { maxPrice = 20000 }, + ["Greater Frost Protection Potion"] = { maxPrice = 150000 }, + ["Mighty Frost Protection Potion"] = { maxPrice = 300000 }, + ["Nature Protection Potion"] = { maxPrice = 25000 }, + ["Greater Nature Protection Potion"] = { maxPrice = 200000 }, + ["Mighty Nature Protection Potion"] = { maxPrice = 350000 }, + ["Shadow Protection Potion"] = { maxPrice = 30000 }, + ["Greater Shadow Protection Potion"] = { maxPrice = 220000 }, + ["Mighty Shadow Protection Potion"] = { maxPrice = 380000 }, + ["Arcane Protection Potion"] = { maxPrice = 15000 }, + ["Greater Arcane Protection Potion"] = { maxPrice = 100000 }, + + -- Combat Stats & Class Potions + ["Rage Potion"] = { maxPrice = 10000 }, + ["Great Rage Potion"] = { maxPrice = 40000 }, + ["Mighty Rage Potion"] = { maxPrice = 180000 }, + ["Greater Stoneshield Potion"] = { maxPrice = 120000 }, + ["Mageblood Potion"] = { maxPrice = 90000 }, + ["Major Troll's Blood Potion"] = { maxPrice = 40000 }, + + -- Physical/Combat Elixirs + ["Elixir of Lion's Strength"] = { maxPrice = 800 }, + ["Elixir of Lesser Agility"] = { maxPrice = 3000 }, + ["Elixir of Agility"] = { maxPrice = 25000 }, + ["Elixir of Giants"] = { maxPrice = 45000 }, + ["Elixir of Brute Force"] = { maxPrice = 60000 }, + ["Elixir of the Mongoose"] = { maxPrice = 180000 }, + + -- Caster Elixirs + ["Elixir of Firepower"] = { maxPrice = 15000 }, + ["Elixir of Greater Firepower"] = { maxPrice = 70000 }, + ["Elixir of Shadow Power"] = { maxPrice = 55000 }, + ["Elixir of Greater Intellect"] = { maxPrice = 35000 }, + ["Elixir of the Sages"] = { maxPrice = 40000 }, + ["Arcane Elixir"] = { maxPrice = 45000 }, + ["Greater Arcane Elixir"] = { maxPrice = 160000 }, + + -- Defensive & Utility Elixirs + ["Elixir of Defense"] = { maxPrice = 8000 }, + ["Elixir of Fortitude"] = { maxPrice = 35000 }, + ["Elixir of Superior Defense"] = { maxPrice = 150000 }, + ["Elixir of Poison Resistance"] = { maxPrice = 25000 }, + ["Gift of Arthas"] = { maxPrice = 30000 }, + ["Elixir of Dream Vision"] = { maxPrice = 40000 }, + + -- Raid Flasks (Persistent through death) + ["Flask of the Titans"] = { maxPrice = 600000 }, + ["Flask of Supreme Power"] = { maxPrice = 600000 }, + ["Flask of Distilled Wisdom"] = { maxPrice = 600000 }, + ["Flask of Chromatic Resistance"] = { maxPrice = 400000 }, + ["Flask of Petrification"] = { maxPrice = 500000 }, + + -- Alchemy Oils + ["Shadow Oil"] = { maxPrice = 80000 }, + ["Frost Oil"] = { maxPrice = 50000 } +} + +-- Addon state properties +local currentItemIndex = 1 +local itemOrder = {} +local isScanning = false + +-- Chronologically map out the sequence keys +for name, _ in pairs(TargetItems) do + table.insert(itemOrder, name) +end + +-- 2. FRAME & EVENT DISPATCHER +local ScannerFrame = CreateFrame("Frame") +ScannerFrame:RegisterEvent("AUCTION_HOUSE_SHOW") +ScannerFrame:RegisterEvent("AUCTION_HOUSE_CLOSED") +ScannerFrame:RegisterEvent("AUCTION_ITEM_LIST_UPDATE") + +-- 3. CORE PRINT UTILITY +local function PrintMessage(msg) + print("|cFF00FFCC[TargetScanner]|r: " .. msg) +end + +-- Converts flat copper currencies into beautifully color-coded Gold/Silver/Copper strings +local function FormatMoney(copper) + if not copper or copper == 0 then return "0g" end + local gold = math.floor(copper / 10000) + local silver = math.floor((copper % 10000) / 100) + local cop = copper % 100 + return string.format("|cFFFFD700%dg|r |cFFC7C7C7%ds|r |cFFB87333%dc|r", gold, silver, cop) +end + +-- 4. SEQUENCE STEP MANAGER +local function ScanNextItem() + if not isScanning then return end + + -- Check if we finished checking our tailored list + if currentItemIndex > #itemOrder then + PrintMessage("Scan process complete!") + isScanning = false + currentItemIndex = 1 + return + end + + local targetName = itemOrder[currentItemIndex] + PrintMessage("Querying server for: " .. targetName .. "...") + + -- Auction Query API Structure: + -- QueryAuctionItems("name", minLevel, maxLevel, page, isUsable, rarityFilter, getAll, exactMatch) + -- We set exactMatch (parameter 8) to true to cut out extraneous suffix permutations + QueryAuctionItems(targetName, nil, nil, 0, nil, nil, false, true) +end + +-- Main interface execution call +function TargetScanner_StartScan() + if isScanning then + PrintMessage("A scan sequence is already actively running.") + return + end + + isScanning = true + currentItemIndex = 1 + PrintMessage("Kicking off sequential tracking for " .. #itemOrder .. " Classic items...") + ScanNextItem() +end + +-- 5. EVENT SYSTEM INTERACTION +ScannerFrame:SetScript("OnEvent", function(self, event, ...) + if event == "AUCTION_HOUSE_SHOW" then + PrintMessage("Anniversary Auction House ready. Type /tscan to check values.") + + elseif event == "AUCTION_HOUSE_CLOSED" then + isScanning = false + currentItemIndex = 1 + + elseif event == "AUCTION_ITEM_LIST_UPDATE" then + -- This event fires when server database page details load into local client visibility + if not isScanning then return end + + local batchCount, totalCount = GetNumAuctionItems("list") + local targetName = itemOrder[currentItemIndex] + local config = TargetItems[targetName] + local foundDeals = false + + -- Scan through all listings currently sent to the client list buffer + for i = 1, batchCount do + -- Data fetch return structure map + local name, _, count, _, _, _, _, _, _, buyoutPrice = GetAuctionItemInfo("list", i) + + if name == targetName and buyoutPrice and buyoutPrice > 0 then + -- Divide by stack count size to extract true single unit prices + local unitPrice = buyoutPrice / count + + if unitPrice <= config.maxPrice then + PrintMessage(string.format("PROFITABLE LISTING: %s x%d - Unit Cost: %s (Total Buyout: %s)", + name, + count, + FormatMoney(unitPrice), + FormatMoney(buyoutPrice) + )) + foundDeals = true + end + end + end + + if not foundDeals then + PrintMessage("No listings found below price caps for: " .. targetName) + end + + -- Increment queue index to prepare the next item + currentItemIndex = currentItemIndex + 1 + + -- CRITICAL: Servers implement severe request limits. + -- An explicit 2.0-second delay protects the client connection from disconnects. + C_Timer.After(2.0, function() + ScanNextItem() + end) + end +end) + +-- 6. INTERFACE INTERACTION COMMAND +SLASH_TARSCAN1 = "/tscan" +SlashCmdList["TARSCAN"] = function(msg) + -- WoW utilizes 'AuctionFrame' + if not AuctionFrame or not AuctionFrame:IsShown() then + PrintMessage("Aborted: You must have an interaction window open with an Auctioneer NPC.") + return + end + TargetScanner_StartScan() +end + +PrintMessage("Targeted script loaded. Macro command: /tscan") \ No newline at end of file diff --git a/TargetScanner/TargetScanner.toc b/TargetScanner/TargetScanner.toc new file mode 100755 index 0000000..9621efd --- /dev/null +++ b/TargetScanner/TargetScanner.toc @@ -0,0 +1,7 @@ +## Interface: 11503 +## Title: TargetScanner +## Notes: Specific item price scanner framework. +## Author: Lauren Hinnen +## Version: 1.0 + +TargetScanner.lua \ No newline at end of file diff --git a/TargetScanner/alchemyIngredientPage.php b/TargetScanner/alchemyIngredientPage.php new file mode 100644 index 0000000..72acb85 --- /dev/null +++ b/TargetScanner/alchemyIngredientPage.php @@ -0,0 +1,12 @@ + + + + + + + Alchemy Ingredient Selector + + + + + \ No newline at end of file diff --git a/TargetScanner/img/alchemy.png b/TargetScanner/img/alchemy.png new file mode 100644 index 0000000000000000000000000000000000000000..719156d871fd7eb5a83f5dc67d205e1011aae941 GIT binary patch literal 7356 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 + + + + + + Alchemy Calculator + + +
+ +
+ + \ No newline at end of file diff --git a/TargetScanner/nav.html b/TargetScanner/nav.html new file mode 100644 index 0000000..6de30e5 --- /dev/null +++ b/TargetScanner/nav.html @@ -0,0 +1,53 @@ + + + + + + + Alchemy Calculator + + + +
+ +
+ + \ No newline at end of file diff --git a/TargetScanner/style.css b/TargetScanner/style.css new file mode 100644 index 0000000..0669170 --- /dev/null +++ b/TargetScanner/style.css @@ -0,0 +1,27 @@ +ul { + list-style-type: none; + margin: 0; + padding: 0; + background-color: #333333; + display: flex; +} + +ul li a { + display: block; + color: white; + padding: 14px 16px; + text-decoration: none; +} + +ul li a:hover { + background-color: #111111; +} + +ul li a.active { + background-color: #04AA6D; +} + +ul li a img { + width: 25px; + height: 25px; +} \ No newline at end of file