commit from backup

This commit is contained in:
mikx
2018-01-05 06:40:15 -05:00
commit 58b08d6ae0
142 changed files with 29080 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
--[[
Copyright 2013 João Cardoso
CustomSearch is distributed under the terms of the GNU General Public License (Version 3).
As a special exception, the copyright holders of this library give you permission to embed it
with independent modules to produce an addon, regardless of the license terms of these
independent modules, and to copy and distribute the resulting software under terms of your
choice, provided that you also meet, for each embedded independent module, the terms and
conditions of the license of that module. Permission is not granted to modify this library.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the library. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
This file is part of CustomSearch.
--]]
local Lib = LibStub:NewLibrary('CustomSearch-1.0', 9)
if not Lib then
return
end
--[[ Parsing ]]--
function Lib:Matches(object, search, filters)
if object then
self.filters = filters
self.object = object
return self:MatchAll(search or '')
end
end
function Lib:MatchAll(search)
for phrase in self:Clean(search):gmatch('[^&]+') do
if not self:MatchAny(phrase) then
return
end
end
return true
end
function Lib:MatchAny(search)
for phrase in search:gmatch('[^|]+') do
if self:Match(phrase) then
return true
end
end
end
function Lib:Match(search)
local tag, rest = search:match('^%s*(%S+):(.*)$')
if tag then
tag = '^' .. tag
search = rest
end
local words = search:gmatch('%S+')
local failed
for word in words do
if word == self.OR then
if failed then
failed = false
else
break
end
else
local negate, rest = word:match('^([!~]=*)(.*)$')
if negate or word == self.NOT_MATCH then
word = rest and rest ~= '' and rest or words() or ''
negate = -1
else
negate = 1
end
local operator, rest = word:match('^(=*[<>]=*)(.*)$')
if operator then
word = rest ~= '' and rest or words()
end
local result = self:Filter(tag, operator, word) and 1 or -1
if result * negate ~= 1 then
failed = true
end
end
end
return not failed
end
--[[ Filtering ]]--
function Lib:Filter(tag, operator, search)
if not search then
return true
end
if tag then
for _, filter in pairs(self.filters) do
for _, value in pairs(filter.tags or {}) do
if value:find(tag) then
return self:UseFilter(filter, operator, search)
end
end
end
else
for _, filter in pairs(self.filters) do
if not filter.onlyTags and self:UseFilter(filter, operator, search) then
return true
end
end
end
end
function Lib:UseFilter(filter, operator, search)
local data = {filter:canSearch(operator, search, self.object)}
if data[1] then
return filter:match(self.object, operator, unpack(data))
end
end
--[[ Utilities ]]--
function Lib:Find(search, ...)
for i = 1, select('#', ...) do
local text = select(i, ...)
if text and self:Clean(text):find(search) then
return true
end
end
end
function Lib:Clean(string)
string = string:lower()
string = string:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', function(c) return '%'..c end)
for accent, char in pairs(self.ACCENTS) do
string = string:gsub(accent, char)
end
return string
end
function Lib:Compare(op, a, b)
if op then
if op:find('<') then
if op:find('=') then
return a <= b
end
return a < b
end
if op:find('>')then
if op:find('=') then
return a >= b
end
return a > b
end
end
return a == b
end
--[[ Localization ]]--
do
local no = {enUS = 'Not', frFR = 'Pas', deDE = 'Nicht'}
local accents = {
a = {'à','â','ã','å'},
e = {'è','é','ê','ê','ë'},
i = {'ì', 'í', 'î', 'ï'},
o = {'ó','ò','ô','õ'},
u = {'ù', 'ú', 'û', 'ü'},
c = {'ç'}, n = {'ñ'}
}
Lib.ACCENTS = {}
for char, accents in pairs(accents) do
for _, accent in ipairs(accents) do
Lib.ACCENTS[accent] = char
end
end
Lib.OR = Lib:Clean(JUST_OR)
Lib.NOT = no[GetLocale()] or NO
Lib.NOT_MATCH = Lib:Clean(Lib.NOT)
setmetatable(Lib, {__call = Lib.Matches})
end
return Lib

View File

