Compare with Previous | Blame | View Log
-- The following encapsulates the Recipe database 27914 RecipeDB = {}; function GetRecipeDescription(name) if RecipeDB[name] == nil then return "<Invalid Recipe>" else return RecipeDB[name].Description end end function SetRecipeDescription(name, descr) if RecipeDB[name] == nil then RecipeDB[name] = {} end RecipeDB[name].Description = descr end function GetRecipeLink(name) if RecipeDB[name] == nil then return "<Invalid Recipe>" else return RecipeDB[name].Link end end function SetRecipeLink(name, link) if RecipeDB[name] == nil then RecipeDB[name] = {} end RecipeDB[name].Link = link end function GetRecipeMats(name) if RecipeDB[name] == nil then return "<Invalid Recipe>" else return RecipeDB[name].Mats end end function SetRecipeMats(name, mats) if RecipeDB[name] == nil then RecipeDB[name] = {} end RecipeDB[name].Mats = mats end function SetRecipeKeywords(name, words) if RecipeDB[name] == nil then RecipeDB[name] = {} end RecipeDB[name].Keywords = words end function GetRecipeDescription(name) if RecipeDB[name] == nil then return "<Invalid Recipe>" else return RecipeDB[name].Description end end -- The following functions encapsulate the Component database bysComponentDB = {}; function SetComponentPrice(name, gold, silver, copper) if bysComponentDB[name] == nil then bysComponentDB[name] = {} end bysComponentDB[name].Price = gold*10000 + silver*100 + copper end function GetComponentPrice(name) if bysComponentDB[name] == nil then return 99,99,99 else local copper = mod(bysComponentDB[name].Price, 100); local silver = mod(bysComponentDB[name].Price/100, 100); local gold = bysComponentDB[name].Price/10000; return gold, silver, copper; end end ----------------------------------------------------------------- function Id2Name(id) local longname,_,_,_,_ = ESell_Enchante_getInfoDetail(id); return longname end function Name2Id(name) -- local longname,_,_,_,_ = ESell_Enchante_getInfoDetail(id); -- return longname end squelches = {}; squelchCount = 0; function SendSquelchedMessage(message, channel, arg3, who) squelchCount = squelchCount + 2; SendChatMessage(message, channel, arg3, who); end function Nakas_EditDB(text) local _, firstspace = strfind(text, " ", 1); local _, secondspace = strfind(text, ".*|h|r ", firstspace + 1); local _, thirdspace = strfind(text, " ", secondspace + 1); local link = strsub(text, firstspace + 1, secondspace-1); local key = strsub(text, secondspace + 1, thirdspace-1); local value = strsub(text, thirdspace + 1); ChatFrame1:AddMessage("link<"..link..">",0,1,1); ChatFrame1:AddMessage("key<"..key..">",0,1,1); ChatFrame1:AddMessage("value<"..value..">",0,1,1); for i, enchanteTable in ipairs(EnchantingSell_ListEnchante) do if link == enchanteTable.Link then enchanteTable[key] = value; end end end function Nakas_AddEnchant(link) ESell_Enchante_AddEnchant(link); end function Nakas_Getlink(who, link) printable = gsub(link, "\124", "\124\124"); ChatFrame1:AddMessage("Here's what it really looks like: \"" .. printable .. "\""); end function Nakas_KeywordsHelp(who) message1 = [[The search engine understands the following keywords:]]; message2 = [[Recipe type & rarity: enchant, gem, rare, meta]] message3 = [[Enchant locations: chest, gloves, 1h, 2h, weapon, ...]] message4 = [[Base attributes: str, agil, stam, int, spirit]] message5 = [[Other attributs: spell, crit, damage, healing, stun, ...]] message6 = [[Gem colors: red, orange, yellow, green, blue, purple]]; message7 = [[Common gem names: peridot, garnet, moonstone, ...]] message8 = [[Common gem cuts: inscribed, potent, shifting, ...]]; message9 = [[Rare gem names: topaz, ruby, skyfire, earthstorm, ...]]; message10 = [[Rare gem cuts: enigmatic, destructive, brutal, ...]]; SendSquelchedMessage(message1, "WHISPER", nil, who); SendSquelchedMessage(message2, "WHISPER", nil, who); SendSquelchedMessage(message3, "WHISPER", nil, who); SendSquelchedMessage(message4, "WHISPER", nil, who); SendSquelchedMessage(message5, "WHISPER", nil, who); SendSquelchedMessage(message6, "WHISPER", nil, who); SendSquelchedMessage(message7, "WHISPER", nil, who); SendSquelchedMessage(message8, "WHISPER", nil, who); SendSquelchedMessage(message9, "WHISPER", nil, who); SendSquelchedMessage(message10, "WHISPER", nil, who); ChatFrame1:AddMessage("Spamming keywords to: "..who,0,1,1); end ----------------------------------------------------------------------------------------------- local Nakas_LastWho = ""; local Nakas_LastMessage = ""; local arEnabled = true; local arHideWhispersTimer = 0; local OriginalChatFrame_OnEvent; function NakasBot_OnLoad() this:RegisterEvent("CHAT_MSG_WHISPER"); this:RegisterEvent("AUCTION_ITEM_LIST_UPDATE"); SlashCmdList["NAKASBOT"] = NakasBot_SlashHandler; SLASH_NAKASBOT1 = "/NakasBot"; SLASH_NAKASBOT2 = "/nb"; local cf = getglobal("ChatFrame1"); cf.Nakas_Orig_AddMessage = cf.AddMessage; -- cf.AddMessage = Nakas_ChatFrame_AddMessage; end -- REVISIT: Rewrite to only squelch outgoing whisper replys, not all whispers. -- See http://www.wowwiki.com/HOWTO:_Hook_Chat_Messages -- CHAT_MSG_WHISPER -- Incomming whispers -- CHAT_MSG_WHISPER_INFORM -- Outgoing whispers function Nakas_ChatFrame_AddMessage(self,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9) if strfind(msg, "[Nakas]") ~= nil then ChatFrame3:AddMessage("squelched:"..msg,1,0,0); return; end return self:Nakas_Orig_AddMessage(msg, a1,a2,a3,a4,a5,a6,a7,a8,a9); end function parse(text) local list = {} local pos = 1 while 1 do local first, last = strfind(text, " ", pos) if first then word = strsub(text, pos, first-1) if word ~= "" then tinsert(list, word) end pos = last+1 else word = strsub(text, pos) if word ~= "" then tinsert(list, word) end break end end return list end --local msg = "Phase2:- There isn't any need for iterating over this mini-string."; --local startPos, endPos, firstWord, restOfString = string.find( msg, "(%w+)[%s%p]*(.*)"); --startPos = 1 --endPos = 66 --firstWord = "Phase2" --restOfString = "There isn't any need for iterating over this mini-string." --keywords = { "agility", "strength", "spirit", -- "fire", "nature", "shadow", "frost", "resist", -- "intellect", "stamina", "weapon", "2h", "1h", "bracer", -- "cloak", "chest", "boot", "glove", "shield", "fiery", "icy", "crusader", "might", "lifestealing", -- "winter", "defense", "block", "healing", "heal", "spell", "demonslaying", -- "power", "damage", "link", "resist", "resistance", "armor", "health", "mana", -- "herbalism", "mining", "skinning", "riding", "skill", "speed", "brilliant", "wizard", "oil", -- "assault", "spell", "crit", "brawn", "restore", "prime", "vitality", "tough", "attack", "power", "penetration" }; function Nakas_RepairString(what) repaired = ""; -- ChatFrame1:AddMessage("before: <"..what..">",0,1,1); what = gsub(what, "%%", ""); what = gsub(what, "!", ""); what = gsub(what, "%?", ""); what = gsub(what, "how much for ", ""); what = gsub(what, "how much ", ""); what = gsub(what, "do you have ", ""); -- Take care of itemlinks what = gsub(what, "%]|h|r", "") what = gsub(what, "|.+%[", "") for i,word in ipairs(parse(what)) do if word == "dmg" then word = "damage" end if word == "firey" then word = "fiery" end if word == "spellpower" then word = "spell power" end if word == "ap" then word = "attack power" end repaired = repaired.." "..word; end repaired = strsub(repaired, 2); -- ChatFrame1:AddMessage("repaired: <"..repaired..">",0,1,1); -- for i, parseword in ipairs(parse(repaired)) do -- ChatFrame1:AddMessage(" <"..parseword..">",0,1,1); -- end return repaired; end function Nakas_GetShortDescription(recipie) if tonumber(recipie) == nil then return RecipeDB[recipie].ShortDescription; end if EnchantingSell_ListEnchante[recipie].ShortDescription ~= nil then return EnchantingSell_ListEnchante[recipie].ShortDescription end name, onthis, bonus, bonusnb = ESell_Enchante_getInfoBonus(recipie); longname,_,description,_,link = ESell_Enchante_getInfoDetail(recipie); price,_,_ = ESell_Enchante_getPrice(recipie); if onthis == "Rod" or onthis == nil or bonus == nil then EnchantingSell_ListEnchante[recipie].ShortDescription = "Some Rod..."; end if onthis == "Oil" then EnchantingSell_ListEnchante[recipie].ShortDescription = "Some Oil..."; end if bonusnb == nil then EnchantingSell_ListEnchante[recipie].ShortDescription = bonus.." to "..onthis; else EnchantingSell_ListEnchante[recipie].ShortDescription = "+"..bonusnb.." "..bonus.." to "..onthis; end return EnchantingSell_ListEnchante[recipie].ShortDescription; end function Nakas_GetKeywords(recipie) -- ChatFrame1:AddMessage(recipie,0,1,1); if tonumber(recipie) == nil then return RecipeDB[recipie].Keywords; end if EnchantingSell_ListEnchante[recipie].Keywords == nil then EnchantingSell_ListEnchante[recipie].Keywords = gsub(strlower(Nakas_GetShortDescription(recipie)),"%+",""); end return EnchantingSell_ListEnchante[recipie].Keywords; end function Nakas_GetLink(recipe) if tonumber(recipe) == nil then return RecipeDB[recipe].Link; else return EnchantingSell_ListEnchante[recipe].Link; end end function Nakas_GetPrice(recipe) if tonumber(recipe) == nil then return RecipeDB[recipe].Price; else price,_,_ = ESell_Enchante_getPrice(recipe); return price/10000; end end function Nakas_DisplayMatches(matches, who) ChatFrame1:AddMessage("Displaying Matches ("..getn(matches).." found)",0,1,1); if getn(matches) == 0 then SendSquelchedMessage("> No matches found", "WHISPER", nil, who); return; end SendSquelchedMessage("> =========<< Search Results >>=========", "WHISPER", nil, who); for i, recipe in ipairs(matches) do short_description = Nakas_GetShortDescription(recipe); link = Nakas_GetLink(recipe); price = Nakas_GetPrice(recipe); if price >= 3 then if price >= 10000 then SendSquelchedMessage("> "..link.." "..short_description, "WHISPER", nil, who); else SendSquelchedMessage("> "..link.." "..short_description.." ("..price.."g+tip)", "WHISPER", nil, who); end end if i > 20 then SendSquelchedMessage("> Displaying first 20 matches ("..getn(matches).." found). Use more keywords to limit the search", "WHISPER", nil, who); break; end end SendSquelchedMessage("> I am currently in: "..GetZoneText(), "WHISPER", nil, who); arHideWhispersTimer = GetTime(); end -- The word matches the recipe if: -- a) The word is 3 or more letters and matches the beginning of a keyword -- b) The word is a number and is an exact match to a keyword function Nakas_WordMatchesRecipe(word, recipe) local keywords = strlower(Nakas_GetKeywords(recipe)); -- If the word is fewer than 3 characters, a full match is required if strlen(word) < 3 then for i, keyword in ipairs(parse(keywords)) do if keyword == word then return true; end end else -- otherwise a match to the front of the keyword is required for i, keyword in ipairs(parse(keywords)) do if strfind(keyword, word,1,true) == 1 then return true; end end end return false; end function Nakas_GetBestMatches(searchstring) local best_matches = {}; local max_matches = 0; local searchset = parse(searchstring); for name, recipe in pairs(RecipeDB) do matches = 0; for i, word in ipairs(searchset) do if Nakas_WordMatchesRecipe(word, name) then matches = matches + 1; -- ChatFrame1:AddMessage("match:"..name,0,1,1); end end if matches > max_matches then max_matches = matches; best_matches = {}; end if matches == max_matches then tinsert(best_matches, name); end end -- ChatFrame1:AddMessage("max_matches:"..max_matches,0,1,1); -- ChatFrame1:AddMessage("getn(searchset):"..getn(searchset),0,1,1); if max_matches * 2 > getn(searchset) then return best_matches; else return nil end end -- Sorting function function Nakas_EnchantCostsMore(a, b) return Nakas_GetPrice(a) > Nakas_GetPrice(b); end function Nakas_HelpMenu(who) message1 = [[Welcome to Nakas' Enchanting & Jewelcrafting search engine!]]; message2 = [[Please choose from the following options:]]; message3 = [[ "search" - Describes how to use the search engine.]]; message4 = [[ "mats" - Gives the prices of mats and describes how prices are calculated.]]; message5 = [[ "tips" - Info on tipping]]; message6 = [[ "new" - Lists my new Outlands enchants]]; message7 = [[ "keywords" - Lists the keywords that the search engine recognizes]]; message8 = [[]]; message9 = [[Feel free to add me to your friends list and use the search engine anytime!]] SendSquelchedMessage(message1, "WHISPER", nil, who); SendSquelchedMessage(message2, "WHISPER", nil, who); SendSquelchedMessage(message3, "WHISPER", nil, who); SendSquelchedMessage(message4, "WHISPER", nil, who); SendSquelchedMessage(message5, "WHISPER", nil, who); SendSquelchedMessage(message6, "WHISPER", nil, who); SendSquelchedMessage(message7, "WHISPER", nil, who); SendSquelchedMessage(message8, "WHISPER", nil, who); SendSquelchedMessage(message9, "WHISPER", nil, who); ChatFrame1:AddMessage("Spamming help to: "..who,0,1,1); arHideWhispersTimer = GetTime(); end function Nakas_SearchHelpMenu(who) message1 = [[The search engine looks for keywords in your whisper, words like "agil", "fiery", "gloves", "+7", etc. If more than 50% of the words in your whisper are keywords, it will assume your whisper is a query.]]; message2 = [[It will look for enchants that match the most number of words by comparing your whisper with the name of the enchant and the description text within the link.]]; message3 = [[Therefore, try not to have extra words in your whisper. For example, the whisper "+25 agility" will trigger the search engine, but the whisper "What do you charge for +25 agility" will not because most of the words are not keywords.]] SendSquelchedMessage(message1, "WHISPER", nil, who); SendSquelchedMessage(message2, "WHISPER", nil, who); SendSquelchedMessage(message3, "WHISPER", nil, who); ChatFrame1:AddMessage("Spamming search help to: "..who,0,1,1); arHideWhispersTimer = GetTime(); end NewEnchantList = { "Enchant Bracer - Brawn", "Enchant Bracer - Assault", "Enchant Chest - Restore Mana Prime", "Enchant Bracer - Stats", "Enchant Chest - Exceptional Health", "Enchant Cloak - Greater Agility", "Enchant Cloak - Major Armor", "Enchant Gloves - Assault", "Enchant Shield - Tough Shield", "Enchant Bracer - Major Intellect", "Enchant Gloves - Blasting", "Enchant Shield - Major Stamina", "Enchant Shield - Intellect", "Enchant Cloak - Spell Penetration", "Enchant Bracer - Superior Healing", "Enchant Weapon - Major Spellpower", "Enchant Weapon - Major Intellect", "Enchant Bracer - Spellpower", "Enchant Gloves - Major Spellpower", "Enchant Gloves - Major Strength", } function Nakas_NewMenu(who) message1 = [[Here is a list of the new Burning Crusade enchants that I can do:]] SendSquelchedMessage(message1, "WHISPER", nil, who); matches = {}; for i, enchant in ipairs(EnchantingSell_ListEnchante) do for j, newEnchant in ipairs(NewEnchantList) do if enchant["LongName"] == newEnchant then tinsert(matches, i); end end end sort(matches, Nakas_EnchantCostsMore); Nakas_DisplayMatches(matches, who); ChatFrame1:AddMessage("Spamming new help to: "..who,0,1,1); arHideWhispersTimer = GetTime(); end function Nakas_MatsHelpMenu(who) message1 = [[The prices of the enchants are auto-calculated from the average AH price of the required mats.]] message2 = [[If you supply your own mats, the price will be discounted appropriatly. If you provide all the mats, you'll only be responsible for the tip]] message3 = [[The price of mats can vary from day to day with the market, so please don't be too upset if they're a little off. Currently, the prices for some of the more expensive mats are set as follows:]] SendSquelchedMessage(message1, "WHISPER", nil, who); SendSquelchedMessage(message2, "WHISPER", nil, who); SendSquelchedMessage(message3, "WHISPER", nil, who); for i, mat in ipairs(EnchantingSell_ListComponant) do price = mat.PriceUnite / 10000; name = mat.Name; -- ChatFrame1:AddMessage(name,0,1,1); inBag, inBank, onAlt = ESell_Reagent_getCount(i, player); inStock = inBag + inBank; if price > 3 and (strfind(name,"Essence") ~= nil or strfind(name,"Shard") ~= nil or strfind(name,"Dust") ~= nil or strfind(name,"Orb") ~= nil or strfind(name,"Primal") ~= nil) then link = EnchantingSell_ListComponant[i]["Link"]; SendSquelchedMessage(">"..link.." "..price.."g ("..inStock.." in stock)", "WHISPER", nil, who); end end ChatFrame1:AddMessage("Spamming mats help to: "..who,0,1,1); arHideWhispersTimer = GetTime(); end function Nakas_TipsHelpMenu(who) message1 = [[The prices quoted are given as a gold amount plus a tip. The gold amount is the market value of the mats, the tip is the gratuity for doing the enchant. In general, tipping is not optional, a few gold tip is considered minimum for any enchant.]]; -- message2 = [[In general, tipping is not optional, a few gold tip is considered minimum for any enchant.]] message3 = [[The guidelines for specific popular enchants/cuts are:]] message4 = [[ 15-25g: +22 Intellect]]; message5 = [[ 10-20g: Spellpower, Healing power, Lifestealing, +5 1h Damage]] message6 = [[ 5-15g: Crusader, +25 Agil, +15 Agil, 2% block, +15 resist]] message7 = [[ 2-5g: Cutting green quality gems]] message8 = [[ 10-15g: Cutting blue quality gems]] message9 = [[For other enchants, the general rule of thumb is 10% the price of mats, with a few gold minimum.]] SendSquelchedMessage(message1, "WHISPER", nil, who); -- SendSquelchedMessage(message2, "WHISPER", nil, who); SendSquelchedMessage(message3, "WHISPER", nil, who); SendSquelchedMessage(message4, "WHISPER", nil, who); SendSquelchedMessage(message5, "WHISPER", nil, who); SendSquelchedMessage(message6, "WHISPER", nil, who); SendSquelchedMessage(message7, "WHISPER", nil, who); SendSquelchedMessage(message8, "WHISPER", nil, who); SendSquelchedMessage(message9, "WHISPER", nil, who); ChatFrame1:AddMessage("Spamming tips help to: "..who,0,1,1); arHideWhispersTimer = GetTime(); end function Nakas_ListAllGems() string = ""; for name, recipe in pairs(RecipeDB) do ChatFrame1:AddMessage(GetItemCount(recipe.Link).." "..recipe.Link); end end function NakasBot_OnEvent(event) if (event == "CHAT_MSG_WHISPER") then local what = string.lower(arg1); local who = arg2; -- spam filter --if UnitLevel(who) == 1 then -- ChatFrame1:AddMessage("Message from "..who.." blocked",1,0,0); -- return; --end if (arEnabled == false) then -- ChatFrame1:AddMessage("> ".."disabled",1,0,0); return; end if (strfind(what,">") == 1) then -- ChatFrame1:AddMessage("> ".."bracket found",1,0,0); return; end if strfind(what, "help") == 1 then Nakas_HelpMenu(who); end if strfind(what, "search") == 1 then Nakas_SearchHelpMenu(who); end if strfind(what, "mats") == 1 then Nakas_MatsHelpMenu(who); end if strfind(what, "tips") == 1 then Nakas_TipsHelpMenu(who); end if strfind(what, "new") == 1 then Nakas_NewMenu(who); end if strfind(what, "getlink") == 1 then Nakas_Getlink(who, arg1); end if strfind(what, "keyword") == 1 then Nakas_KeywordsHelp(who); end if strfind(what, "editdb") == 1 then Nakas_EditDB(arg1); end if strfind(what, "addenchant") == 1 then Nakas_EditDB(arg1); end if strfind(what, "listall") == 1 then Nakas_ListAllGems(arg1); end what = Nakas_RepairString(what); -- ChatFrame1:AddMessage("> Original string: ["..arg1.."]",1,0,0); -- ChatFrame1:AddMessage("> Repaired string: ["..what.."]",1,0,0); matches = Nakas_GetBestMatches(what); if matches ~= nil then ChatFrame1:AddMessage("> "..who..": "..arg1,1,0,0); sort(matches, Nakas_EnchantCostsMore); Nakas_DisplayMatches(matches, who); else Nakas_LastWho = who; Nakas_LastMessage = what; end end end function NakasBot_SlashHandler(arg1) if (arg1 == "on") then arEnabled = true; ChatFrame1:AddMessage("NakasEnchant enabled"); return; end if (arg1 == "off") then arEnabled = false; ChatFrame1:AddMessage("NakasEnchant disabled"); return; end if (arg1 == "reply") then matches = Nakas_GetBestMatches(Nakas_LastMessage); sort(matches, Nakas_EnchantCostsMore); Nakas_DisplayMatches(matches, Nakas_LastWho); end end