Partial work on loot tables (non-compiling)

This commit is contained in:
KimLS
2013-02-21 22:13:33 -08:00
parent 543ef3fb32
commit 6f13d0cfbc
24 changed files with 909 additions and 487 deletions
+2
View File
@@ -132,6 +132,7 @@ SET(common_headers
extprofile.h
features.h
fixed_memory_hash_set.h
fixed_memory_variable_hash_set.h
guild_base.h
guilds.h
ipc_mutex.h
@@ -142,6 +143,7 @@ SET(common_headers
linked_list.h
logsys.h
logtypes.h
loottable.h
mail_oplist.h
md5.h
memory_mapped_file.h
+1 -1
View File
@@ -24,7 +24,7 @@
#endif
#include "../common/eq_packet_structs.h"
#include "../zone/zonedump.h"
#include "../zone/loottable.h"
#include "../common/loottable.h"
#include "SharedLibrary.h"
////////////
+17
View File
@@ -21,6 +21,7 @@
#include "types.h"
#include <string.h>
#include <string>
#include <list>
#include <time.h>
#include "../common/version.h"
//#include "../common/item_struct.h"
@@ -5039,6 +5040,22 @@ struct MercenaryMerchantResponse_Struct {
/*0004*/
};
struct ServerLootItem_Struct {
uint32 item_id;
int16 equipSlot;
uint8 charges;
uint16 lootslot;
uint32 aug1;
uint32 aug2;
uint32 aug3;
uint32 aug4;
uint32 aug5;
uint8 minlevel;
uint8 maxlevel;
};
typedef std::list<ServerLootItem_Struct*> ItemList;
// Restore structure packing to default
#pragma pack()
+241
View File
@@ -0,0 +1,241 @@
/* 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_FIXED_MEMORY_VARIABLE_HASHSET_H
#define _EQEMU_FIXED_MEMORY_VARIABLE_HASHSET_H
#include <string.h>
#include "eqemu_exception.h"
#include "types.h"
namespace EQEmu {
/*! Simple HashSet designed to be used in fixed memory that may be difficult to use an
allocator for (shared memory), we assume all keys are unsigned int, values are a pointer and size
*/
template<class T>
class FixedMemoryVariableHashSet {
typedef uint32 key_type;
typedef T value_type;
typedef uint8 byte;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef uint32 size_type;
public:
/*!
Constructor which initializes the hash set
\param data Raw data
\param size Raw data size
\param max_element_id Number of offsets to store: eg highest "key" that will be used.
*/
FixedMemoryVariableHashSet(byte *data, size_type size, key_type max_element_id) {
data_ = data;
size_ = size;
remaining_size_ = size_ - (sizeof(key_type) * 3) - (sizeof(key_type) * (max_element_id + 1));
byte *ptr = data;
*reinterpret_cast<key_type*>(ptr) = max_element_id + 1;
offset_count_ = max_element_id + 1;
ptr += sizeof(key_type);
*reinterpret_cast<key_type*>(ptr) = remaining_size_;
ptr += sizeof(key_type);
*reinterpret_cast<key_type*>(ptr) = 0;
current_offset_ = 0;
ptr += sizeof(key_type);
offsets_ = reinterpret_cast<key_type*>(ptr);
memset(ptr, 0xFFFFFFFFU, sizeof(key_type) * (max_element_id + 1));
ptr += sizeof(key_type) * (max_element_id + 1);
elements_ = reinterpret_cast<byte*>(ptr);
}
/*!
Constructor which does not initialize the hash set. Builds the hash set from what data is
stored in the data pointer passed.
\param data Raw data
\param size Raw data size
*/
FixedMemoryVariableHashSet(byte *data, size_type size) {
data_ = data;
size_ = size;
byte *ptr = data;
offset_count_ = *reinterpret_cast<key_type*>(ptr);
ptr += sizeof(key_type);
remaining_size_ = *reinterpret_cast<key_type*>(ptr);
ptr += sizeof(key_type);
current_offset_ = *reinterpret_cast<key_type*>(ptr);
ptr += sizeof(key_type);
offsets_ = reinterpret_cast<key_type*>(ptr);
ptr += sizeof(key_type) * offset_count_;
elements_ = reinterpret_cast<byte*>(ptr);
}
//! Copy Constructor
FixedMemoryVariableHashSet(const FixedMemoryVariableHashSet& other) :
data_(other.data_),
size_(other.size_),
offset_count_(other.offset_count_),
remaining_size_(other.remaining_size_),
current_offset_(other.current_offset_),
offsets_(other.offsets_),
elements_(other.elements_)
{
}
//! RValue-Move Constructor
#ifdef EQEMU_RVALUE_MOVE
FixedMemoryVariableHashSet(FixedMemoryVariableHashSet&& other) :
data_(other.data_),
size_(other.size_),
offset_count_(other.offset_count_),
remaining_size_(other.remaining_size_),
current_offset_(other.current_offset_),
offsets_(other.offsets_),
elements_(other.elements_)
{
}
#endif
//! Destructor
~FixedMemoryVariableHashSet() {
}
//! Assignment operator
const FixedMemoryVariableHashSet& operator=(const FixedMemoryVariableHashSet& other) {
data_ = other.data_;
size_ = other.size_;
offset_count_ = other.offset_count_;
remaining_size_ = other.remaining_size_;
current_offset_ = other.current_offset_;
offsets_ = other.offsets_;
elements_ = other.elements_;
return *this;
}
//! Returns the number of bytes in the set currently
size_type size() const {
return size_ - remaining_size_;
}
//! Returns the maximum number of bytes one can insert into the set.
size_type max_size() const {
return size_ - (sizeof(key_type) * 2);
}
//! 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
\param i Index to retrieve the value from
*/
reference operator[](const key_type& i) {
if(i >= offset_count_) {
EQ_EXCEPT("Fixed Memory Variable Hash Set", "Index out of range");
}
if(offsets_[i] == 0xFFFFFFFFU) {
EQ_EXCEPT("Fixed Memory Variable Hash Set", "Element not found.");
}
return *reinterpret_cast<value_type*>(&elements_[offsets_[i]]);
}
/*!
Retrieve value function
\param i Index to retrieve the value from
*/
reference at(const key_type& i) {
if(i >= offset_count_) {
EQ_EXCEPT("Fixed Memory Variable Hash Set", "Index out of range");
}
if(offsets_[i] == 0xFFFFFFFFU) {
EQ_EXCEPT("Fixed Memory Variable Hash Set", "Element not found.");
}
return *reinterpret_cast<value_type*>(&elements_[offsets_[i]]);
}
/*!
Checks if there is a value at a certain index
\param i Index to check for a value
*/
bool exists(const key_type& i) const {
if(i >= offset_count_) {
return false;
}
if(offsets_[i] == 0xFFFFFFFFU) {
return false;
}
return true;
}
/*!
Inserts a value into the set at a specific index
\param i Index to insert the value at
\param v Value to insert
*/
void insert(const key_type& i, byte *data, size_type size) {
if(i >= offset_count_) {
EQ_EXCEPT("Fixed Memory Variable Hash Set", "Index out of range.");
}
if(size > remaining_size_) {
EQ_EXCEPT("Fixed Memory Hash Set", "Not enough room in hash set to insert this value.");
}
if(offsets_[i] != 0xFFFFFFFFU) {
EQ_EXCEPT("Fixed Memory Hash Set", "Could not insert a repeat value at this index.");
} else {
offsets_[i] = current_offset_;
memcpy(&elements_[current_offset_], data, size);
remaining_size_ -= size;
*reinterpret_cast<key_type*>(data_ + sizeof(key_type)) = remaining_size_;
current_offset_ += size;
*reinterpret_cast<key_type*>(data_ + (sizeof(key_type) * 2)) = current_offset_;
}
}
private:
unsigned char *data_;
size_type size_;
size_type remaining_size_;
key_type current_offset_;
key_type offset_count_;
key_type *offsets_;
byte *elements_;
};
} // EQEmu
#endif
+56
View File
@@ -0,0 +1,56 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemu.org)
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_LOOTTABLE_H
#define _EQEMU_LOOTTABLE_H
#pragma pack(1)
struct LootTableEntries_Struct {
uint32 lootdrop_id;
uint8 droplimit;
uint8 mindrop;
uint8 multiplier;
float probability;
};
struct LootTable_Struct {
uint32 mincash;
uint32 maxcash;
uint32 avgcoin;
uint32 NumEntries;
LootTableEntries_Struct Entries[0];
};
struct LootDropEntries_Struct {
uint32 item_id;
int8 item_charges;
uint8 equip_item;
float chance;
uint8 minlevel;
uint8 maxlevel;
uint8 multiplier;
};
struct LootDrop_Struct {
uint32 NumEntries;
LootDropEntries_Struct Entries[0];
};
#pragma pack()
#endif
+385 -129
View File
@@ -18,40 +18,25 @@
using namespace std;
extern LoadEMuShareMemDLL EMuShareMemDLL;
//hackish mechanism to support callbacks from sharedmem
SharedDatabase *SharedDatabase::s_usedb = NULL;
SharedDatabase::SharedDatabase()
: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL)
: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), faction_mmf(NULL), loot_mmf(NULL)
{
SDBInitVars();
s_usedb = this;
}
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)
: Database(host, user, passwd, database, port), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL),
faction_mmf(NULL), loot_mmf(NULL)
{
SDBInitVars();
s_usedb = this;
}
void SharedDatabase::SDBInitVars() {
max_item = 0;
max_npc_type = 0;
loottable_max = 0;
lootdrop_max = 0;
max_door_type = 0;
npcfactionlist_max = 0;
}
SharedDatabase::~SharedDatabase() {
safe_delete(skill_caps_mmf);
safe_delete(items_mmf);
safe_delete(items_hash);
safe_delete(faction_mmf);
safe_delete(loot_mmf);
}
bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
@@ -753,41 +738,6 @@ int32 SharedDatabase::GetItemsCount(uint32* max_id) {
return ret;
}
int32 SharedDatabase::GetNPCTypesCount(uint32* oMaxID) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
query = new char[256];
strcpy(query, "SELECT MAX(id), count(*) FROM npc_types");
if (RunQuery(query, strlen(query), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row != NULL && row[1] != 0) {
int32 ret = atoi(row[1]);
if (oMaxID) {
if (row[0])
*oMaxID = atoi(row[0]);
else
*oMaxID = 0;
}
mysql_free_result(result);
return ret;
}
mysql_free_result(result);
}
else {
cerr << "Error in GetNPCTypesCount query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return -1;
}
return -1;
}
bool SharedDatabase::LoadItems() {
if(items_mmf) {
return true;
@@ -1133,7 +1083,8 @@ string SharedDatabase::GetBook(const char *txtfile)
bool SharedDatabase::extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID) {
return s_usedb->DBLoadNPCFactionLists(iNPCFactionListCount, iMaxNPCFactionListID);
return false;
//return s_usedb->DBLoadNPCFactionLists(iNPCFactionListCount, iMaxNPCFactionListID);
}
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
@@ -1150,8 +1101,7 @@ bool SharedDatabase::LoadNPCFactionLists() {
cout << "Error: SharedDatabase::LoadNPCFactionLists-ShareMem: GetNPCFactionListsCount() returned < 0" << endl;
return false;
}
npcfactionlist_max = tmp_npcfactionlist_max;
bool ret = EMuShareMemDLL.NPCFactionList.DLLLoadNPCFactionLists(&extDBLoadNPCFactionLists, sizeof(NPCFactionList), &tmp, &npcfactionlist_max, MAX_NPC_FACTIONS);
bool ret = EMuShareMemDLL.NPCFactionList.DLLLoadNPCFactionLists(&extDBLoadNPCFactionLists, sizeof(NPCFactionList), &tmp, &tmp_npcfactionlist_max, MAX_NPC_FACTIONS);
return ret;
}
@@ -1181,7 +1131,7 @@ bool SharedDatabase::DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iM
mysql_free_result(result);
return false;
}
npcfactionlist_max = atoi(row[0]);
//npcfactionlist_max = atoi(row[0]);
mysql_free_result(result);
NPCFactionList tmpnfl;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, primaryfaction, ignore_primary_assist from npc_faction"), errbuf, &result)) {
@@ -1698,76 +1648,6 @@ const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
return NULL; // nothing here for now... database and/or sharemem pulls later
}
void SharedDatabase::GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT inspectmessage FROM character_ WHERE name='%s'", playername), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
mysql_free_result(result);
}
else {
cerr << "Error in GetPlayerInspectMessage query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
void SharedDatabase::SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", message->text, playername), errbuf)) {
cerr << "Error in SetPlayerInspectMessage query '" << query << "' " << errbuf << endl;
}
safe_delete_array(query);
}
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT BotInspectMessage FROM bots WHERE BotID=%i", botid), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
mysql_free_result(result);
}
else {
cerr << "Error in GetBotInspectMessage query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", message->text, botid), errbuf)) {
cerr << "Error in SetBotInspectMessage query '" << query << "' " << errbuf << endl;
}
safe_delete_array(query);
}
int SharedDatabase::GetMaxSpellID() {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = NULL;
@@ -1921,3 +1801,379 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
safe_delete_array(query);
}
}
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<uint8*>(ptr);
uint32 *loottable_max = reinterpret_cast<uint32*>(ptr); data += sizeof(uint32);
uint32 *lootdrop_max = reinterpret_cast<uint32*>(ptr); data += sizeof(uint32);
uint32 *lootdrop_offset = reinterpret_cast<uint32*>(ptr); data += sizeof(uint32);
uint32 *loottable_offset = reinterpret_cast<uint32*>(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<uint32*>(reinterpret_cast<uint8*>(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<LootTable_Struct*>(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)
{
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";
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *result;
MYSQL_ROW row;
if(RunQuery(count_query, strlen(count_query), errbuf, &result)) {
if(row = mysql_fetch_row(result)) {
loot_table_count = static_cast<uint32>(atoul(row[0]));
loot_drop_count = static_cast<uint32>(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(max_query, strlen(max_query), errbuf, &result)) {
if(row = mysql_fetch_row(result)) {
max_loot_table = static_cast<uint32>(atoul(row[0]));
max_loot_drop = static_cast<uint32>(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<uint32>(atoul(row[0]));
loot_drop_entries = static_cast<uint32>(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;
}
}
bool SharedDatabase::DBLoadLoot() {
LogFile->write(EQEMuLog::Status, "Loading Loot tables from database...");
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
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;
}
return true;
}
const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
return EMuShareMemDLL.Loot.GetLootTable(loottable_id);
}
const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
return EMuShareMemDLL.Loot.GetLootDrop(lootdrop_id);
}
void SharedDatabase::GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT inspectmessage FROM character_ WHERE name='%s'", playername), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
mysql_free_result(result);
}
else {
cerr << "Error in GetPlayerInspectMessage query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
void SharedDatabase::SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", message->text, playername), errbuf)) {
cerr << "Error in SetPlayerInspectMessage query '" << query << "' " << errbuf << endl;
}
safe_delete_array(query);
}
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT BotInspectMessage FROM bots WHERE BotID=%i", botid), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
mysql_free_result(result);
}
else {
cerr << "Error in GetBotInspectMessage query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", message->text, botid), errbuf)) {
cerr << "Error in SetBotInspectMessage query '" << query << "' " << errbuf << endl;
}
safe_delete_array(query);
}
+20 -32
View File
@@ -47,7 +47,7 @@ public:
void SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message);
void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message);
void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message);
bool GetCommandSettings(map<string,uint8> &commands);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
/*
@@ -76,28 +76,29 @@ public:
/*
* Shared Memory crap
*/
inline const uint32 GetMaxItem() { return max_item; }
inline const uint32 GetMaxLootTableID() { return loottable_max; }
inline const uint32 GetMaxLootDropID() { return lootdrop_max; }
inline const uint32 GetMaxNPCType() { return max_npc_type; }
inline const uint32 GetMaxNPCFactionList() { return npcfactionlist_max; }
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
const NPCFactionList* GetNPCFactionEntry(uint32 id);
const LootTable_Struct* GetLootTable(uint32 loottable_id);
const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id);
bool LoadLoot();
bool LoadNPCFactionLists();
bool GetCommandSettings(map<string,uint8> &commands);
bool DBLoadItems(int32 iItemCount, uint32 iMaxItemID);
bool DBLoadNPCTypes(int32 iNPCTypeCount, uint32 iMaxNPCTypeID);
bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
bool DBLoadLoot();
//items
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);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
//faction lists
const NPCFactionList* GetNPCFactionEntry(uint32 id);
bool LoadNPCFactionLists();
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);
bool LoadLoot();
const LootTable_Struct* GetLootTable(uint32 loottable_id);
const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id);
bool DBLoadLoot();
void LoadSkillCaps(void *data);
bool LoadSkillCaps();
@@ -109,31 +110,18 @@ public:
void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID);
protected:
void SDBInitVars();
/*
* Private shared mem stuff
*/
int32 GetNPCTypesCount(uint32* oMaxID = 0);
int32 GetNPCFactionListsCount(uint32* oMaxID = 0);
static bool extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
static bool extDBLoadLoot();
uint32 max_item;
uint32 max_npc_type;
uint32 max_door_type;
uint32 npcfactionlist_max;
uint32 loottable_max;
uint32 lootdrop_max;
uint32 npc_spells_maxid;
EQEmu::MemoryMappedFile *items_mmf;
EQEmu::FixedMemoryHashSet<Item_Struct> *items_hash;
EQEmu::MemoryMappedFile *faction_mmf;
EQEmu::MemoryMappedFile *loot_mmf;
EQEmu::MemoryMappedFile *skill_caps_mmf;
private:
static SharedDatabase *s_usedb;
};