From 9eaa98675b2279d86d7ad3b63708b1fb5b603c74 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 22 Feb 2013 18:25:17 -0800 Subject: [PATCH] Shared Memory Loot works --- common/Item.cpp | 2 +- common/memory_mapped_file.cpp | 1 + common/shareddb.cpp | 487 +++++++++++++--------------------- common/shareddb.h | 38 +-- shared_memory/loot.cpp | 48 ++-- shared_memory/main.cpp | 8 +- 6 files changed, 236 insertions(+), 348 deletions(-) diff --git a/common/Item.cpp b/common/Item.cpp index db9317f76..c5779cae0 100644 --- a/common/Item.cpp +++ b/common/Item.cpp @@ -967,7 +967,7 @@ bool Inventory::CheckNoDrop(int16 slot_id) { if (!inst) return false; if (!inst->GetItem()->NoDrop) return true; if (inst->GetItem()->ItemClass == 1) { - for (uint16 i=0; i<10; i++) { + for (uint8 i = 0; i < 10; i++) { ItemInst* bagitem = GetItem(Inventory::CalcSlotId(slot_id, i)); if (bagitem && !bagitem->GetItem()->NoDrop) return true; } diff --git a/common/memory_mapped_file.cpp b/common/memory_mapped_file.cpp index b045c9422..0591bcaec 100644 --- a/common/memory_mapped_file.cpp +++ b/common/memory_mapped_file.cpp @@ -205,6 +205,7 @@ namespace EQEmu { void MemoryMappedFile::ZeroFile() { memset(reinterpret_cast(memory_), 0, sizeof(shared_memory_struct)); + memset(memory_->data, 0, size_); memory_->loaded = false; memory_->size = size_; } diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 5379daade..1bcde4bbc 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -21,13 +21,14 @@ using namespace std; extern LoadEMuShareMemDLL EMuShareMemDLL; SharedDatabase::SharedDatabase() -: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), faction_mmf(NULL), loot_mmf(NULL) +: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), faction_mmf(NULL), + loot_table_mmf(NULL), loot_drop_mmf(NULL), loot_table_hash(NULL), loot_drop_hash(NULL) { } SharedDatabase::SharedDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port) : Database(host, user, passwd, database, port), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), - faction_mmf(NULL), loot_mmf(NULL) + faction_mmf(NULL), loot_table_mmf(NULL), loot_drop_mmf(NULL), loot_table_hash(NULL), loot_drop_hash(NULL) { } @@ -36,7 +37,10 @@ SharedDatabase::~SharedDatabase() { safe_delete(items_mmf); safe_delete(items_hash); safe_delete(faction_mmf); - safe_delete(loot_mmf); + safe_delete(loot_table_mmf); + safe_delete(loot_drop_mmf); + safe_delete(loot_table_hash); + safe_delete(loot_drop_hash); } bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme) @@ -1088,21 +1092,23 @@ bool SharedDatabase::extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 } const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) { - return EMuShareMemDLL.NPCFactionList.GetNPCFactionList(id); + return NULL; + //return EMuShareMemDLL.NPCFactionList.GetNPCFactionList(id); } bool SharedDatabase::LoadNPCFactionLists() { - if (!EMuShareMemDLL.Load()) - return false; - int32 tmp = -1; - uint32 tmp_npcfactionlist_max; - tmp = GetNPCFactionListsCount(&tmp_npcfactionlist_max); - if (tmp < 0) { - cout << "Error: SharedDatabase::LoadNPCFactionLists-ShareMem: GetNPCFactionListsCount() returned < 0" << endl; - return false; - } - bool ret = EMuShareMemDLL.NPCFactionList.DLLLoadNPCFactionLists(&extDBLoadNPCFactionLists, sizeof(NPCFactionList), &tmp, &tmp_npcfactionlist_max, MAX_NPC_FACTIONS); - return ret; + //if (!EMuShareMemDLL.Load()) + // return false; + //int32 tmp = -1; + //uint32 tmp_npcfactionlist_max; + //tmp = GetNPCFactionListsCount(&tmp_npcfactionlist_max); + //if (tmp < 0) { + // cout << "Error: SharedDatabase::LoadNPCFactionLists-ShareMem: GetNPCFactionListsCount() returned < 0" << endl; + // return false; + //} + //bool ret = EMuShareMemDLL.NPCFactionList.DLLLoadNPCFactionLists(&extDBLoadNPCFactionLists, sizeof(NPCFactionList), &tmp, &tmp_npcfactionlist_max, MAX_NPC_FACTIONS); + //return ret; + return true; } bool SharedDatabase::DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID) { @@ -1552,7 +1558,7 @@ 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) { + if(Class_ > class_count || static_cast(Skill) > skill_count || Level > level_count) { return 0; } @@ -1581,7 +1587,7 @@ 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) { + if(Class_ > class_count || static_cast(Skill) > skill_count || Level > level_count) { return 0; } @@ -1609,7 +1615,7 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level) } if(ret > GetSkillCap(Class_, Skill, Level)) - ret = GetSkillCap(Class_, Skill, Level); + ret = static_cast(GetSkillCap(Class_, Skill, Level)); return ret; } @@ -1802,310 +1808,197 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { } } -bool SharedDatabase::LoadLoot() { - //char errbuf[MYSQL_ERRMSG_SIZE]; - //char *query = 0; - //MYSQL_RES *result; - //MYSQL_ROW row; - //uint32 tmpLootTableCount = 0; - //uint32 tmpLootTableEntriesCount = 0; - //uint32 tmpLootDropCount = 0; - //uint32 tmpLootDropEntriesCount = 0; - //if (RunQuery(query, MakeAnyLenString(&query, "SELECT max(id), count(*) FROM loottable"), errbuf, &result)) { - // safe_delete_array(query); - // if (mysql_num_rows(result) == 1) { - // row = mysql_fetch_row(result); - // if (row[0]) - // loottable_max = atoi(row[0]); - // else - // loottable_max = 0; - // tmpLootTableCount = atoi(row[1]); - // } - // else { - // mysql_free_result(result); - // return false; - // } - // mysql_free_result(result); - //} - //else { - // cerr << "Error in LoadLoot query, loottable part: '" << query << "' " << errbuf << endl; - // safe_delete_array(query); - // return false; - //} - //if (RunQuery(query, MakeAnyLenString(&query, "SELECT count(*) FROM loottable_entries"), errbuf, &result)) { - // safe_delete_array(query); - // if (mysql_num_rows(result) == 1) { - // row = mysql_fetch_row(result); - // tmpLootTableEntriesCount = atoi(row[0]); - // } - // else { - // mysql_free_result(result); - // return false; - // } - // mysql_free_result(result); - //} - //else { - // cerr << "Error in LoadLoot query, loottable2 part: '" << query << "' " << errbuf << endl; - // safe_delete_array(query); - // return false; - //} - // - //if (RunQuery(query, MakeAnyLenString(&query, "SELECT max(id), count(*) FROM lootdrop"), errbuf, &result)) { - // safe_delete_array(query); - // if (mysql_num_rows(result) == 1) { - // row = mysql_fetch_row(result); - // if (row[0]) - // lootdrop_max = atoi(row[0]); - // else - // lootdrop_max = 0; - // tmpLootDropCount = atoi(row[1]); - // } - // else { - // mysql_free_result(result); - // return false; - // } - // mysql_free_result(result); - //} - //else { - // cerr << "Error in LoadLoot query, lootdrop1 part: '" << query << "' " << errbuf << endl; - // safe_delete_array(query); - // return false; - //} - //if (RunQuery(query, MakeAnyLenString(&query, "SELECT max(lootdrop_id), count(*) FROM lootdrop_entries"), errbuf, &result)) { - // safe_delete_array(query); - // if (mysql_num_rows(result) == 1) { - // row = mysql_fetch_row(result); - // tmpLootDropEntriesCount = atoi(row[1]); - // } - // else { - // mysql_free_result(result); - // return false; - // } - // mysql_free_result(result); - //} - //else { - // cerr << "Error in LoadLoot query, lootdrop part: '" << query << "' " << errbuf << endl; - // safe_delete_array(query); - // return false; - //} - //return EMuShareMemDLL.Loot.DLLLoadLoot(&extDBLoadLoot, - // sizeof(LootTable_Struct), tmpLootTableCount, loottable_max, - // sizeof(LootTableEntries_Struct), tmpLootTableEntriesCount, - // sizeof(LootDrop_Struct), tmpLootDropCount, lootdrop_max, - // sizeof(LootDropEntries_Struct), tmpLootDropEntriesCount); - return false; -} - -void SharedDatabase::LoadLoot(void *ptr, uint32 loot_table_count, uint32 max_loot_table, uint32 loot_table_entries, - uint32 loot_drop_count, uint32 max_loot_drop, uint32 loot_drop_entries) -{ - uint8 *data = reinterpret_cast(ptr); - uint32 *loottable_max = reinterpret_cast(ptr); data += sizeof(uint32); - uint32 *lootdrop_max = reinterpret_cast(ptr); data += sizeof(uint32); - uint32 *lootdrop_offset = reinterpret_cast(ptr); data += sizeof(uint32); - uint32 *loottable_offset = reinterpret_cast(ptr); data += (sizeof(uint32) * (max_loot_table + 1)); - - *loottable_max = max_loot_table + 1; - *lootdrop_max = max_loot_drop + 1; - *loottable_offset = sizeof(uint32) * 3; - data += sizeof(uint32) * (*loottable_max + 1); - - uint32 *loottable_offsets = reinterpret_cast(reinterpret_cast(ptr) + (*loottable_offset)); - uint32 *lootdrop_offsets = NULL; - - const char *loottable_query = "SELECT * FROM loottable ORDER BY id"; - char errbuf[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; - if(RunQuery(loottable_query, strlen(loottable_query), errbuf, &result)) { - while(row = mysql_fetch_row(result)) { - LootTable_Struct *table = reinterpret_cast(data); data += sizeof(LootTable_Struct); - - } - mysql_free_result(result); - } -} - -void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries, - uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries) -{ +void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries) { loot_table_count = 0; max_loot_table = 0; loot_table_entries = 0; - loot_drop_count = 0; - max_loot_drop = 0; - loot_drop_entries = 0; - const char *count_query = "SELECT (SELECT COUNT(*) FROM loottable) as loot_table_count, " - "(SELECT COUNT(*) FROM lootdrop) as loot_drop_count"; - const char *max_query = "SELECT MAX(loottable.id) AS max_loot_table, MAX(lootdrop.id) as max_loot_drop" - " FROM loottable, lootdrop"; - const char *entries_count_query = "SELECT (SELECT COUNT(*) FROM loottable_entries) as loot_table_count, " - "(SELECT COUNT(*) FROM lootdrop_entries) as loot_drop_count"; + const char *query = "SELECT COUNT(*), MAX(id), (SELECT COUNT(*) FROM loottable_entries) FROM loottable"; char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; - if(RunQuery(count_query, strlen(count_query), errbuf, &result)) { + if(RunQuery(query, strlen(query), errbuf, &result)) { if(row = mysql_fetch_row(result)) { loot_table_count = static_cast(atoul(row[0])); - loot_drop_count = static_cast(atoul(row[1])); + max_loot_table = static_cast(atoul(row[1])); + loot_table_entries = static_cast(atoul(row[2])); } mysql_free_result(result); } else { - LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", max_query, errbuf); - return; - } - - if(RunQuery(max_query, strlen(max_query), errbuf, &result)) { - if(row = mysql_fetch_row(result)) { - max_loot_table = static_cast(atoul(row[0])); - max_loot_drop = static_cast(atoul(row[1])); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", max_query, errbuf); - return; - } - - if(RunQuery(entries_count_query, strlen(entries_count_query), errbuf, &result)) { - if(row = mysql_fetch_row(result)) { - loot_table_entries = static_cast(atoul(row[0])); - loot_drop_entries = static_cast(atoul(row[1])); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", entries_count_query, errbuf); - return; + LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query, errbuf); } } -bool SharedDatabase::DBLoadLoot() { - LogFile->write(EQEMuLog::Status, "Loading Loot tables from database..."); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; +void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries) { + loot_drop_count = 0; + max_loot_drop = 0; + loot_drop_entries = 0; + const char *query = "SELECT COUNT(*), MAX(id), (SELECT COUNT(*) FROM lootdrop_entries) FROM lootdrop"; + char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; - MYSQL_RES *result2; - uint32 i, tmpid = 0, tmpmincash = 0, tmpmaxcash = 0, tmpavgcoin = 0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, mincash, maxcash, avgcoin FROM loottable"), errbuf, &result)) { - safe_delete_array(query); - LootTable_Struct* tmpLT = 0; - while ((row = mysql_fetch_row(result))) { - tmpid = atoi(row[0]); - tmpmincash = atoi(row[1]); - tmpmaxcash = atoi(row[2]); - tmpavgcoin = atoi(row[3]); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT loottable_id, lootdrop_id, droplimit, mindrop, multiplier, probability FROM loottable_entries WHERE loottable_id=%i", tmpid), errbuf, &result2)) { - safe_delete_array(query); - tmpLT = (LootTable_Struct*) new uchar[sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * mysql_num_rows(result2))]; - memset(tmpLT, 0, sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * mysql_num_rows(result2))); - tmpLT->NumEntries = mysql_num_rows(result2); - tmpLT->mincash = tmpmincash; - tmpLT->maxcash = tmpmaxcash; - tmpLT->avgcoin = tmpavgcoin; - i=0; - while ((row = mysql_fetch_row(result2))) { - if (i >= tmpLT->NumEntries) { - mysql_free_result(result); - mysql_free_result(result2); - safe_delete_array(tmpLT); - cerr << "Error in ZoneDatabase::DBLoadLoot, i >= NumEntries" << endl; - return false; - } - tmpLT->Entries[i].lootdrop_id = atoi(row[1]); - tmpLT->Entries[i].droplimit = atoi(row[2]); - tmpLT->Entries[i].mindrop = atoi(row[3]); - tmpLT->Entries[i].multiplier = atoi(row[4]); - tmpLT->Entries[i].probability = atof(row[5]); - i++; - } - if (!EMuShareMemDLL.Loot.cbAddLootTable(tmpid, tmpLT)) { - mysql_free_result(result); - mysql_free_result(result2); - safe_delete_array(tmpLT); - cout << "Error in ZoneDatabase::DBLoadLoot: !cbAddLootTable(" << tmpid << ")" << endl; - return false; - } - safe_delete_array(tmpLT); - mysql_free_result(result2); - } - else { - mysql_free_result(result); - cerr << "Error in LoadLoot (memshare) #1 query '" << query << "' " << errbuf << endl; - safe_delete_array(query); - return false; - } - } - mysql_free_result(result); - } - else { - cerr << "Error in LoadLoot (memshare) #2 query '" << query << "' " << errbuf << endl; - safe_delete_array(query); - return false; - } - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM lootdrop", tmpid), errbuf, &result)) { - safe_delete_array(query); - LootDrop_Struct* tmpLD = 0; - while ((row = mysql_fetch_row(result))) { - tmpid = atoi(row[0]); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT lootdrop_id, item_id, item_charges, equip_item, chance, minlevel, maxlevel, multiplier FROM lootdrop_entries WHERE lootdrop_id=%i order by chance desc", tmpid), errbuf, &result2)) { - safe_delete_array(query); - tmpLD = (LootDrop_Struct*) new uchar[sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * mysql_num_rows(result2))]; - memset(tmpLD, 0, sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * mysql_num_rows(result2))); - tmpLD->NumEntries = mysql_num_rows(result2); - i=0; - while ((row = mysql_fetch_row(result2))) { - if (i >= tmpLD->NumEntries) { - mysql_free_result(result); - mysql_free_result(result2); - safe_delete_array(tmpLD); - cerr << "Error in ZoneDatabase::DBLoadLoot, i >= NumEntries" << endl; - return false; - } - tmpLD->Entries[i].item_id = atoi(row[1]); - tmpLD->Entries[i].item_charges = atoi(row[2]); - tmpLD->Entries[i].equip_item = atoi(row[3]); - tmpLD->Entries[i].chance = atof(row[4]); - tmpLD->Entries[i].minlevel = atoi(row[5]); - tmpLD->Entries[i].maxlevel = atoi(row[6]); - tmpLD->Entries[i].multiplier = atoi(row[7]); - i++; - } - if (!EMuShareMemDLL.Loot.cbAddLootDrop(tmpid, tmpLD)) { - mysql_free_result(result); - mysql_free_result(result2); - safe_delete_array(tmpLD); - cout << "Error in ZoneDatabase::DBLoadLoot: !cbAddLootDrop(" << tmpid << ")" << endl; - return false; - } - safe_delete_array(tmpLD); - mysql_free_result(result2); - } - else { - cerr << "Error in LoadLoot (memshare) #3 query '" << query << "' " << errbuf << endl; - mysql_free_result(result); - safe_delete_array(query); - return false; - } - } - mysql_free_result(result); - } - else { - cerr << "Error in LoadLoot (memshare) #4 query '" << query << "' " << errbuf << endl; - safe_delete_array(query); - return false; - } + if(RunQuery(query, strlen(query), errbuf, &result)) { + if(row = mysql_fetch_row(result)) { + loot_drop_count = static_cast(atoul(row[0])); + max_loot_drop = static_cast(atoul(row[1])); + loot_drop_entries = static_cast(atoul(row[2])); + } + mysql_free_result(result); + } else { + LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query, errbuf); + } +} - return true; +void SharedDatabase::LoadLootTables(void *data, uint32 size) { + EQEmu::FixedMemoryVariableHashSet hash(reinterpret_cast(data), size); + const char *query = "SELECT loottable.id, loottable.mincash, loottable.maxcash, loottable.avgcoin," + " loottable_entries.lootdrop_id, loottable_entries.multiplier, loottable_entries.droplimit, " + "loottable_entries.mindrop, loottable_entries.probability FROM loottable JOIN loottable_entries" + " ON loottable.id = loottable_entries.loottable_id ORDER BY id"; + char errbuf[MYSQL_ERRMSG_SIZE]; + MYSQL_RES *result; + MYSQL_ROW row; + uint8 loot_table[sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * 128)]; + LootTable_Struct *lt = reinterpret_cast(loot_table); + + if(RunQuery(query, strlen(query), errbuf, &result)) { + uint32 current_id = 0; + uint32 current_entry = 0; + while(row = mysql_fetch_row(result)) { + uint32 id = static_cast(atoul(row[0])); + if(id != current_id) { + if(current_id != 0) { + hash.insert(current_id, loot_table, (sizeof(LootTable_Struct) + + (sizeof(LootTableEntries_Struct) * lt->NumEntries))); + } + + memset(loot_table, 0, sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * 128)); + current_entry = 0; + current_id = id; + lt->mincash = static_cast(atoul(row[1])); + lt->maxcash = static_cast(atoul(row[2])); + lt->avgcoin = static_cast(atoul(row[3])); + } + + if(current_entry > 128) { + continue; + } + + lt->Entries[current_entry].lootdrop_id = static_cast(atoul(row[4])); + lt->Entries[current_entry].multiplier = static_cast(atoi(row[5])); + lt->Entries[current_entry].droplimit = static_cast(atoi(row[6])); + lt->Entries[current_entry].mindrop = static_cast(atoi(row[7])); + lt->Entries[current_entry].probability = static_cast(atof(row[8])); + + ++(lt->NumEntries); + ++current_entry; + } + mysql_free_result(result); + } else { + LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query, errbuf); + } +} + +void SharedDatabase::LoadLootDrops(void *data, uint32 size) { + EQEmu::FixedMemoryVariableHashSet hash(reinterpret_cast(data), size); + const char *query = "SELECT lootdrop.id, lootdrop_entries.item_id, lootdrop_entries.item_charges, " + "lootdrop_entries.equip_item, lootdrop_entries.chance, lootdrop_entries.minlevel, " + "lootdrop_entries.maxlevel, lootdrop_entries.multiplier FROM lootdrop JOIN lootdrop_entries " + "ON lootdrop.id = lootdrop_entries.lootdrop_id ORDER BY lootdrop_id"; + char errbuf[MYSQL_ERRMSG_SIZE]; + MYSQL_RES *result; + MYSQL_ROW row; + + uint8 loot_drop[sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * 1260)]; + LootDrop_Struct *ld = reinterpret_cast(loot_drop); + if(RunQuery(query, strlen(query), errbuf, &result)) { + uint32 current_id = 0; + uint32 current_entry = 0; + while(row = mysql_fetch_row(result)) { + uint32 id = static_cast(atoul(row[0])); + if(id != current_id) { + if(current_id != 0) { + hash.insert(current_id, loot_drop, (sizeof(LootDrop_Struct) + + (sizeof(LootDropEntries_Struct) * ld->NumEntries))); + } + + memset(loot_drop, 0, sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * 1260)); + current_entry = 0; + current_id = id; + } + + if(current_entry > 1260) { + continue; + } + + ld->Entries[current_entry].item_id = static_cast(atoul(row[1])); + ld->Entries[current_entry].item_charges = static_cast(atoi(row[2])); + ld->Entries[current_entry].equip_item = static_cast(atoi(row[3])); + ld->Entries[current_entry].chance = static_cast(atof(row[4])); + ld->Entries[current_entry].minlevel = static_cast(atoi(row[5])); + ld->Entries[current_entry].maxlevel = static_cast(atoi(row[6])); + ld->Entries[current_entry].multiplier = static_cast(atoi(row[7])); + + ++(ld->NumEntries); + ++current_entry; + } + mysql_free_result(result); + } else { + LogFile->write(EQEMuLog::Error, "Error getting loot drop info from database: %s, %s", query, errbuf); + } +} + +bool SharedDatabase::LoadLoot() { + if(loot_table_mmf || loot_drop_mmf) + return true; + + try { + EQEmu::IPCMutex mutex("loot"); + mutex.Lock(); + loot_table_mmf = new EQEmu::MemoryMappedFile("shared/loot_table"); + loot_table_hash = new EQEmu::FixedMemoryVariableHashSet( + reinterpret_cast(loot_table_mmf->Get()), + loot_table_mmf->Size()); + loot_drop_mmf = new EQEmu::MemoryMappedFile("shared/loot_drop"); + loot_drop_hash = new EQEmu::FixedMemoryVariableHashSet( + reinterpret_cast(loot_drop_mmf->Get()), + loot_drop_mmf->Size()); + mutex.Unlock(); + } catch(std::exception &ex) { + LogFile->write(EQEMuLog::Error, "Error loading loot: %s", ex.what()); + return false; + } + + return true; } const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) { - return EMuShareMemDLL.Loot.GetLootTable(loottable_id); + if(!loot_table_hash) + return NULL; + + try { + if(loot_drop_hash->exists(loottable_id)) { + return &loot_table_hash->at(loottable_id); + } + } catch(std::exception &ex) { + LogFile->write(EQEMuLog::Error, "Could not get loot table: %s", ex.what()); + } + return NULL; } const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) { - return EMuShareMemDLL.Loot.GetLootDrop(lootdrop_id); + if(!loot_drop_hash) + return NULL; + + try { + if(loot_drop_hash->exists(lootdrop_id)) { + return &loot_drop_hash->at(lootdrop_id); + } + } catch(std::exception &ex) { + LogFile->write(EQEMuLog::Error, "Could not get loot drop: %s", ex.what()); + } + return NULL; } void SharedDatabase::GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message) { diff --git a/common/shareddb.h b/common/shareddb.h index 378a4612e..6aa5c59e2 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -8,6 +8,7 @@ #include "spdat.h" #include "Item.h" #include "fixed_memory_hash_set.h" +#include "fixed_memory_variable_hash_set.h" #include @@ -91,14 +92,13 @@ public: bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID); //loot - void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries, - uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries); - void LoadLoot(void *ptr, uint32 loot_table_count, uint32 max_loot_table, uint32 loot_table_entries, - uint32 loot_drop_count, uint32 max_loot_drop, uint32 loot_drop_entries); + void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries); + void GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries); + void LoadLootTables(void *data, uint32 size); + void LoadLootDrops(void *data, uint32 size); bool LoadLoot(); const LootTable_Struct* GetLootTable(uint32 loottable_id); const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id); - bool DBLoadLoot(); void LoadSkillCaps(void *data); bool LoadSkillCaps(); @@ -120,31 +120,11 @@ protected: EQEmu::MemoryMappedFile *items_mmf; EQEmu::FixedMemoryHashSet *items_hash; EQEmu::MemoryMappedFile *faction_mmf; - EQEmu::MemoryMappedFile *loot_mmf; + EQEmu::MemoryMappedFile *loot_table_mmf; + EQEmu::FixedMemoryVariableHashSet *loot_table_hash; + EQEmu::MemoryMappedFile *loot_drop_mmf; + EQEmu::FixedMemoryVariableHashSet *loot_drop_hash; EQEmu::MemoryMappedFile *skill_caps_mmf; }; - - - - #endif /*SHAREDDB_H_*/ - - - - - - - - - - - - - - - - - - - diff --git a/shared_memory/loot.cpp b/shared_memory/loot.cpp index 25527336d..b88f2312a 100644 --- a/shared_memory/loot.cpp +++ b/shared_memory/loot.cpp @@ -22,29 +22,43 @@ #include "../common/ipc_mutex.h" #include "../common/memory_mapped_file.h" #include "../common/eqemu_exception.h" +#include "../common/fixed_memory_variable_hash_set.h" #include "../common/loottable.h" void LoadLoot(SharedDatabase *database) { EQEmu::IPCMutex mutex("loot"); mutex.Lock(); - uint32 loottable_count, loottable_max, loottable_entries_count, lootdrop_count, lootdrop_max, lootdrop_entries_count; - database->GetLootTableInfo(loottable_max, loottable_entries_count, - lootdrop_max, lootdrop_entries_count); - uint32 size = (sizeof(uint32) *3) + - (sizeof(uint32) * (loottable_max + 1)) + - (sizeof(LootTable_Struct) * loottable_count) + - (sizeof(LootTableEntries_Struct) * loottable_entries_count) + - (sizeof(uint32) * (lootdrop_max + 1)) + - (sizeof(LootDrop_Struct) * lootdrop_count) + - (sizeof(LootDropEntries_Struct) * lootdrop_entries_count); + uint32 loot_table_count, loot_table_max, loot_table_entries_count; + uint32 loot_drop_count, loot_drop_max, loot_drop_entries_count; + database->GetLootTableInfo(loot_table_count, loot_table_max, loot_table_entries_count); + database->GetLootDropInfo(loot_drop_count, loot_drop_max, loot_drop_entries_count); - EQEmu::MemoryMappedFile mmf("shared/loot", size); - mmf.ZeroFile(); - - void *ptr = mmf.Get(); - database->LoadLoot(ptr, loottable_count, loottable_max, loottable_entries_count, lootdrop_count, - lootdrop_max, lootdrop_entries_count); - mmf.SetLoaded(); + uint32 loot_table_size = (3 * sizeof(uint32)) + //header + ((loot_table_max + 1) * sizeof(uint32)) + //offset list + (loot_table_count * sizeof(LootTable_Struct)) + //loot table headers + (loot_table_entries_count * sizeof(LootTableEntries_Struct)); //number of loot table entries + + uint32 loot_drop_size = (3 * sizeof(uint32)) + //header + ((loot_drop_max + 1) * sizeof(uint32)) + //offset list + (loot_drop_count * sizeof(LootDrop_Struct)) + //loot table headers + (loot_drop_entries_count * sizeof(LootDropEntries_Struct)); //number of loot table entries + + EQEmu::MemoryMappedFile mmf_loot_table("shared/loot_table", loot_table_size); + EQEmu::MemoryMappedFile mmf_loot_drop("shared/loot_drop", loot_drop_size); + mmf_loot_table.ZeroFile(); + mmf_loot_drop.ZeroFile(); + + EQEmu::FixedMemoryVariableHashSet loot_table_hash(reinterpret_cast(mmf_loot_table.Get()), + loot_table_size, loot_table_max); + + EQEmu::FixedMemoryVariableHashSet loot_drop_hash(reinterpret_cast(mmf_loot_drop.Get()), + loot_drop_size, loot_drop_max); + + database->LoadLootTables(mmf_loot_table.Get(), loot_table_max); + database->LoadLootDrops(mmf_loot_drop.Get(), loot_drop_max); + + mmf_loot_table.SetLoaded(); + mmf_loot_drop.SetLoaded(); mutex.Unlock(); } diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index d8807d289..1529033ac 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -53,11 +53,11 @@ int main(int argc, char **argv) { return 0; } - bool load_all = false; - bool load_items = false; + bool load_all = true; + bool load_items = true; bool load_loot = true; - bool load_skill_caps = false; - bool load_spells = false; + bool load_skill_caps = true; + bool load_spells = true; if(load_all || load_items) { LogFile->write(EQEMuLog::Status, "Loading items..."); try {