@@ -0,0 +1,295 @@
--[[
ItemSearch
An item text search engine of some sort
--]]
local Search = LibStub('CustomSearch-1.0')
local Unfit = LibStub('Unfit-1.0')
local Lib = LibStub:NewLibrary('LibItemSearch-1.2-ElvUI', 6)
if Lib then
Lib.Filters = {}
else
return
end
--[[ User API ]]--
function Lib:Matches(link, search)
return Search(link, search, self.Filters)
end
function Lib:Tooltip(link, search)
return link and self.Filters.tip:match(link, nil, search)
end
function Lib:TooltipPhrase(link, search, allowPartialMatch)
return link and self.Filters.tipPhrases:match(link, nil, search, allowPartialMatch)
end
function Lib:InSet(link, search)
if IsEquippableItem(link) then
local id = tonumber(link:match('item:(%-?%d+)'))
return self:BelongsToSet(id, (search or ''):lower())
end
end
--[[ Basics ]]--
Lib.Filters.name = {
tags = {'n', 'name'},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, item, _, search)
local name = item:match('%[(.-)%]')
return Search:Find(search, name)
end
}
Lib.Filters.type = {
tags = {'t', 'type', 's', 'slot'},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, item, _, search)
local type, subType, _, equipSlot = select(6, GetItemInfo(item))
return Search:Find(search, type, subType, _G[equipSlot])
end
}
Lib.Filters.level = {
tags = {'l', 'level', 'lvl', 'ilvl'},
canSearch = function(self, _, search)
return tonumber(search)
end,
match = function(self, link, operator, num)
local lvl = select(4, GetItemInfo(link))
if lvl then
return Search:Compare(operator, lvl, num)
end
end
}
Lib.Filters.requiredlevel = {
tags = {'r', 'req', 'rl', 'reql', 'reqlvl'},
canSearch = function(self, _, search)
return tonumber(search)
end,
match = function(self, link, operator, num)
local lvl = select(5, GetItemInfo(link))
if lvl then
return Search:Compare(operator, lvl, num)
end
end
}
--[[ Quality ]]--
local qualities = {}
for i = 0, #ITEM_QUALITY_COLORS do
qualities[i] = _G['ITEM_QUALITY' .. i .. '_DESC']:lower()
end
Lib.Filters.quality = {
tags = {'q', 'quality'},
canSearch = function(self, _, search)
for i, name in pairs(qualities) do
if name:find(search) then
return i
end
end
end,
match = function(self, link, operator, num)
local quality = link:sub(1, 9) == 'battlepet' and tonumber(link:match('%d+:%d+:(%d+)')) or select(3, GetItemInfo(link))
return Search:Compare(operator, quality, num)
end,
}
--[[ Usable ]]--
Lib.Filters.usable = {
tags = {},
canSearch = function(self, operator, search)
return not operator and search == 'usable'
end,
match = function(self, link)
if not Unfit:IsItemUnusable(link) then
local lvl = select(5, GetItemInfo(link))
return lvl and (lvl ~= 0 and lvl <= UnitLevel('player'))
end
end
}
--[[ Tooltip Searches ]]--
local scanner = LibItemSearchTooltipScanner or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate')
Lib.Filters.tip = {
tags = {'tt', 'tip', 'tooltip'},
onlyTags = true,
canSearch = function(self, _, search)
return search
end,
match = function(self, link, _, search)
if link:find('item:') then
scanner:SetOwner(UIParent, 'ANCHOR_NONE')
scanner:SetHyperlink(link)
for i = 1, scanner:NumLines() do
if Search:Find(search, _G[scanner:GetName() .. 'TextLeft' .. i]:GetText()) then
return true
end
end
end
end
}
local escapes = {
["|c%x%x%x%x%x%x%x%x"] = "", -- color start
["|r"] = "", -- color end
}
local function CleanString(str)
for k, v in pairs(escapes) do
str = str:gsub(k, v)
end
return str
end
Lib.Filters.tipPhrases = {
canSearch = function(self, _, search)
return self.keywords[search]
end,
match = function(self, link, _, search, allowPartialMatch)
local id = link:match('item:(%d+)')
if not id then
return
end
local cached = self.cache[search][id]
if cached ~= nil then
return cached
end
scanner:SetOwner(UIParent, 'ANCHOR_NONE')
scanner:SetHyperlink(link)
local matches = false
for i = 1, scanner:NumLines() do
local text = _G['LibItemSearchTooltipScannerTextLeft' .. i]:GetText()
text = CleanString(text)
if search == text or (allowPartialMatch and text:find(search)) then
matches = true
break
end
end
self.cache[search][id] = matches
return matches
end,
cache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end}),
keywords = {
[ITEM_SOULBOUND:lower()] = ITEM_BIND_ON_PICKUP,
['bound'] = ITEM_BIND_ON_PICKUP,
['bop'] = ITEM_BIND_ON_PICKUP,
['boe'] = ITEM_BIND_ON_EQUIP,
['bou'] = ITEM_BIND_ON_USE,
['boa'] = ITEM_BIND_TO_BNETACCOUNT,
[GetItemClassInfo(LE_ITEM_CLASS_QUESTITEM):lower()] = ITEM_BIND_QUEST,
[QUESTS_LABEL:lower()] = ITEM_BIND_QUEST,
[TOY:lower()] = TOY,
[MINIMAP_TRACKING_VENDOR_REAGENT:lower()] = PROFESSIONS_USED_IN_COOKING,
['reagent'] = PROFESSIONS_USED_IN_COOKING,
['crafting'] = PROFESSIONS_USED_IN_COOKING,
['naval'] = 'naval equipment',
['follower'] = 'follower',
['followe'] = 'follower',
['follow'] = 'follower',
["relic"] = (GetItemSubClassInfo(LE_ITEM_CLASS_GEM, 11)),
["reli"] = (GetItemSubClassInfo(LE_ITEM_CLASS_GEM, 11)),
["rel"] = (GetItemSubClassInfo(LE_ITEM_CLASS_GEM, 11)),
["power"] = ARTIFACT_POWER,
["powe"] = ARTIFACT_POWER,
["pow"] = ARTIFACT_POWER,
}
}
--[[ Equipment Sets ]]--
if IsAddOnLoaded('ItemRack') then
local sameID = ItemRack.SameID
function Lib:BelongsToSet(id, search)
for name, set in pairs(ItemRackUser.Sets) do
if name:sub(1,1) ~= '' and Search:Find(search, name) then
for _, item in pairs(set.equip) do
if sameID(id, item) then
return true
end
end
end
end
end
elseif IsAddOnLoaded('Wardrobe') then
function Lib:BelongsToSet(id, search)
for _, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
local name = outfit.OutfitName
if Search:Find(search, name) then
for _, item in pairs(outfit.Item) do
if item.IsSlotUsed == 1 and item.ItemID == id then
return true
end
end
end
end
end
else
function Lib:BelongsToSet(id, search)
for i = 1, GetNumEquipmentSets() do
local name = GetEquipmentSetInfo(i)
if Search:Find(search, name) or search == "matchall" then
local items = GetEquipmentSetItemIDs(name)
for _, item in pairs(items) do
if id == item then
return true
end
end
end
end
end
end
Lib.Filters.sets = {
tags = {'s', 'set'},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, link, _, search)
return Lib:InSet(link, search)
end,
}

