void AuctionHouse::SendAuctionList(Player * plr, WorldPacket * packet) { uint32 start_index, current_index = 0; uint32 counted_items = 0; std::string auctionString; uint8 levelRange1, levelRange2, usableCheck; int32 inventory_type, itemclass, itemsubclass, rarityCheck; *packet >> start_index; *packet >> auctionString; *packet >> levelRange1 >> levelRange2; *packet >> inventory_type >> itemclass >> itemsubclass; *packet >> rarityCheck >> usableCheck; // convert auction string to lowercase for faster parsing. if(auctionString.length() > 0) { for(uint32 j = 0; j < auctionString.length(); ++j) auctionString[j] = tolower(auctionString[j]); } WorldPacket data(SMSG_AUCTION_LIST_RESULT, 7000); data << uint32(0); auctionLock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Auction*>::iterator itr = auctions.begin(); ItemPrototype * proto; for(; itr != auctions.end(); ++itr) { if(itr->second->Deleted) continue; proto = itr->second->pItem->GetProto(); // Check the auction for parameters // inventory type if(inventory_type != -1 && inventory_type != (int32)proto->InventoryType) continue; // class if(itemclass != -1 && itemclass != (int32)proto->Class) continue; // subclass if(itemsubclass != -1 && itemsubclass != (int32)proto->SubClass) continue; // this is going to hurt. - name if(auctionString.length() > 0 && !FindXinYString(auctionString, proto->lowercase_name)) continue; // rarity if(rarityCheck != -1 && rarityCheck != (int32)proto->Quality) continue; // level range check - lower boundary if(levelRange1 && proto->RequiredLevel < levelRange1) continue; // level range check - high boundary if(levelRange2 && proto->RequiredLevel > levelRange2) continue; // usable check - this will hurt too :( if(usableCheck) { // allowed class if(proto->AllowableClass && !(plr->getClassMask() & proto->AllowableClass)) continue; if(proto->RequiredLevel && proto->RequiredLevel > plr->getLevel()) continue; if(proto->AllowableRace && !(plr->getRaceMask() & proto->AllowableRace)) continue; if(proto->Class == 4 && proto->SubClass && !(plr->GetArmorProficiency()&(((uint32)(1))<<proto->SubClass))) continue; if(proto->Class == 2 && proto->SubClass && !(plr->GetWeaponProficiency()&(((uint32)(1))<<proto->SubClass))) continue; if(proto->RequiredSkill && (!plr->_HasSkillLine(proto->RequiredSkill) || proto->RequiredSkillRank > plr->_GetSkillLineCurrent(proto->RequiredSkill, true))) continue; } // Page system. ++counted_items; if(counted_items >= start_index + 50) continue; current_index++; if(start_index && current_index < start_index) continue; // all checks passed -> add to packet. itr->second->AddToPacket(data); (*(uint32*)&data.contents()[0])++; } // total count data << uint32(1 + counted_items); #ifdef USING_BIG_ENDIAN swap32((uint32*)&data.contents()[0]); #endif auctionLock.ReleaseReadLock(); plr->GetSession()->SendPacket(&data); }
bool ChatHandler::HandleQuestLookupCommand(const char * args, WorldSession * m_session) { if(!*args) return false; string x = string(args); ASCENT_TOLOWER(x); if(x.length() < 4) { RedSystemMessage(m_session, "Your search string must be at least 5 characters long."); return true; } BlueSystemMessage(m_session, "Starting search of quests `%s`...", x.c_str()); uint32 t = getMSTime(); StorageContainerIterator<Quest> * itr = QuestStorage.MakeIterator(); Quest * i; uint32 count = 0; string y; string recout; while(!itr->AtEnd()) { i = itr->Get(); y = string(i->title); ASCENT_TOLOWER(y); if(FindXinYString(x, y)) { string questid = MyConvertIntToString(i->id); const char * questtitle = i->title; recout = "|cff00ccff"; recout += questid.c_str(); recout += ": "; recout += questtitle; recout += "\n"; SendMultilineMessage(m_session, recout.c_str()); ++count; if(count == 25) { RedSystemMessage(m_session, "More than 25 results returned. aborting."); break; } } if(!itr->Inc()) break; } itr->Destruct(); if (count == 0) { recout = "|cff00ccffNo matches found.\n\n"; SendMultilineMessage(m_session, recout.c_str()); } BlueSystemMessage(m_session, "Search completed in %u ms.", getMSTime() - t); return true; }
bool ChatHandler::HandleQuestLookupCommand(const char * args, WorldSession * m_session) { if(!*args) return false; string x = string(args); arcemu_TOLOWER(x); if(x.length() < 4) { RedSystemMessage(m_session, "Your search string must be at least 4 characters long."); return true; } BlueSystemMessage(m_session, "Starting search of quests `%s`...", x.c_str()); uint32 t = getMSTime(); StorageContainerIterator<Quest> * itr = QuestStorage.MakeIterator(); Quest * i; uint32 count = 0; string y; string recout; while(!itr->AtEnd()) { i = itr->Get(); y = string(i->title); LocalizedQuest *li = (m_session->language>0) ? sLocalizationMgr.GetLocalizedQuest(i->id, m_session->language) : NULL; std::string liName = std::string(li ? li->Title : ""); arcemu_TOLOWER(liName); arcemu_TOLOWER(y); bool localizedFound = false; if(FindXinYString(x, liName)) localizedFound = true; if(FindXinYString(x, y) || localizedFound) { string questid = MyConvertIntToString(i->id); const char * questtitle = localizedFound ? (li ? li->Title : "") : i->title; // send quest link recout = questid.c_str(); recout += ": |cff00ccff|Hquest:"; recout += questid.c_str(); recout += ":"; recout += MyConvertIntToString(i->min_level); recout += "|h["; recout += questtitle; recout += "]|h|r"; SendMultilineMessage(m_session, recout.c_str()); ++count; if(count == 25) { RedSystemMessage(m_session, "More than 25 results returned. aborting."); break; } } if(!itr->Inc()) break; } itr->Destruct(); if (count == 0) { recout = "|cff00ccffNo matches found.\n\n"; SendMultilineMessage(m_session, recout.c_str()); } BlueSystemMessage(m_session, "Search completed in %u ms.", getMSTime() - t); return true; }
void AuctionHouse::SendAuctionList(Player* plr, WorldPacket* packet) { std::string searchedname; uint8 levelmin, levelmax, usable; uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; *packet >> listfrom; // start, used for page control listing by 50 elements *packet >> searchedname; *packet >> levelmin >> levelmax; *packet >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; *packet >> quality >> usable; packet->read_skip<uint8>(); // unk packet->read_skip<uint8>(); // unk // this block looks like it uses some lame byte packing or similar... for (uint8 i = 0; i < 15; i++) packet->read_skip<uint8>(); WorldPacket data(SMSG_AUCTION_LIST_RESULT, 7000); uint32 count = 0; uint32 totalcount = 0; data << uint32(0); // convert auction string to lowercase for faster parsing. if (searchedname.length() > 0) { for (uint32 j = 0; j < searchedname.length(); ++j) searchedname[j] = static_cast<char>(tolower(searchedname[j])); } auctionLock.AcquireReadLock(); std::unordered_map<uint32, Auction*>::iterator itr = auctions.begin(); ItemPrototype* proto; for (; itr != auctions.end(); ++itr) { if (itr->second->Deleted) continue; proto = itr->second->pItem->GetProto(); // Check the auction for parameters // inventory type if (auctionSlotID != -1 && auctionSlotID != (int32)proto->InventoryType) continue; // class if (auctionMainCategory != 0xffffffff && auctionMainCategory != (int32)proto->Class) continue; // subclass if (auctionSubCategory != 0xffffffff && auctionSubCategory != (int32)proto->SubClass) continue; // this is going to hurt. - name if (searchedname.length() > 0 && !FindXinYString(searchedname, proto->lowercase_name)) continue; // rarity if (quality != 0xffffffff && quality > (int32)proto->Quality) continue; // level range check - lower boundary if (levelmin && proto->RequiredLevel < levelmin) continue; // level range check - high boundary if (levelmax && proto->RequiredLevel > levelmax) continue; // usable check - this will hurt too :( if (quality) { // allowed class if (proto->AllowableClass && !(plr->getClassMask() & proto->AllowableClass)) continue; if (proto->RequiredLevel && proto->RequiredLevel > plr->getLevel()) continue; if (proto->AllowableRace && !(plr->getRaceMask() & proto->AllowableRace)) continue; if (proto->Class == 4 && proto->SubClass && !(plr->GetArmorProficiency() & (((uint32)(1)) << proto->SubClass))) continue; if (proto->Class == 2 && proto->SubClass && !(plr->GetWeaponProficiency() & (((uint32)(1)) << proto->SubClass))) continue; if (proto->RequiredSkill && (!plr->_HasSkillLine(proto->RequiredSkill) || proto->RequiredSkillRank > plr->_GetSkillLineCurrent(proto->RequiredSkill, true))) continue; } // Add the item if no search term or if entered search term was found if (count < 50 && totalcount >= listfrom) { ++count; itr->second->BuildAuctionInfo(data); } ++totalcount; } data.put<uint32>(0, count); data << uint32(totalcount); data << uint32(300); //unk 2.3.0 auctionLock.ReleaseReadLock(); plr->GetSession()->SendPacket(&data); }
/** Handles .lookup achievement GM achievement lookup command usage: .lookup achievement string : searches for "string" in achievement name .lookup achievement desc string : searches for "string" in achievement description .lookup achievement reward string : searches for "string" in achievement reward name .lookup achievement criteria string : searches for "string" in achievement criteria name .lookup achievement all string : searches for "string" in achievement name, description, reward, and critiera */ bool ChatHandler::HandleLookupAchievementCmd(const char* args, WorldSession* m_session) { if(!*args) return false; string x; bool lookupname = true, lookupdesc = false, lookupcriteria = false, lookupreward = false; if(strnicmp(args, "name ", 5) == 0) { x = string(args + 5); } else if(strnicmp(args, "desc ", 5) == 0) { lookupname = false; lookupdesc = true; x = string(args + 5); } else if(strnicmp(args, "criteria ", 9) == 0) { lookupname = false; lookupcriteria = true; x = string(args + 9); } else if(strnicmp(args, "reward ", 7) == 0) { lookupname = false; lookupreward = true; x = string(args + 7); } else if(strnicmp(args, "all ", 4) == 0) { lookupdesc = true; lookupcriteria = true; lookupreward = true; x = string(args + 4); } else { x = string(args); } if(x.length() < 4) { RedSystemMessage(m_session, "Your search string must be at least 4 characters long."); return true; } arcemu_TOLOWER(x); GreenSystemMessage(m_session, "Starting search of achievement `%s`...", x.c_str()); uint32 t = getMSTime(); uint32 i, j, numFound = 0; string y, recout; char playerGUID[17]; snprintf(playerGUID, 17, I64FMT, m_session->GetPlayer()->GetGUID()); if(lookupname || lookupdesc || lookupreward) { std::set<uint32> foundList; j = dbcAchievementStore.GetNumRows(); bool foundmatch; for(i = 0; i < j && numFound < 25; ++i) { AchievementEntry const* achievement = dbcAchievementStore.LookupRowForced(i); if(achievement) { if(foundList.find(achievement->ID) != foundList.end()) { // already listed this achievement (some achievements have multiple entries in dbc) continue; } foundmatch = false; if(lookupname) { y = string(achievement->name); arcemu_TOLOWER(y); foundmatch = FindXinYString(x, y); } if(!foundmatch && lookupdesc) { y = string(achievement->description); arcemu_TOLOWER(y); foundmatch = FindXinYString(x, y); } if(!foundmatch && lookupreward) { y = string(achievement->rewardName); arcemu_TOLOWER(y); foundmatch = FindXinYString(x, y); } if(!foundmatch) { continue; } foundList.insert(achievement->ID); std::stringstream strm; strm << achievement->ID; // create achievement link recout = "|cffffffffAchievement "; recout += strm.str(); recout += ": |cfffff000|Hachievement:"; recout += strm.str(); recout += ":"; recout += (const char*)playerGUID; time_t completetime = m_session->GetPlayer()->GetAchievementMgr().GetCompletedTime(achievement); if(completetime) { // achievement is completed struct tm* ct; ct = localtime(&completetime); strm.str(""); strm << ":1:" << ct->tm_mon + 1 << ":" << ct->tm_mday << ":" << ct->tm_year - 100 << ":-1:-1:-1:-1|h["; recout += strm.str(); } else { // achievement is not completed recout += ":0:0:0:-1:0:0:0:0|h["; } recout += achievement->name; if(!lookupreward) { recout += "]|h|r"; } else { recout += "]|h |cffffffff"; recout += achievement->rewardName; recout += "|r"; } strm.str(""); SendMultilineMessage(m_session, recout.c_str()); if(++numFound >= 25) { RedSystemMessage(m_session, "More than 25 results found."); break; } } } // for loop (number of rows, up to 25) } // lookup name or description if(lookupcriteria && numFound < 25) { std::set<uint32> foundList; j = dbcAchievementCriteriaStore.GetNumRows(); for(i = 0; i < j && numFound < 25; ++i) { AchievementCriteriaEntry const* criteria = dbcAchievementCriteriaStore.LookupRowForced(i); if(criteria) { if(foundList.find(criteria->ID) != foundList.end()) { // already listed this achievement (some achievements have multiple entries in dbc) continue; } y = string(criteria->name); arcemu_TOLOWER(y); if(!FindXinYString(x, y)) { continue; } foundList.insert(criteria->ID); std::stringstream strm; strm << criteria->ID; recout = "|cffffffffCriteria "; recout += strm.str(); recout += ": |cfffff000"; recout += criteria->name; strm.str(""); AchievementEntry const* achievement = dbcAchievementStore.LookupEntryForced(criteria->referredAchievement); if(achievement) { // create achievement link recout += " |cffffffffAchievement "; strm << achievement->ID; recout += strm.str(); recout += ": |cfffff000|Hachievement:"; recout += strm.str(); recout += ":"; recout += (const char*)playerGUID; time_t completetime = m_session->GetPlayer()->GetAchievementMgr().GetCompletedTime(achievement); if(completetime) { // achievement is completed struct tm* ct; ct = localtime(&completetime); strm.str(""); strm << ":1:" << ct->tm_mon + 1 << ":" << ct->tm_mday << ":" << ct->tm_year - 100 << ":-1:-1:-1:-1|h["; recout += strm.str(); } else { // achievement is not completed recout += ":0:0:0:-1:0:0:0:0|h["; } recout += achievement->name; if(!lookupreward) { recout += "]|h|r"; } else { recout += "]|h |cffffffff"; recout += achievement->rewardName; recout += "|r"; } strm.str(""); } SendMultilineMessage(m_session, recout.c_str()); if(++numFound >= 25) { RedSystemMessage(m_session, "More than 25 results found."); break; } } } // for loop (number of rows, up to 25) } // lookup criteria if(numFound == 0) { recout = "|cff00ccffNo matches found."; SendMultilineMessage(m_session, recout.c_str()); } BlueSystemMessage(m_session, "Search completed in %u ms.", getMSTime() - t); return true; }