mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-21 06:22:27 +00:00
Items in shared memory
This commit is contained in:
parent
0115b18e67
commit
3e9c2a06a3
@ -49,7 +49,7 @@ namespace EQEmu {
|
|||||||
size_ = size;
|
size_ = size;
|
||||||
|
|
||||||
byte *ptr = data;
|
byte *ptr = data;
|
||||||
*reinterpret_cast<key_type*>(ptr) = max_element_id;
|
*reinterpret_cast<key_type*>(ptr) = max_element_id + 1;
|
||||||
offset_count_ = max_element_id + 1;
|
offset_count_ = max_element_id + 1;
|
||||||
ptr += sizeof(key_type);
|
ptr += sizeof(key_type);
|
||||||
|
|
||||||
@ -62,8 +62,8 @@ namespace EQEmu {
|
|||||||
ptr += sizeof(key_type);
|
ptr += sizeof(key_type);
|
||||||
|
|
||||||
offsets_ = reinterpret_cast<key_type*>(ptr);
|
offsets_ = reinterpret_cast<key_type*>(ptr);
|
||||||
memset(ptr, 0xFFFFFFFFU, sizeof(key_type) * max_element_id);
|
memset(ptr, 0xFFFFFFFFU, sizeof(key_type) * (max_element_id + 1));
|
||||||
ptr += sizeof(key_type) * max_element_id;
|
ptr += sizeof(key_type) * (max_element_id + 1);
|
||||||
|
|
||||||
elements_ = reinterpret_cast<value_type*>(ptr);
|
elements_ = reinterpret_cast<value_type*>(ptr);
|
||||||
}
|
}
|
||||||
@ -152,6 +152,11 @@ namespace EQEmu {
|
|||||||
return max_elements_;
|
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
|
Retrieve value operator
|
||||||
\param i Index to retrieve the value from
|
\param i Index to retrieve the value from
|
||||||
|
|||||||
@ -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];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
int32 ret = -1;
|
int32 ret = -1;
|
||||||
|
|
||||||
char query[] = "SELECT MAX(id), count(*) FROM items";
|
char query[] = "SELECT MAX(id), count(*) FROM items";
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
if (RunQuery(query, static_cast<uint32>(strlen(query)), errbuf, &result)) {
|
||||||
row = mysql_fetch_row(result);
|
row = mysql_fetch_row(result);
|
||||||
if (row != NULL && row[1] != 0) {
|
if (row != NULL && row[1] != 0) {
|
||||||
ret = atoi(row[1]);
|
ret = atoi(row[1]);
|
||||||
if (oMaxID) {
|
if (max_id) {
|
||||||
if (row[0])
|
if (row[0])
|
||||||
*oMaxID = atoi(row[0]);
|
*max_id = atoi(row[0]);
|
||||||
else
|
else
|
||||||
*oMaxID = 0;
|
*max_id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cerr << "Error in GetItemsCount query '" << query << "' " << errbuf << endl;
|
LogFile->write(EQEMuLog::Error, "Error in GetItemsCount '%s': '%s'", query, errbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -788,47 +788,44 @@ int32 SharedDatabase::GetNPCTypesCount(uint32* oMaxID) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SharedDatabase::extDBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
|
||||||
return s_usedb->DBLoadItems(iItemCount, iMaxItemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SharedDatabase::LoadItems() {
|
bool SharedDatabase::LoadItems() {
|
||||||
if (!EMuShareMemDLL.Load())
|
if(items_mmf) {
|
||||||
return false;
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load all database items into cache
|
try {
|
||||||
bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
EQEmu::IPCMutex mutex("items");
|
||||||
_CP(Database_DBLoadItems);
|
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<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::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<Item_Struct>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
|
||||||
|
mutex.Unlock();
|
||||||
|
} catch(std::exception& ex) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error Loading Items: %s", ex.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) {
|
||||||
|
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
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];
|
char ndbuffer[4];
|
||||||
|
bool disableNoRent = false;
|
||||||
if(GetVariable("disablenorent", ndbuffer, 4)) {
|
if(GetVariable("disablenorent", ndbuffer, 4)) {
|
||||||
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
||||||
disableNoRent = true;
|
disableNoRent = true;
|
||||||
@ -853,20 +850,15 @@ bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve all items from database
|
|
||||||
char query[] = "select source,"
|
char query[] = "select source,"
|
||||||
#define F(x) "`"#x"`,"
|
#define F(x) "`"#x"`,"
|
||||||
#include "item_fieldlist.h"
|
#include "item_fieldlist.h"
|
||||||
#undef F
|
#undef F
|
||||||
"updated"
|
"updated"
|
||||||
" from items order by id";
|
" from items order by id";
|
||||||
|
|
||||||
Item_Struct item;
|
Item_Struct item;
|
||||||
if(RunQuery(query, sizeof(query), errbuf, &result)) {
|
if(RunQuery(query, sizeof(query), errbuf, &result)) {
|
||||||
while((row = mysql_fetch_row(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));
|
memset(&item, 0, sizeof(Item_Struct));
|
||||||
|
|
||||||
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
||||||
@ -881,9 +873,7 @@ bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
|||||||
item.Slots = (uint32)atoul(row[ItemField::slots]);
|
item.Slots = (uint32)atoul(row[ItemField::slots]);
|
||||||
item.Price = (uint32)atoul(row[ItemField::price]);
|
item.Price = (uint32)atoul(row[ItemField::price]);
|
||||||
item.Icon = (uint32)atoul(row[ItemField::icon]);
|
item.Icon = (uint32)atoul(row[ItemField::icon]);
|
||||||
//item.Unk012 = (int32)atoul(row[ItemField::UNK012]);
|
item.BenefitFlag = (atoul(row[ItemField::benefitflag]) != 0);
|
||||||
//item.Unk013 = (uint32)atoul(row[ItemField::UNK013]);
|
|
||||||
item.BenefitFlag = (uint32)atoul(row[ItemField::benefitflag]);
|
|
||||||
item.Tradeskills = (atoi(row[ItemField::tradeskills])==0) ? false : true;
|
item.Tradeskills = (atoi(row[ItemField::tradeskills])==0) ? false : true;
|
||||||
item.CR = (int8)atoi(row[ItemField::cr]);
|
item.CR = (int8)atoi(row[ItemField::cr]);
|
||||||
item.DR = (int8)atoi(row[ItemField::dr]);
|
item.DR = (int8)atoi(row[ItemField::dr]);
|
||||||
@ -998,18 +988,14 @@ bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
|||||||
item.RecastType = (uint32)atoul(row[ItemField::recasttype]);
|
item.RecastType = (uint32)atoul(row[ItemField::recasttype]);
|
||||||
item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]);
|
item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]);
|
||||||
item.AugDistiller = (uint32)atoul(row[ItemField::augdistiller]);
|
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.Attuneable = (atoi(row[ItemField::attuneable])==0) ? false : true;
|
||||||
item.NoPet = (atoi(row[ItemField::nopet])==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.PointType = (uint32)atoul(row[ItemField::pointtype]);
|
||||||
item.PotionBelt = (atoi(row[ItemField::potionbelt])==0) ? false : true;
|
item.PotionBelt = (atoi(row[ItemField::potionbelt])==0) ? false : true;
|
||||||
item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots])==0) ? false : true;
|
item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots])==0) ? false : true;
|
||||||
item.StackSize = (uint16)atoi(row[ItemField::stacksize]);
|
item.StackSize = (uint16)atoi(row[ItemField::stacksize]);
|
||||||
item.NoTransfer = disableNoTransfer ? false : (atoi(row[ItemField::notransfer])==0) ? false : true;
|
item.NoTransfer = disableNoTransfer ? false : (atoi(row[ItemField::notransfer])==0) ? false : true;
|
||||||
item.Stackable = (atoi(row[ItemField::stackable])==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.Effect = (uint32)atoul(row[ItemField::clickeffect]);
|
||||||
item.Click.Type = (uint8)atoul(row[ItemField::clicktype]);
|
item.Click.Type = (uint8)atoul(row[ItemField::clicktype]);
|
||||||
item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]);
|
item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]);
|
||||||
@ -1065,31 +1051,52 @@ bool SharedDatabase::DBLoadItems(int32 iItemCount, uint32 iMaxItemID) {
|
|||||||
strcpy(item.FocusName,row[ItemField::focusname]);
|
strcpy(item.FocusName,row[ItemField::focusname]);
|
||||||
strcpy(item.ScrollName,row[ItemField::scrollname]);
|
strcpy(item.ScrollName,row[ItemField::scrollname]);
|
||||||
|
|
||||||
if (!EMuShareMemDLL.Items.cbAddItem(item.ID, &item)) {
|
try {
|
||||||
LogFile->write(EQEMuLog::Error, "Database::DBLoadItems: Failure reported from EMuShareMemDLL.Items.cbAddItem(%i)", item.ID);
|
hash.insert(item.ID, item);
|
||||||
|
} catch(std::exception &ex) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Database::LoadItems: %s", ex.what());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogFile->write(EQEMuLog::Error, "DBLoadItems query '%s', %s", query, errbuf);
|
LogFile->write(EQEMuLog::Error, "LoadItems '%s', %s", query, errbuf);
|
||||||
LogFile->write(EQEMuLog::Error, "If you got boat loads of errors, make sure you sourced all sql updates!\n");
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
||||||
return EMuShareMemDLL.Items.GetItem(id);
|
if(!items_hash || id > items_hash->max_key()) {
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Item_Struct* SharedDatabase::IterateItems(uint32* NextIndex) {
|
if(items_hash->exists(id)) {
|
||||||
return EMuShareMemDLL.Items.IterateItems(NextIndex);
|
return &(items_hash->at(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
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 class_count = PLAYER_CLASS_COUNT;
|
||||||
uint32 skill_count = HIGHEST_SKILL + 1;
|
uint32 skill_count = HIGHEST_SKILL + 1;
|
||||||
uint32 level_count = HARD_LEVEL_CAP + 1;
|
uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
|
if(Class_ > class_count || Skill > skill_count || Level > level_count) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(Level > static_cast<uint8>(SkillMaxLevel)){
|
if(Level > static_cast<uint8>(SkillMaxLevel)){
|
||||||
Level = static_cast<uint8>(SkillMaxLevel);
|
Level = static_cast<uint8>(SkillMaxLevel);
|
||||||
}
|
}
|
||||||
@ -1620,8 +1631,11 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level)
|
|||||||
uint32 class_count = PLAYER_CLASS_COUNT;
|
uint32 class_count = PLAYER_CLASS_COUNT;
|
||||||
uint32 skill_count = HIGHEST_SKILL + 1;
|
uint32 skill_count = HIGHEST_SKILL + 1;
|
||||||
uint32 level_count = HARD_LEVEL_CAP + 1;
|
uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
uint8 ret = 0;
|
if(Class_ > class_count || Skill > skill_count || Level > level_count) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 ret = 0;
|
||||||
if(Level > static_cast<uint8>(SkillMaxLevel)) {
|
if(Level > static_cast<uint8>(SkillMaxLevel)) {
|
||||||
uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
|
uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
|
||||||
uint16 *skill_caps_table = reinterpret_cast<uint16*>(skill_caps_mmf->Get());
|
uint16 *skill_caps_table = reinterpret_cast<uint16*>(skill_caps_mmf->Get());
|
||||||
|
|||||||
@ -81,29 +81,32 @@ public:
|
|||||||
inline const uint32 GetMaxLootDropID() { return lootdrop_max; }
|
inline const uint32 GetMaxLootDropID() { return lootdrop_max; }
|
||||||
inline const uint32 GetMaxNPCType() { return max_npc_type; }
|
inline const uint32 GetMaxNPCType() { return max_npc_type; }
|
||||||
inline const uint32 GetMaxNPCFactionList() { return npcfactionlist_max; }
|
inline const uint32 GetMaxNPCFactionList() { return npcfactionlist_max; }
|
||||||
const Item_Struct* GetItem(uint32 id);
|
|
||||||
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
|
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
|
||||||
const NPCFactionList* GetNPCFactionEntry(uint32 id);
|
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 LootTable_Struct* GetLootTable(uint32 loottable_id);
|
||||||
const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id);
|
const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id);
|
||||||
bool LoadItems();
|
|
||||||
bool LoadLoot();
|
bool LoadLoot();
|
||||||
bool LoadNPCFactionLists();
|
bool LoadNPCFactionLists();
|
||||||
bool GetCommandSettings(map<string,uint8> &commands);
|
bool GetCommandSettings(map<string,uint8> &commands);
|
||||||
const Item_Struct* IterateItems(uint32* NextIndex);
|
|
||||||
bool DBLoadItems(int32 iItemCount, uint32 iMaxItemID);
|
bool DBLoadItems(int32 iItemCount, uint32 iMaxItemID);
|
||||||
bool DBLoadNPCTypes(int32 iNPCTypeCount, uint32 iMaxNPCTypeID);
|
bool DBLoadNPCTypes(int32 iNPCTypeCount, uint32 iMaxNPCTypeID);
|
||||||
bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
|
bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
|
||||||
bool DBLoadLoot();
|
bool DBLoadLoot();
|
||||||
|
|
||||||
int GetMaxSpellID();
|
int32 GetItemsCount(uint32* max_id = 0);
|
||||||
void LoadSpells(void *data, int max_spells);
|
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||||
void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID);
|
bool LoadItems();
|
||||||
|
const Item_Struct* IterateItems(uint32* id);
|
||||||
|
const Item_Struct* GetItem(uint32 id);
|
||||||
|
|
||||||
void LoadSkillCaps(void *data);
|
void LoadSkillCaps(void *data);
|
||||||
bool LoadSkillCaps();
|
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:
|
protected:
|
||||||
void SDBInitVars();
|
void SDBInitVars();
|
||||||
@ -111,10 +114,8 @@ protected:
|
|||||||
/*
|
/*
|
||||||
* Private shared mem stuff
|
* Private shared mem stuff
|
||||||
*/
|
*/
|
||||||
int32 GetItemsCount(uint32* oMaxID = 0);
|
|
||||||
int32 GetNPCTypesCount(uint32* oMaxID = 0);
|
int32 GetNPCTypesCount(uint32* oMaxID = 0);
|
||||||
int32 GetNPCFactionListsCount(uint32* oMaxID = 0);
|
int32 GetNPCFactionListsCount(uint32* oMaxID = 0);
|
||||||
static bool extDBLoadItems(int32 iItemCount, uint32 iMaxItemID);
|
|
||||||
static bool extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
|
static bool extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
|
||||||
static bool extDBLoadLoot();
|
static bool extDBLoadLoot();
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
SET(shared_memory_sources
|
SET(shared_memory_sources
|
||||||
|
items.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
spells.cpp
|
spells.cpp
|
||||||
skill_caps.cpp
|
skill_caps.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(shared_memory_headers
|
SET(shared_memory_headers
|
||||||
|
items.h
|
||||||
spells.h
|
spells.h
|
||||||
skill_caps.h
|
skill_caps.h
|
||||||
)
|
)
|
||||||
|
|||||||
49
shared_memory/items.cpp
Normal file
49
shared_memory/items.cpp
Normal file
@ -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<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::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();
|
||||||
|
}
|
||||||
25
shared_memory/items.h
Normal file
25
shared_memory/items.h
Normal file
@ -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
|
||||||
@ -24,8 +24,9 @@
|
|||||||
#include "../common/crash.h"
|
#include "../common/crash.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/eqemu_exception.h"
|
#include "../common/eqemu_exception.h"
|
||||||
#include "spells.h"
|
#include "items.h"
|
||||||
#include "skill_caps.h"
|
#include "skill_caps.h"
|
||||||
|
#include "spells.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
RegisterExecutablePlatform(ExePlatformSharedMemory);
|
RegisterExecutablePlatform(ExePlatformSharedMemory);
|
||||||
@ -52,8 +53,19 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool load_all = true;
|
bool load_all = true;
|
||||||
|
bool load_items = true;
|
||||||
bool load_skill_caps = true;
|
bool load_skill_caps = true;
|
||||||
bool load_spells = 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) {
|
if(load_all || load_skill_caps) {
|
||||||
LogFile->write(EQEMuLog::Status, "Loading skill caps...");
|
LogFile->write(EQEMuLog::Status, "Loading skill caps...");
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -38,6 +38,10 @@ public:
|
|||||||
TEST_ADD(FixedMemoryHashTest::OverwriteRetrieveTest);
|
TEST_ADD(FixedMemoryHashTest::OverwriteRetrieveTest);
|
||||||
TEST_ADD(FixedMemoryHashTest::InsertAgainTest);
|
TEST_ADD(FixedMemoryHashTest::InsertAgainTest);
|
||||||
TEST_ADD(FixedMemoryHashTest::RetrieveAgainTest);
|
TEST_ADD(FixedMemoryHashTest::RetrieveAgainTest);
|
||||||
|
TEST_ADD(FixedMemoryHashTest::InsertBeginTest);
|
||||||
|
TEST_ADD(FixedMemoryHashTest::RetrieveBeginTest);
|
||||||
|
TEST_ADD(FixedMemoryHashTest::InsertEndTest);
|
||||||
|
TEST_ADD(FixedMemoryHashTest::RetrieveEndTest);
|
||||||
}
|
}
|
||||||
~FixedMemoryHashTest() {
|
~FixedMemoryHashTest() {
|
||||||
delete[] data_;
|
delete[] data_;
|
||||||
@ -142,6 +146,88 @@ public:
|
|||||||
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
|
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
|
||||||
TEST_ASSERT(item.ID == 1001);
|
TEST_ASSERT(item.ID == 1001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InsertBeginTest() {
|
||||||
|
EQEmu::FixedMemoryHashSet<Item_Struct> 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<Item_Struct> 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<Item_Struct> 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<Item_Struct> 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:
|
private:
|
||||||
uint8 *data_;
|
uint8 *data_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
|||||||
@ -42,23 +42,15 @@
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
try {
|
try {
|
||||||
std::unique_ptr<Test::Output> output(new Test::HtmlOutput);
|
std::ofstream outfile("test_output.txt");
|
||||||
|
std::unique_ptr<Test::Output> output(new Test::TextOutput(Test::TextOutput::Verbose, outfile));
|
||||||
Test::Suite tests;
|
Test::Suite tests;
|
||||||
tests.add(std::auto_ptr<MemoryMappedFileTest>(new MemoryMappedFileTest()));
|
tests.add(std::auto_ptr<MemoryMappedFileTest>(new MemoryMappedFileTest()));
|
||||||
tests.add(std::auto_ptr<IPCMutexTest>(new IPCMutexTest()));
|
tests.add(std::auto_ptr<IPCMutexTest>(new IPCMutexTest()));
|
||||||
tests.add(std::auto_ptr<FixedMemoryHashTest>(new FixedMemoryHashTest()));
|
tests.add(std::auto_ptr<FixedMemoryHashTest>(new FixedMemoryHashTest()));
|
||||||
tests.run(*output, true);
|
tests.run(*output, true);
|
||||||
|
|
||||||
std::ofstream outfile("tests.html");
|
|
||||||
Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());
|
|
||||||
if(html)
|
|
||||||
html->generate(outfile, true, "EQEmuTests");
|
|
||||||
|
|
||||||
outfile.close();
|
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
getchar();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
getchar();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -381,7 +381,6 @@ int command_init(void) {
|
|||||||
command_add("opcode","- opcode management",250,command_opcode) ||
|
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("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("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("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("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) ||
|
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);
|
c->Message(0, "Item #%s not found", search_criteria);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef SHAREMEM
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
//int iSearchLen = strlen(search_criteria)+1;
|
|
||||||
char sName[64];
|
char sName[64];
|
||||||
char sCriteria[255];
|
char sCriteria[255];
|
||||||
strn0cpy(sCriteria, search_criteria, sizeof(sCriteria));
|
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.");
|
c->Message(0, "50 items shown...too many results.");
|
||||||
else
|
else
|
||||||
c->Message(0, "%i items found", count);
|
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)
|
void command_setaaxp(Client *c, const Seperator *sep)
|
||||||
|
|||||||
@ -243,7 +243,6 @@ void command_summonitem(Client *c, const Seperator *sep);
|
|||||||
void command_giveitem(Client *c, const Seperator *sep);
|
void command_giveitem(Client *c, const Seperator *sep);
|
||||||
void command_givemoney(Client *c, const Seperator *sep);
|
void command_givemoney(Client *c, const Seperator *sep);
|
||||||
void command_itemsearch(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_setaaxp(Client *c, const Seperator *sep);
|
||||||
void command_setaapts(Client *c, const Seperator *sep);
|
void command_setaapts(Client *c, const Seperator *sep);
|
||||||
void command_setcrystals(Client *c, const Seperator *sep);
|
void command_setcrystals(Client *c, const Seperator *sep);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user