View File

@@ -0,0 +1,6 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CustomSearch-1.0\CustomSearch-1.0.lua"/>
<Script file="Unfit-1.0\Unfit-1.0.lua"/>
<Script file="LibItemSearch-1.2.lua"/>
</Ui>

View File

@@ -0,0 +1,127 @@
--[[
Copyright 2011-2016 João Cardoso
Unfit is distributed under the terms of the GNU General Public License (Version 3).
As a special exception, the copyright holders of this library give you permission to embed it
with independent modules to produce an addon, regardless of the license terms of these
independent modules, and to copy and distribute the resulting software under terms of your
choice, provided that you also meet, for each embedded independent module, the terms and
conditions of the license of that module. Permission is not granted to modify this library.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the library. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
This file is part of Unfit.
--]]
local Lib = LibStub:NewLibrary('Unfit-1.0', 9)
if not Lib then
return
end
--[[ Data ]]--
do
local _, Class = UnitClass('player')
local Unusable
if Class == 'DEATHKNIGHT' then
Unusable = { -- weapon, armor, dual-wield
{LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_STAFF,LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_SHIELD}
}
elseif Class == 'DEMONHUNTER' then
Unusable = {
{LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD}
}
elseif Class == 'DRUID' then
Unusable = {
{LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD},
true
}
elseif Class == 'HUNTER' then
Unusable = {
{LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD}
}
elseif Class == 'MAGE' then
Unusable = {
{LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW},
{LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD},
true
}
elseif Class == 'MONK' then
Unusable = {
{LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD}
}
elseif Class == 'PALADIN' then
Unusable = {
{LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{},
true
}
elseif Class == 'PRIEST' then
Unusable = {
{LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW},
{LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD},
true
}
elseif Class == 'ROGUE' then
Unusable = {
{LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD}
}
elseif Class == 'SHAMAN' then
Unusable = {
{LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND},
{LE_ITEM_ARMOR_PLATEM}
}
elseif Class == 'WARLOCK' then
Unusable = {
{LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW},
{LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD},
true
}
elseif Class == 'WARRIOR' then
Unusable = {{LE_ITEM_WEAPON_WARGLAIVE, LE_ITEM_WEAPON_WAND}, {}}
else
Unusable = {{}, {}}
end
Lib.unusable = {}
Lib.cannotDual = Unusable[3]
for i, class in ipairs({LE_ITEM_CLASS_WEAPON, LE_ITEM_CLASS_ARMOR}) do
local list = {}
for _, subclass in ipairs(Unusable[i]) do
list[subclass] = true
end
Lib.unusable[class] = list
end
end
--[[ API ]]--
function Lib:IsItemUnusable(...)
if ... then
local slot, _,_, class, subclass = select(9, GetItemInfo(...))
return Lib:IsClassUnusable(class, subclass, slot)
end
end
function Lib:IsClassUnusable(class, subclass, slot)
if class and subclass and Lib.unusable[class] then
return slot ~= '' and Lib.unusable[class][subclass] or slot == 'INVTYPE_WEAPONOFFHAND' and Lib.cannotDual
end
end