diff --git a/common/fixed_memory_hash_set.h b/common/fixed_memory_hash_set.h index db06b1278..d020f1b80 100644 --- a/common/fixed_memory_hash_set.h +++ b/common/fixed_memory_hash_set.h @@ -49,7 +49,7 @@ namespace EQEmu { size_ = size; byte *ptr = data; - *reinterpret_cast(ptr) = max_element_id; + *reinterpret_cast(ptr) = max_element_id + 1; offset_count_ = max_element_id + 1; ptr += sizeof(key_type); @@ -62,8 +62,8 @@ namespace EQEmu { ptr += sizeof(key_type); offsets_ = reinterpret_cast(ptr); - memset(ptr, 0xFFFFFFFFU, sizeof(key_type) * max_element_id); - ptr += sizeof(key_type) * max_element_id; + memset(ptr, 0xFFFFFFFFU, sizeof(key_type) * (max_element_id + 1)); + ptr += sizeof(key_type) * (max_element_id + 1); elements_ = reinterpret_cast(ptr); } @@ -151,6 +151,11 @@ namespace EQEmu { size_type max_size() const { return max_elements_; } + + //! Returns the maximum key one can use with the set. + key_type max_key() const { + return offset_count_ > 0 ? (offset_count_ - 1) : 0; + } /*! Retrieve value operator diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 0d4d206be..61fc726c5 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -726,28 +726,28 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) } -int32 SharedDatabase::GetItemsCount(uint32* oMaxID) { +int32 SharedDatabase::GetItemsCount(uint32* max_id) { char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; int32 ret = -1; - char query[] = "SELECT MAX(id),count(*) FROM items"; - if (RunQuery(query, strlen(query), errbuf, &result)) { + char query[] = "SELECT MAX(id), count(*) FROM items"; + if (RunQuery(query, static_cast(strlen(query)), errbuf, &result)) { row = mysql_fetch_row(result); if (row != NULL && row[1] != 0) { ret = atoi(row[1]); - if (oMaxID) { + if (max_id) { if (row[0]) - *oMaxID = atoi(row[0]); + *max_id = atoi(row[0]); else - *oMaxID = 0; + *max_id = 0; } } mysql_free_result(result); } else { - cerr << "Error in GetItemsCount query '" << query << "' " << errbuf << endl; + LogFile->write(EQEMuLog::Error, "Error in GetItemsCount '%s': '%s'", query, errbuf); } return ret; @@ -788,308 +788,315 @@ int32 SharedDatabase::GetNPCTypesCount(uint32* oMaxID) { return -1; } - -bool SharedDatabase::extDBLoadItems(int32 iItemCount, uint32 iMaxItemID) { - return s_usedb->DBLoadItems(iItemCount, iMaxItemID); -} - bool SharedDatabase::LoadItems() { - if (!EMuShareMemDLL.Load()) - return false; - int32 tmp = 0; - tmp = GetItemsCount(&max_item); - if (tmp == -1) { - cout << "Error: SharedDatabase::LoadItems() (sharemem): GetItemsCount() returned -1" << endl; - return false; - } - bool ret = EMuShareMemDLL.Items.DLLLoadItems(&extDBLoadItems, sizeof(Item_Struct), &tmp, &max_item); - return ret; + if(items_mmf) { + return true; + } + + try { + EQEmu::IPCMutex mutex("items"); + mutex.Lock(); + items_mmf = new EQEmu::MemoryMappedFile("shared/items"); + + uint32 max_item = 0; + int32 items = GetItemsCount(&max_item); + if(items == -1) { + EQ_EXCEPT("SharedDatabase", "Database returned no result"); + } + uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); + if(items_mmf->Size() != size) { + EQ_EXCEPT("SharedDatabase", "Couldn't load items because items_mmf->Size() != size"); + } + + items_hash = new EQEmu::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), size); + mutex.Unlock(); + } catch(std::exception& ex) { + LogFile->write(EQEMuLog::Error, "Error Loading Items: %s", ex.what()); + return false; + } + + return true; } -// Load all database items into cache -bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) { - _CP(Database_DBLoadItems); - char errbuf[MYSQL_ERRMSG_SIZE]; +void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) { + EQEmu::FixedMemoryHashSet hash(reinterpret_cast(data), size, items, max_item_id); + char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; - bool ret = false; - - LogFile->write(EQEMuLog::Status, "Loading items from database: count=%i", iItemCount); - - // Make sure enough memory was alloc'd in cache - int32 item_count = GetItemsCount(&max_item); - if (item_count != iItemCount) { - LogFile->write(EQEMuLog::Error, "Insufficient shared memory to load items (actual=%i, allocated=%i)", item_count, iItemCount); - return ret; - } - else if (max_item != iMaxItemID) { - LogFile->write(EQEMuLog::Error, "Insufficient shared memory to load items (max item=%i, allocated=%i). Increase MMF_EQMAX_ITEMS define", max_item, iMaxItemID); - return ret; - } - - bool disableNoRent = false; - char ndbuffer[4]; - if(GetVariable("disablenorent", ndbuffer, 4)) { - if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { - disableNoRent = true; - } - } - bool disableNoDrop = false; - if(GetVariable("disablenodrop", ndbuffer, 4)) { - if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { - disableNoDrop = true; - } - } - bool disableLoreGroup = false; - if(GetVariable("disablelore", ndbuffer, 4)) { - if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { - disableLoreGroup = true; - } - } - bool disableNoTransfer = false; - if(GetVariable("disablenotransfer", ndbuffer, 4)) { - if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { - disableNoTransfer = true; - } - } - - // Retrieve all items from database - char query[] = "select source," + + char ndbuffer[4]; + bool disableNoRent = false; + if(GetVariable("disablenorent", ndbuffer, 4)) { + if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { + disableNoRent = true; + } + } + bool disableNoDrop = false; + if(GetVariable("disablenodrop", ndbuffer, 4)) { + if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { + disableNoDrop = true; + } + } + bool disableLoreGroup = false; + if(GetVariable("disablelore", ndbuffer, 4)) { + if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { + disableLoreGroup = true; + } + } + bool disableNoTransfer = false; + if(GetVariable("disablenotransfer", ndbuffer, 4)) { + if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') { + disableNoTransfer = true; + } + } + + char query[] = "select source," #define F(x) "`"#x"`," #include "item_fieldlist.h" #undef F "updated" " from items order by id"; - - Item_Struct item; - if (RunQuery(query, sizeof(query), errbuf, &result)) { - while((row = mysql_fetch_row(result))) { -#if EQDEBUG >= 6 - LogFile->write(EQEMuLog::Status, "Loading %s:%i", row[ItemField::name], row[ItemField::id]); -#endif - memset(&item, 0, sizeof(Item_Struct)); + Item_Struct item; + if(RunQuery(query, sizeof(query), errbuf, &result)) { + while((row = mysql_fetch_row(result))) { + memset(&item, 0, sizeof(Item_Struct)); - item.ItemClass = (uint8)atoi(row[ItemField::itemclass]); - strcpy(item.Name,row[ItemField::name]); - strcpy(item.Lore,row[ItemField::lore]); - strcpy(item.IDFile,row[ItemField::idfile]); - item.ID = (uint32)atoul(row[ItemField::id]); - item.Weight = (uint8)atoi(row[ItemField::weight]); + item.ItemClass = (uint8)atoi(row[ItemField::itemclass]); + strcpy(item.Name,row[ItemField::name]); + strcpy(item.Lore,row[ItemField::lore]); + strcpy(item.IDFile,row[ItemField::idfile]); + item.ID = (uint32)atoul(row[ItemField::id]); + item.Weight = (uint8)atoi(row[ItemField::weight]); item.NoRent = disableNoRent ? (uint8)atoi("255") : (uint8)atoi(row[ItemField::norent]); - item.NoDrop = disableNoDrop ? (uint8)atoi("255") : (uint8)atoi(row[ItemField::nodrop]); - item.Size = (uint8)atoi(row[ItemField::size]); - item.Slots = (uint32)atoul(row[ItemField::slots]); - item.Price = (uint32)atoul(row[ItemField::price]); - item.Icon = (uint32)atoul(row[ItemField::icon]); - //item.Unk012 = (int32)atoul(row[ItemField::UNK012]); - //item.Unk013 = (uint32)atoul(row[ItemField::UNK013]); - item.BenefitFlag = (uint32)atoul(row[ItemField::benefitflag]); - item.Tradeskills = (atoi(row[ItemField::tradeskills])==0) ? false : true; - item.CR = (int8)atoi(row[ItemField::cr]); - item.DR = (int8)atoi(row[ItemField::dr]); - item.PR = (int8)atoi(row[ItemField::pr]); - item.MR = (int8)atoi(row[ItemField::mr]); - item.FR = (int8)atoi(row[ItemField::fr]); - item.AStr = (int8)atoi(row[ItemField::astr]); - item.ASta = (int8)atoi(row[ItemField::asta]); - item.AAgi = (int8)atoi(row[ItemField::aagi]); - item.ADex = (int8)atoi(row[ItemField::adex]); - item.ACha = (int8)atoi(row[ItemField::acha]); - item.AInt = (int8)atoi(row[ItemField::aint]); - item.AWis = (int8)atoi(row[ItemField::awis]); - item.HP = (int32)atoul(row[ItemField::hp]); - item.Mana = (int32)atoul(row[ItemField::mana]); - item.AC = (int32)atoul(row[ItemField::ac]); - item.Deity = (uint32)atoul(row[ItemField::deity]); - item.SkillModValue = (int32)atoul(row[ItemField::skillmodvalue]); - //item.Unk033 = (int32)atoul(row[ItemField::UNK033]); - item.SkillModType = (uint32)atoul(row[ItemField::skillmodtype]); - item.BaneDmgRace = (uint32)atoul(row[ItemField::banedmgrace]); - item.BaneDmgAmt = (int8)atoi(row[ItemField::banedmgamt]); - item.BaneDmgBody = (uint32)atoul(row[ItemField::banedmgbody]); - item.Magic = (atoi(row[ItemField::magic])==0) ? false : true; - item.CastTime_ = (int32)atoul(row[ItemField::casttime_]); - item.ReqLevel = (uint8)atoi(row[ItemField::reqlevel]); - item.BardType = (uint32)atoul(row[ItemField::bardtype]); - item.BardValue = (int32)atoul(row[ItemField::bardvalue]); - item.Light = (int8)atoi(row[ItemField::light]); - item.Delay = (uint8)atoi(row[ItemField::delay]); - item.RecLevel = (uint8)atoi(row[ItemField::reclevel]); - item.RecSkill = (uint8)atoi(row[ItemField::recskill]); - item.ElemDmgType = (uint8)atoi(row[ItemField::elemdmgtype]); - item.ElemDmgAmt = (uint8)atoi(row[ItemField::elemdmgamt]); - item.Range = (uint8)atoi(row[ItemField::range]); - item.Damage = (uint32)atoi(row[ItemField::damage]); - item.Color = (uint32)atoul(row[ItemField::color]); - item.Classes = (uint32)atoul(row[ItemField::classes]); - item.Races = (uint32)atoul(row[ItemField::races]); - //item.Unk054 = (uint32)atoul(row[ItemField::UNK054]); - item.MaxCharges = (int16)atoi(row[ItemField::maxcharges]); - item.ItemType = (uint8)atoi(row[ItemField::itemtype]); - item.Material = (uint8)atoi(row[ItemField::material]); - item.SellRate = (float)atof(row[ItemField::sellrate]); - //item.Unk059 = (uint32)atoul(row[ItemField::UNK059]); - item.CastTime = (uint32)atoul(row[ItemField::casttime]); - item.EliteMaterial = (uint32)atoul(row[ItemField::elitematerial]); - item.ProcRate = (int32)atoi(row[ItemField::procrate]); - item.CombatEffects = (int8)atoi(row[ItemField::combateffects]); - item.Shielding = (int8)atoi(row[ItemField::shielding]); - item.StunResist = (int8)atoi(row[ItemField::stunresist]); - item.StrikeThrough = (int8)atoi(row[ItemField::strikethrough]); - item.ExtraDmgSkill = (uint32)atoul(row[ItemField::extradmgskill]); - item.ExtraDmgAmt = (uint32)atoul(row[ItemField::extradmgamt]); - item.SpellShield = (int8)atoi(row[ItemField::spellshield]); - item.Avoidance = (int8)atoi(row[ItemField::avoidance]); - item.Accuracy = (int8)atoi(row[ItemField::accuracy]); - item.CharmFileID = (uint32)atoul(row[ItemField::charmfileid]); - item.FactionMod1 = (int32)atoul(row[ItemField::factionmod1]); - item.FactionMod2 = (int32)atoul(row[ItemField::factionmod2]); - item.FactionMod3 = (int32)atoul(row[ItemField::factionmod3]); - item.FactionMod4 = (int32)atoul(row[ItemField::factionmod4]); - item.FactionAmt1 = (int32)atoul(row[ItemField::factionamt1]); - item.FactionAmt2 = (int32)atoul(row[ItemField::factionamt2]); - item.FactionAmt3 = (int32)atoul(row[ItemField::factionamt3]); - item.FactionAmt4 = (int32)atoul(row[ItemField::factionamt4]); - strcpy(item.CharmFile,row[ItemField::charmfile]); - item.AugType = (uint32)atoul(row[ItemField::augtype]); - item.AugSlotType[0] = (uint8)atoi(row[ItemField::augslot1type]); - item.AugSlotVisible[0] = (uint8)atoi(row[ItemField::augslot1visible]); - item.AugSlotUnk2[0] = 0; - item.AugSlotType[1] = (uint8)atoi(row[ItemField::augslot2type]); - item.AugSlotVisible[1] = (uint8)atoi(row[ItemField::augslot2visible]); - item.AugSlotUnk2[1] = 0; - item.AugSlotType[2] = (uint8)atoi(row[ItemField::augslot3type]); - item.AugSlotVisible[2] = (uint8)atoi(row[ItemField::augslot3visible]); - item.AugSlotUnk2[2] = 0; - item.AugSlotType[3] = (uint8)atoi(row[ItemField::augslot4type]); - item.AugSlotVisible[3] = (uint8)atoi(row[ItemField::augslot4visible]); - item.AugSlotUnk2[3] = 0; - item.AugSlotType[4] = (uint8)atoi(row[ItemField::augslot5type]); - item.AugSlotVisible[4] = (uint8)atoi(row[ItemField::augslot5visible]); - item.AugSlotUnk2[4] = 0; - item.LDoNTheme = (uint32)atoul(row[ItemField::ldontheme]); - item.LDoNPrice = (uint32)atoul(row[ItemField::ldonprice]); - item.LDoNSold = (uint32)atoul(row[ItemField::ldonsold]); - item.BagType = (uint8)atoi(row[ItemField::bagtype]); - item.BagSlots = (uint8)atoi(row[ItemField::bagslots]); - item.BagSize = (uint8)atoi(row[ItemField::bagsize]); - item.BagWR = (uint8)atoi(row[ItemField::bagwr]); - item.Book = (uint8)atoi(row[ItemField::book]); - item.BookType = (uint32)atoul(row[ItemField::booktype]); - strcpy(item.Filename,row[ItemField::filename]); - item.BaneDmgRaceAmt = (uint32)atoul(row[ItemField::banedmgraceamt]); - item.AugRestrict = (uint32)atoul(row[ItemField::augrestrict]); - item.LoreGroup = disableLoreGroup ? (uint8)atoi("0") : atoi(row[ItemField::loregroup]); - item.LoreFlag = item.LoreGroup!=0; - item.PendingLoreFlag = (atoi(row[ItemField::pendingloreflag])==0) ? false : true; - item.ArtifactFlag = (atoi(row[ItemField::artifactflag])==0) ? false : true; - item.SummonedFlag = (atoi(row[ItemField::summonedflag])==0) ? false : true; - item.Favor = (uint32)atoul(row[ItemField::favor]); - item.FVNoDrop = (atoi(row[ItemField::fvnodrop])==0) ? false : true; - item.Endur = (uint32)atoul(row[ItemField::endur]); - item.DotShielding = (uint32)atoul(row[ItemField::dotshielding]); - item.Attack = (uint32)atoul(row[ItemField::attack]); - item.Regen = (uint32)atoul(row[ItemField::regen]); - item.ManaRegen = (uint32)atoul(row[ItemField::manaregen]); - item.EnduranceRegen = (uint32)atoul(row[ItemField::enduranceregen]); - item.Haste = (uint32)atoul(row[ItemField::haste]); - item.DamageShield = (uint32)atoul(row[ItemField::damageshield]); - item.RecastDelay = (uint32)atoul(row[ItemField::recastdelay]); - item.RecastType = (uint32)atoul(row[ItemField::recasttype]); - item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]); - item.AugDistiller = (uint32)atoul(row[ItemField::augdistiller]); - //item.Unk123 = (uint32)atoul(row[ItemField::UNK123]); - //item.Unk124 = (uint32)atoul(row[ItemField::UNK124]); - item.Attuneable = (atoi(row[ItemField::attuneable])==0) ? false : true; - item.NoPet = (atoi(row[ItemField::nopet])==0) ? false : true; - //item.Unk127 = (uint32)atoul(row[ItemField::UNK127]); - item.PointType = (uint32)atoul(row[ItemField::pointtype]); - item.PotionBelt = (atoi(row[ItemField::potionbelt])==0) ? false : true; - item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots])==0) ? false : true; - item.StackSize = (uint16)atoi(row[ItemField::stacksize]); + item.NoDrop = disableNoDrop ? (uint8)atoi("255") : (uint8)atoi(row[ItemField::nodrop]); + item.Size = (uint8)atoi(row[ItemField::size]); + item.Slots = (uint32)atoul(row[ItemField::slots]); + item.Price = (uint32)atoul(row[ItemField::price]); + item.Icon = (uint32)atoul(row[ItemField::icon]); + item.BenefitFlag = (atoul(row[ItemField::benefitflag]) != 0); + item.Tradeskills = (atoi(row[ItemField::tradeskills])==0) ? false : true; + item.CR = (int8)atoi(row[ItemField::cr]); + item.DR = (int8)atoi(row[ItemField::dr]); + item.PR = (int8)atoi(row[ItemField::pr]); + item.MR = (int8)atoi(row[ItemField::mr]); + item.FR = (int8)atoi(row[ItemField::fr]); + item.AStr = (int8)atoi(row[ItemField::astr]); + item.ASta = (int8)atoi(row[ItemField::asta]); + item.AAgi = (int8)atoi(row[ItemField::aagi]); + item.ADex = (int8)atoi(row[ItemField::adex]); + item.ACha = (int8)atoi(row[ItemField::acha]); + item.AInt = (int8)atoi(row[ItemField::aint]); + item.AWis = (int8)atoi(row[ItemField::awis]); + item.HP = (int32)atoul(row[ItemField::hp]); + item.Mana = (int32)atoul(row[ItemField::mana]); + item.AC = (int32)atoul(row[ItemField::ac]); + item.Deity = (uint32)atoul(row[ItemField::deity]); + item.SkillModValue = (int32)atoul(row[ItemField::skillmodvalue]); + //item.Unk033 = (int32)atoul(row[ItemField::UNK033]); + item.SkillModType = (uint32)atoul(row[ItemField::skillmodtype]); + item.BaneDmgRace = (uint32)atoul(row[ItemField::banedmgrace]); + item.BaneDmgAmt = (int8)atoi(row[ItemField::banedmgamt]); + item.BaneDmgBody = (uint32)atoul(row[ItemField::banedmgbody]); + item.Magic = (atoi(row[ItemField::magic])==0) ? false : true; + item.CastTime_ = (int32)atoul(row[ItemField::casttime_]); + item.ReqLevel = (uint8)atoi(row[ItemField::reqlevel]); + item.BardType = (uint32)atoul(row[ItemField::bardtype]); + item.BardValue = (int32)atoul(row[ItemField::bardvalue]); + item.Light = (int8)atoi(row[ItemField::light]); + item.Delay = (uint8)atoi(row[ItemField::delay]); + item.RecLevel = (uint8)atoi(row[ItemField::reclevel]); + item.RecSkill = (uint8)atoi(row[ItemField::recskill]); + item.ElemDmgType = (uint8)atoi(row[ItemField::elemdmgtype]); + item.ElemDmgAmt = (uint8)atoi(row[ItemField::elemdmgamt]); + item.Range = (uint8)atoi(row[ItemField::range]); + item.Damage = (uint32)atoi(row[ItemField::damage]); + item.Color = (uint32)atoul(row[ItemField::color]); + item.Classes = (uint32)atoul(row[ItemField::classes]); + item.Races = (uint32)atoul(row[ItemField::races]); + //item.Unk054 = (uint32)atoul(row[ItemField::UNK054]); + item.MaxCharges = (int16)atoi(row[ItemField::maxcharges]); + item.ItemType = (uint8)atoi(row[ItemField::itemtype]); + item.Material = (uint8)atoi(row[ItemField::material]); + item.SellRate = (float)atof(row[ItemField::sellrate]); + //item.Unk059 = (uint32)atoul(row[ItemField::UNK059]); + item.CastTime = (uint32)atoul(row[ItemField::casttime]); + item.EliteMaterial = (uint32)atoul(row[ItemField::elitematerial]); + item.ProcRate = (int32)atoi(row[ItemField::procrate]); + item.CombatEffects = (int8)atoi(row[ItemField::combateffects]); + item.Shielding = (int8)atoi(row[ItemField::shielding]); + item.StunResist = (int8)atoi(row[ItemField::stunresist]); + item.StrikeThrough = (int8)atoi(row[ItemField::strikethrough]); + item.ExtraDmgSkill = (uint32)atoul(row[ItemField::extradmgskill]); + item.ExtraDmgAmt = (uint32)atoul(row[ItemField::extradmgamt]); + item.SpellShield = (int8)atoi(row[ItemField::spellshield]); + item.Avoidance = (int8)atoi(row[ItemField::avoidance]); + item.Accuracy = (int8)atoi(row[ItemField::accuracy]); + item.CharmFileID = (uint32)atoul(row[ItemField::charmfileid]); + item.FactionMod1 = (int32)atoul(row[ItemField::factionmod1]); + item.FactionMod2 = (int32)atoul(row[ItemField::factionmod2]); + item.FactionMod3 = (int32)atoul(row[ItemField::factionmod3]); + item.FactionMod4 = (int32)atoul(row[ItemField::factionmod4]); + item.FactionAmt1 = (int32)atoul(row[ItemField::factionamt1]); + item.FactionAmt2 = (int32)atoul(row[ItemField::factionamt2]); + item.FactionAmt3 = (int32)atoul(row[ItemField::factionamt3]); + item.FactionAmt4 = (int32)atoul(row[ItemField::factionamt4]); + strcpy(item.CharmFile,row[ItemField::charmfile]); + item.AugType = (uint32)atoul(row[ItemField::augtype]); + item.AugSlotType[0] = (uint8)atoi(row[ItemField::augslot1type]); + item.AugSlotVisible[0] = (uint8)atoi(row[ItemField::augslot1visible]); + item.AugSlotUnk2[0] = 0; + item.AugSlotType[1] = (uint8)atoi(row[ItemField::augslot2type]); + item.AugSlotVisible[1] = (uint8)atoi(row[ItemField::augslot2visible]); + item.AugSlotUnk2[1] = 0; + item.AugSlotType[2] = (uint8)atoi(row[ItemField::augslot3type]); + item.AugSlotVisible[2] = (uint8)atoi(row[ItemField::augslot3visible]); + item.AugSlotUnk2[2] = 0; + item.AugSlotType[3] = (uint8)atoi(row[ItemField::augslot4type]); + item.AugSlotVisible[3] = (uint8)atoi(row[ItemField::augslot4visible]); + item.AugSlotUnk2[3] = 0; + item.AugSlotType[4] = (uint8)atoi(row[ItemField::augslot5type]); + item.AugSlotVisible[4] = (uint8)atoi(row[ItemField::augslot5visible]); + item.AugSlotUnk2[4] = 0; + item.LDoNTheme = (uint32)atoul(row[ItemField::ldontheme]); + item.LDoNPrice = (uint32)atoul(row[ItemField::ldonprice]); + item.LDoNSold = (uint32)atoul(row[ItemField::ldonsold]); + item.BagType = (uint8)atoi(row[ItemField::bagtype]); + item.BagSlots = (uint8)atoi(row[ItemField::bagslots]); + item.BagSize = (uint8)atoi(row[ItemField::bagsize]); + item.BagWR = (uint8)atoi(row[ItemField::bagwr]); + item.Book = (uint8)atoi(row[ItemField::book]); + item.BookType = (uint32)atoul(row[ItemField::booktype]); + strcpy(item.Filename,row[ItemField::filename]); + item.BaneDmgRaceAmt = (uint32)atoul(row[ItemField::banedmgraceamt]); + item.AugRestrict = (uint32)atoul(row[ItemField::augrestrict]); + item.LoreGroup = disableLoreGroup ? (uint8)atoi("0") : atoi(row[ItemField::loregroup]); + item.LoreFlag = item.LoreGroup!=0; + item.PendingLoreFlag = (atoi(row[ItemField::pendingloreflag])==0) ? false : true; + item.ArtifactFlag = (atoi(row[ItemField::artifactflag])==0) ? false : true; + item.SummonedFlag = (atoi(row[ItemField::summonedflag])==0) ? false : true; + item.Favor = (uint32)atoul(row[ItemField::favor]); + item.FVNoDrop = (atoi(row[ItemField::fvnodrop])==0) ? false : true; + item.Endur = (uint32)atoul(row[ItemField::endur]); + item.DotShielding = (uint32)atoul(row[ItemField::dotshielding]); + item.Attack = (uint32)atoul(row[ItemField::attack]); + item.Regen = (uint32)atoul(row[ItemField::regen]); + item.ManaRegen = (uint32)atoul(row[ItemField::manaregen]); + item.EnduranceRegen = (uint32)atoul(row[ItemField::enduranceregen]); + item.Haste = (uint32)atoul(row[ItemField::haste]); + item.DamageShield = (uint32)atoul(row[ItemField::damageshield]); + item.RecastDelay = (uint32)atoul(row[ItemField::recastdelay]); + item.RecastType = (uint32)atoul(row[ItemField::recasttype]); + item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]); + item.AugDistiller = (uint32)atoul(row[ItemField::augdistiller]); + item.Attuneable = (atoi(row[ItemField::attuneable])==0) ? false : true; + item.NoPet = (atoi(row[ItemField::nopet])==0) ? false : true; + item.PointType = (uint32)atoul(row[ItemField::pointtype]); + item.PotionBelt = (atoi(row[ItemField::potionbelt])==0) ? false : true; + item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots])==0) ? false : true; + item.StackSize = (uint16)atoi(row[ItemField::stacksize]); item.NoTransfer = disableNoTransfer ? false : (atoi(row[ItemField::notransfer])==0) ? false : true; - item.Stackable = (atoi(row[ItemField::stackable])==0) ? false : true; - //item.Unk134 = (uint32)atoul(row[ItemField::UNK134]); - item.Click.Effect = (uint32)atoul(row[ItemField::clickeffect]); - item.Click.Type = (uint8)atoul(row[ItemField::clicktype]); - item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]); - item.Click.Level2 = (uint8)atoul(row[ItemField::clicklevel2]); - strcpy(item.CharmFile,row[ItemField::charmfile]); - item.Proc.Effect = (uint16)atoul(row[ItemField::proceffect]); - item.Proc.Type = (uint8)atoul(row[ItemField::proctype]); - item.Proc.Level = (uint8)atoul(row[ItemField::proclevel]); - item.Proc.Level2 = (uint8)atoul(row[ItemField::proclevel2]); - item.Worn.Effect = (uint16)atoul(row[ItemField::worneffect]); - item.Worn.Type = (uint8)atoul(row[ItemField::worntype]); - item.Worn.Level = (uint8)atoul(row[ItemField::wornlevel]); - item.Worn.Level2 = (uint8)atoul(row[ItemField::wornlevel2]); - item.Focus.Effect = (uint16)atoul(row[ItemField::focuseffect]); - item.Focus.Type = (uint8)atoul(row[ItemField::focustype]); - item.Focus.Level = (uint8)atoul(row[ItemField::focuslevel]); - item.Focus.Level2 = (uint8)atoul(row[ItemField::focuslevel2]); - item.Scroll.Effect = (uint16)atoul(row[ItemField::scrolleffect]); - item.Scroll.Type = (uint8)atoul(row[ItemField::scrolltype]); - item.Scroll.Level = (uint8)atoul(row[ItemField::scrolllevel]); - item.Scroll.Level2 = (uint8)atoul(row[ItemField::scrolllevel2]); - item.Bard.Effect = (uint16)atoul(row[ItemField::bardeffect]); - item.Bard.Type = (uint8)atoul(row[ItemField::bardtype]); - item.Bard.Level = (uint8)atoul(row[ItemField::bardlevel]); - item.Bard.Level2 = (uint8)atoul(row[ItemField::bardlevel2]); - item.QuestItemFlag = (atoi(row[ItemField::questitemflag])==0) ? false : true; - item.SVCorruption = (int32)atoi(row[ItemField::svcorruption]); - item.Purity = (uint32)atoul(row[ItemField::purity]); - item.BackstabDmg = (uint32)atoul(row[ItemField::backstabdmg]); - item.DSMitigation = (uint32)atoul(row[ItemField::dsmitigation]); - item.HeroicStr = (int32)atoi(row[ItemField::heroic_str]); - item.HeroicInt = (int32)atoi(row[ItemField::heroic_int]); - item.HeroicWis = (int32)atoi(row[ItemField::heroic_wis]); - item.HeroicAgi = (int32)atoi(row[ItemField::heroic_agi]); - item.HeroicDex = (int32)atoi(row[ItemField::heroic_dex]); - item.HeroicSta = (int32)atoi(row[ItemField::heroic_sta]); - item.HeroicCha = (int32)atoi(row[ItemField::heroic_cha]); - item.HeroicMR = (int32)atoi(row[ItemField::heroic_mr]); - item.HeroicFR = (int32)atoi(row[ItemField::heroic_fr]); - item.HeroicCR = (int32)atoi(row[ItemField::heroic_cr]); - item.HeroicDR = (int32)atoi(row[ItemField::heroic_dr]); - item.HeroicPR = (int32)atoi(row[ItemField::heroic_pr]); - item.HeroicSVCorrup = (int32)atoi(row[ItemField::heroic_svcorrup]); - item.HealAmt = (int32)atoi(row[ItemField::healamt]); - item.SpellDmg = (int32)atoi(row[ItemField::spelldmg]); - item.LDoNSellBackRate = (uint32)atoul(row[ItemField::ldonsellbackrate]); - item.ScriptFileID = (uint32)atoul(row[ItemField::scriptfileid]); - item.ExpendableArrow = (uint16)atoul(row[ItemField::expendablearrow]); - item.Clairvoyance = (uint32)atoul(row[ItemField::clairvoyance]); - strcpy(item.ClickName,row[ItemField::clickname]); - strcpy(item.ProcName,row[ItemField::procname]); - strcpy(item.WornName,row[ItemField::wornname]); - strcpy(item.FocusName,row[ItemField::focusname]); - strcpy(item.ScrollName,row[ItemField::scrollname]); + item.Stackable = (atoi(row[ItemField::stackable])==0) ? false : true; + item.Click.Effect = (uint32)atoul(row[ItemField::clickeffect]); + item.Click.Type = (uint8)atoul(row[ItemField::clicktype]); + item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]); + item.Click.Level2 = (uint8)atoul(row[ItemField::clicklevel2]); + strcpy(item.CharmFile,row[ItemField::charmfile]); + item.Proc.Effect = (uint16)atoul(row[ItemField::proceffect]); + item.Proc.Type = (uint8)atoul(row[ItemField::proctype]); + item.Proc.Level = (uint8)atoul(row[ItemField::proclevel]); + item.Proc.Level2 = (uint8)atoul(row[ItemField::proclevel2]); + item.Worn.Effect = (uint16)atoul(row[ItemField::worneffect]); + item.Worn.Type = (uint8)atoul(row[ItemField::worntype]); + item.Worn.Level = (uint8)atoul(row[ItemField::wornlevel]); + item.Worn.Level2 = (uint8)atoul(row[ItemField::wornlevel2]); + item.Focus.Effect = (uint16)atoul(row[ItemField::focuseffect]); + item.Focus.Type = (uint8)atoul(row[ItemField::focustype]); + item.Focus.Level = (uint8)atoul(row[ItemField::focuslevel]); + item.Focus.Level2 = (uint8)atoul(row[ItemField::focuslevel2]); + item.Scroll.Effect = (uint16)atoul(row[ItemField::scrolleffect]); + item.Scroll.Type = (uint8)atoul(row[ItemField::scrolltype]); + item.Scroll.Level = (uint8)atoul(row[ItemField::scrolllevel]); + item.Scroll.Level2 = (uint8)atoul(row[ItemField::scrolllevel2]); + item.Bard.Effect = (uint16)atoul(row[ItemField::bardeffect]); + item.Bard.Type = (uint8)atoul(row[ItemField::bardtype]); + item.Bard.Level = (uint8)atoul(row[ItemField::bardlevel]); + item.Bard.Level2 = (uint8)atoul(row[ItemField::bardlevel2]); + item.QuestItemFlag = (atoi(row[ItemField::questitemflag])==0) ? false : true; + item.SVCorruption = (int32)atoi(row[ItemField::svcorruption]); + item.Purity = (uint32)atoul(row[ItemField::purity]); + item.BackstabDmg = (uint32)atoul(row[ItemField::backstabdmg]); + item.DSMitigation = (uint32)atoul(row[ItemField::dsmitigation]); + item.HeroicStr = (int32)atoi(row[ItemField::heroic_str]); + item.HeroicInt = (int32)atoi(row[ItemField::heroic_int]); + item.HeroicWis = (int32)atoi(row[ItemField::heroic_wis]); + item.HeroicAgi = (int32)atoi(row[ItemField::heroic_agi]); + item.HeroicDex = (int32)atoi(row[ItemField::heroic_dex]); + item.HeroicSta = (int32)atoi(row[ItemField::heroic_sta]); + item.HeroicCha = (int32)atoi(row[ItemField::heroic_cha]); + item.HeroicMR = (int32)atoi(row[ItemField::heroic_mr]); + item.HeroicFR = (int32)atoi(row[ItemField::heroic_fr]); + item.HeroicCR = (int32)atoi(row[ItemField::heroic_cr]); + item.HeroicDR = (int32)atoi(row[ItemField::heroic_dr]); + item.HeroicPR = (int32)atoi(row[ItemField::heroic_pr]); + item.HeroicSVCorrup = (int32)atoi(row[ItemField::heroic_svcorrup]); + item.HealAmt = (int32)atoi(row[ItemField::healamt]); + item.SpellDmg = (int32)atoi(row[ItemField::spelldmg]); + item.LDoNSellBackRate = (uint32)atoul(row[ItemField::ldonsellbackrate]); + item.ScriptFileID = (uint32)atoul(row[ItemField::scriptfileid]); + item.ExpendableArrow = (uint16)atoul(row[ItemField::expendablearrow]); + item.Clairvoyance = (uint32)atoul(row[ItemField::clairvoyance]); + strcpy(item.ClickName,row[ItemField::clickname]); + strcpy(item.ProcName,row[ItemField::procname]); + strcpy(item.WornName,row[ItemField::wornname]); + strcpy(item.FocusName,row[ItemField::focusname]); + strcpy(item.ScrollName,row[ItemField::scrollname]); - if (!EMuShareMemDLL.Items.cbAddItem(item.ID, &item)) { - LogFile->write(EQEMuLog::Error, "Database::DBLoadItems: Failure reported from EMuShareMemDLL.Items.cbAddItem(%i)", item.ID); - break; - } + try { + hash.insert(item.ID, item); + } catch(std::exception &ex) { + LogFile->write(EQEMuLog::Error, "Database::LoadItems: %s", ex.what()); + break; + } } mysql_free_result(result); - ret = true; } else { - LogFile->write(EQEMuLog::Error, "DBLoadItems query '%s', %s", query, errbuf); - LogFile->write(EQEMuLog::Error, "If you got boat loads of errors, make sure you sourced all sql updates!\n"); + LogFile->write(EQEMuLog::Error, "LoadItems '%s', %s", query, errbuf); } - return ret; } - const Item_Struct* SharedDatabase::GetItem(uint32 id) { - return EMuShareMemDLL.Items.GetItem(id); + if(!items_hash || id > items_hash->max_key()) { + return NULL; + } + + if(items_hash->exists(id)) { + return &(items_hash->at(id)); + } + + return NULL; } -const Item_Struct* SharedDatabase::IterateItems(uint32* NextIndex) { - return EMuShareMemDLL.Items.IterateItems(NextIndex); -} +const Item_Struct* SharedDatabase::IterateItems(uint32* id) { + if(!items_hash || !id) { + return NULL; + } + for(;;) { + if(*id > items_hash->max_key()) { + break; + } + + if(items_hash->exists(*id)) { + return &(items_hash->at((*id)++)); + } else { + ++(*id); + } + } + + return NULL; +} string SharedDatabase::GetBook(const char *txtfile) { @@ -1595,6 +1602,10 @@ uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillType Skill, uint8 Level) { uint32 class_count = PLAYER_CLASS_COUNT; uint32 skill_count = HIGHEST_SKILL + 1; uint32 level_count = HARD_LEVEL_CAP + 1; + if(Class_ > class_count || Skill > skill_count || Level > level_count) { + return 0; + } + if(Level > static_cast(SkillMaxLevel)){ Level = static_cast(SkillMaxLevel); } @@ -1620,8 +1631,11 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level) uint32 class_count = PLAYER_CLASS_COUNT; uint32 skill_count = HIGHEST_SKILL + 1; uint32 level_count = HARD_LEVEL_CAP + 1; + if(Class_ > class_count || Skill > skill_count || Level > level_count) { + return 0; + } + uint8 ret = 0; - if(Level > static_cast(SkillMaxLevel)) { uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count); uint16 *skill_caps_table = reinterpret_cast(skill_caps_mmf->Get()); diff --git a/common/shareddb.h b/common/shareddb.h index 80b412715..3a6873f0f 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -81,29 +81,32 @@ public: inline const uint32 GetMaxLootDropID() { return lootdrop_max; } inline const uint32 GetMaxNPCType() { return max_npc_type; } inline const uint32 GetMaxNPCFactionList() { return npcfactionlist_max; } - const Item_Struct* GetItem(uint32 id); const EvolveInfo* GetEvolveInfo(uint32 loregroup); const NPCFactionList* GetNPCFactionEntry(uint32 id); - uint16 GetSkillCap(uint8 Class_, SkillType Skill, uint8 Level); - uint8 GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level); const LootTable_Struct* GetLootTable(uint32 loottable_id); const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id); - bool LoadItems(); bool LoadLoot(); bool LoadNPCFactionLists(); bool GetCommandSettings(map &commands); - const Item_Struct* IterateItems(uint32* NextIndex); bool DBLoadItems(int32 iItemCount, uint32 iMaxItemID); bool DBLoadNPCTypes(int32 iNPCTypeCount, uint32 iMaxNPCTypeID); bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID); bool DBLoadLoot(); - int GetMaxSpellID(); - void LoadSpells(void *data, int max_spells); - void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID); + int32 GetItemsCount(uint32* max_id = 0); + void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id); + bool LoadItems(); + const Item_Struct* IterateItems(uint32* id); + const Item_Struct* GetItem(uint32 id); void LoadSkillCaps(void *data); bool LoadSkillCaps(); + uint16 GetSkillCap(uint8 Class_, SkillType Skill, uint8 Level); + uint8 GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level); + + int GetMaxSpellID(); + void LoadSpells(void *data, int max_spells); + void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID); protected: void SDBInitVars(); @@ -111,10 +114,8 @@ protected: /* * Private shared mem stuff */ - int32 GetItemsCount(uint32* oMaxID = 0); int32 GetNPCTypesCount(uint32* oMaxID = 0); int32 GetNPCFactionListsCount(uint32* oMaxID = 0); - static bool extDBLoadItems(int32 iItemCount, uint32 iMaxItemID); static bool extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID); static bool extDBLoadLoot(); diff --git a/shared_memory/CMakeLists.txt b/shared_memory/CMakeLists.txt index 4b4442d74..954419cc0 100644 --- a/shared_memory/CMakeLists.txt +++ b/shared_memory/CMakeLists.txt @@ -1,12 +1,14 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(shared_memory_sources + items.cpp main.cpp spells.cpp skill_caps.cpp ) SET(shared_memory_headers + items.h spells.h skill_caps.h ) diff --git a/shared_memory/items.cpp b/shared_memory/items.cpp new file mode 100644 index 000000000..2a96f8188 --- /dev/null +++ b/shared_memory/items.cpp @@ -0,0 +1,49 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "items.h" +#include "../common/debug.h" +#include "../common/shareddb.h" +#include "../common/ipc_mutex.h" +#include "../common/memory_mapped_file.h" +#include "../common/eqemu_exception.h" +#include "../common/spdat.h" +#include "../common/classes.h" +#include "../common/features.h" +#include "../common/item_struct.h" + +void LoadItems(SharedDatabase *database) { + EQEmu::IPCMutex mutex("items"); + mutex.Lock(); + + uint32 max_item = 0; + int32 items = database->GetItemsCount(&max_item); + if(items == -1) { + EQ_EXCEPT("Shared Memory", "Unable to get any items from the database."); + } + + uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); + EQEmu::MemoryMappedFile mmf("shared/items", size); + mmf.ZeroFile(); + + void *ptr = mmf.Get(); + database->LoadItems(ptr, size, items, max_item); + mmf.SetLoaded(); + + mutex.Unlock(); +} diff --git a/shared_memory/items.h b/shared_memory/items.h new file mode 100644 index 000000000..6ef0f7f2a --- /dev/null +++ b/shared_memory/items.h @@ -0,0 +1,25 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __EQEMU_SHARED_MEMORY_ITEMS_H +#define __EQEMU_SHARED_MEMORY_ITEMS_H + +class SharedDatabase; +void LoadItems(SharedDatabase *database); + +#endif diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 00aeb3a8c..17d67da8e 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -24,8 +24,9 @@ #include "../common/crash.h" #include "../common/rulesys.h" #include "../common/eqemu_exception.h" -#include "spells.h" +#include "items.h" #include "skill_caps.h" +#include "spells.h" int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformSharedMemory); @@ -52,8 +53,19 @@ int main(int argc, char **argv) { } bool load_all = true; + bool load_items = true; bool load_skill_caps = true; bool load_spells = true; + if(load_all || load_items) { + LogFile->write(EQEMuLog::Status, "Loading items..."); + try { + LoadItems(&database); + } catch(std::exception &ex) { + LogFile->write(EQEMuLog::Error, "%s", ex.what()); + return 0; + } + } + if(load_all || load_skill_caps) { LogFile->write(EQEMuLog::Status, "Loading skill caps..."); try { diff --git a/tests/fixed_memory_test.h b/tests/fixed_memory_test.h index 0e9b49962..30bb9e175 100644 --- a/tests/fixed_memory_test.h +++ b/tests/fixed_memory_test.h @@ -38,6 +38,10 @@ public: TEST_ADD(FixedMemoryHashTest::OverwriteRetrieveTest); TEST_ADD(FixedMemoryHashTest::InsertAgainTest); TEST_ADD(FixedMemoryHashTest::RetrieveAgainTest); + TEST_ADD(FixedMemoryHashTest::InsertBeginTest); + TEST_ADD(FixedMemoryHashTest::RetrieveBeginTest); + TEST_ADD(FixedMemoryHashTest::InsertEndTest); + TEST_ADD(FixedMemoryHashTest::RetrieveEndTest); } ~FixedMemoryHashTest() { delete[] data_; @@ -142,6 +146,88 @@ public: TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0); TEST_ASSERT(item.ID == 1001); } + + void InsertBeginTest() { + EQEmu::FixedMemoryHashSet hash(data_, size_); + Item_Struct item; + memset(&item, 0, sizeof(item)); + strcpy(item.Name, "Bronze Sword"); + item.ID = 0; + hash.insert(0, item); + + TEST_ASSERT(hash.exists(1000)); + TEST_ASSERT(hash.exists(1001)); + TEST_ASSERT(hash.exists(0)); + TEST_ASSERT(hash.size() == 3); + TEST_ASSERT(hash.max_size() == 72000); + TEST_ASSERT(!hash.empty()); + } + + void RetrieveBeginTest() { + EQEmu::FixedMemoryHashSet hash(data_, size_); + TEST_ASSERT(hash.exists(1000)); + TEST_ASSERT(hash.exists(1001)); + TEST_ASSERT(hash.exists(0)); + TEST_ASSERT(hash.size() == 3); + TEST_ASSERT(hash.max_size() == 72000); + TEST_ASSERT(!hash.empty()); + + Item_Struct item = hash[1000]; + TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); + TEST_ASSERT(item.ID == 1000); + + item = hash[1001]; + TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0); + TEST_ASSERT(item.ID == 1001); + + item = hash[0]; + TEST_ASSERT(strcmp(item.Name, "Bronze Sword") == 0); + TEST_ASSERT(item.ID == 0); + } + + void InsertEndTest() { + EQEmu::FixedMemoryHashSet hash(data_, size_); + Item_Struct item; + memset(&item, 0, sizeof(item)); + strcpy(item.Name, "Jade Sword"); + item.ID = 190000; + hash.insert(190000, item); + + TEST_ASSERT(hash.exists(1000)); + TEST_ASSERT(hash.exists(1001)); + TEST_ASSERT(hash.exists(0)); + TEST_ASSERT(hash.exists(190000)); + TEST_ASSERT(hash.size() == 4); + TEST_ASSERT(hash.max_size() == 72000); + TEST_ASSERT(!hash.empty()); + } + + void RetrieveEndTest() { + EQEmu::FixedMemoryHashSet hash(data_, size_); + TEST_ASSERT(hash.exists(1000)); + TEST_ASSERT(hash.exists(1001)); + TEST_ASSERT(hash.exists(0)); + TEST_ASSERT(hash.exists(190000)); + TEST_ASSERT(hash.size() == 4); + TEST_ASSERT(hash.max_size() == 72000); + TEST_ASSERT(!hash.empty()); + + Item_Struct item = hash[1000]; + TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); + TEST_ASSERT(item.ID == 1000); + + item = hash[1001]; + TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0); + TEST_ASSERT(item.ID == 1001); + + item = hash[0]; + TEST_ASSERT(strcmp(item.Name, "Bronze Sword") == 0); + TEST_ASSERT(item.ID == 0); + + item = hash[190000]; + TEST_ASSERT(strcmp(item.Name, "Jade Sword") == 0); + TEST_ASSERT(item.ID == 190000); + } private: uint8 *data_; size_t size_; diff --git a/tests/main.cpp b/tests/main.cpp index feb687153..2031dc61d 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -42,23 +42,15 @@ int main() { try { - std::unique_ptr output(new Test::HtmlOutput); + std::ofstream outfile("test_output.txt"); + std::unique_ptr output(new Test::TextOutput(Test::TextOutput::Verbose, outfile)); Test::Suite tests; tests.add(std::auto_ptr(new MemoryMappedFileTest())); tests.add(std::auto_ptr(new IPCMutexTest())); tests.add(std::auto_ptr(new FixedMemoryHashTest())); tests.run(*output, true); - - std::ofstream outfile("tests.html"); - Test::HtmlOutput* const html = dynamic_cast(output.get()); - if(html) - html->generate(outfile, true, "EQEmuTests"); - - outfile.close(); } catch(...) { - getchar(); return -1; } - getchar(); return 0; } \ No newline at end of file diff --git a/zone/command.cpp b/zone/command.cpp index b0ade5d98..2379e531a 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -381,7 +381,6 @@ int command_init(void) { command_add("opcode","- opcode management",250,command_opcode) || command_add("logs","[status|normal|error|debug|quest|all] - Subscribe to a log type",250,command_logs) || command_add("nologs","[status|normal|error|debug|quest|all] - Unsubscribe to a log type",250,command_nologs) || - command_add("datarate","[rate] - Query/set datarate",100,command_datarate) || command_add("ban","[name] - Ban by character name",150,command_ban) || command_add("suspend","[name][days] - Suspend by character name and for specificed number of days",150,command_suspend) || command_add("ipban","[IP address] - Ban IP by character name",200,command_ipban) || @@ -6302,9 +6301,8 @@ void command_itemsearch(Client *c, const Seperator *sep) c->Message(0, "Item #%s not found", search_criteria); return; } -#ifdef SHAREMEM - int count=0; - //int iSearchLen = strlen(search_criteria)+1; + + int count = 0; char sName[64]; char sCriteria[255]; strn0cpy(sCriteria, search_criteria, sizeof(sCriteria)); @@ -6337,27 +6335,8 @@ void command_itemsearch(Client *c, const Seperator *sep) c->Message(0, "50 items shown...too many results."); else c->Message(0, "%i items found", count); -#endif - } -} -void command_datarate(Client *c, const Seperator *sep) -{ -// EQStream *eqs = c->Connection(); - - if (sep->arg[1][0] == 0) { - //c->Message(0, "Datarate: %1.1f", eqs->GetDataRate()); - //if (c->Admin() >= commandChangeDatarate) { - //c->Message(0, "Dataflow: %i", eqs->GetDataFlow()); - //c->Message(0, "Datahigh: %i", eqs->GetDataHigh()); - //} } - else if (sep->IsNumber(1) && atof(sep->arg[1]) > 0 && (c->Admin() >= commandChangeDatarate || atof(sep->arg[1]) <= 25)) { - //eqs->SetDataRate(atof(sep->arg[1])); - //c->Message(0, "Datarate: %1.1f", eqs->GetDataRate()); - } - else - c->Message(0, "Usage: #DataRate [new data rate in kb/sec, max 25]"); } void command_setaaxp(Client *c, const Seperator *sep) diff --git a/zone/command.h b/zone/command.h index 6341247f9..903b4d288 100644 --- a/zone/command.h +++ b/zone/command.h @@ -243,7 +243,6 @@ void command_summonitem(Client *c, const Seperator *sep); void command_giveitem(Client *c, const Seperator *sep); void command_givemoney(Client *c, const Seperator *sep); void command_itemsearch(Client *c, const Seperator *sep); -void command_datarate(Client *c, const Seperator *sep); void command_setaaxp(Client *c, const Seperator *sep); void command_setaapts(Client *c, const Seperator *sep); void command_setcrystals(Client *c, const Seperator *sep);