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

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

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"
////////////

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()

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

View File

@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
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
@ -15,33 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
alter table npc_types add column loottable_id int(11) unsigned not null;
create table loottable (id int(11) unsigned auto_increment primary key, name varchar(255) not null unique,
mincash int(11) unsigned not null, maxcash int(11) unsigned not null, avgcoin smallint(4) unsigned not null default 0);
#ifndef _EQEMU_LOOTTABLE_H
#define _EQEMU_LOOTTABLE_H
create table loottable_entries (loottable_id int(11) unsigned not null, lootdrop_id int(11) unsigned not null,
multiplier tinyint(2) unsigned default 1 not null, probability tinyint(2) unsigned default 100 not null,
primary key (loottable_id, lootdrop_id));
create table lootdrop (id int(11) unsigned auto_increment primary key, name varchar(255) not null unique);
create table lootdrop_entries (lootdrop_id int(11) unsigned not null, item_id int(11) not null,
item_charges tinyint(2) default 1 not null, equip_item tinyint(2) unsigned not null,
chance tinyint(2) unsigned default 1 not null, primary key (lootdrop_id, item_id));
ALTER TABLE `loottable_entries` ADD `probability` FLOAT NOT NULL DEFAULT '100';
*/
#ifndef LOOTTABLE_H
#define LOOTTABLE_H
#include "zonedump.h"
#include "../common/linked_list.h"
#include <list>
using namespace std;
#pragma pack(1)
struct LootTableEntries_Struct {
@ -76,6 +53,4 @@ struct LootDrop_Struct {
};
#pragma pack()
typedef list<ServerLootItem_Struct*> ItemList;
#endif

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);
}

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;
};

View File

@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(shared_memory_sources
items.cpp
loot.cpp
main.cpp
spells.cpp
skill_caps.cpp
@ -9,6 +10,7 @@ SET(shared_memory_sources
SET(shared_memory_headers
items.h
loot.h
spells.h
skill_caps.h
)

View File

@ -22,9 +22,6 @@
#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) {

50
shared_memory/loot.cpp Normal file
View File

@ -0,0 +1,50 @@
/* 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 "loot.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/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);
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();
mutex.Unlock();
}

25
shared_memory/loot.h Normal file
View 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_LOOT_H
#define __EQEMU_SHARED_MEMORY_LOOT_H
class SharedDatabase;
void LoadLoot(SharedDatabase *database);
#endif

View File

@ -25,6 +25,7 @@
#include "../common/rulesys.h"
#include "../common/eqemu_exception.h"
#include "items.h"
#include "loot.h"
#include "skill_caps.h"
#include "spells.h"
@ -52,10 +53,11 @@ int main(int argc, char **argv) {
return 0;
}
bool load_all = true;
bool load_items = true;
bool load_skill_caps = true;
bool load_spells = true;
bool load_all = false;
bool load_items = false;
bool load_loot = true;
bool load_skill_caps = false;
bool load_spells = false;
if(load_all || load_items) {
LogFile->write(EQEMuLog::Status, "Loading items...");
try {
@ -66,6 +68,16 @@ int main(int argc, char **argv) {
}
}
if(load_all || load_loot) {
LogFile->write(EQEMuLog::Status, "Loading loot...");
try {
LoadLoot(&database);
} catch(std::exception &ex) {
LogFile->write(EQEMuLog::Error, "%s", ex.what());
return 0;
}
}
if(load_all || load_skill_caps) {
LogFile->write(EQEMuLog::Status, "Loading skill caps...");
try {

View File

@ -22,7 +22,6 @@
#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"

View File

@ -7,9 +7,10 @@ SET(tests_sources
)
SET(tests_headers
memory_mapped_file_test.h
ipc_mutex_test.h
fixed_memory_test.h
fixed_memory_variable_test.h
ipc_mutex_test.h
memory_mapped_file_test.h
)
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})

View File

@ -0,0 +1,132 @@
/* 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_TESTS_FIXED_MEMORY_VARIABLE_H
#define __EQEMU_TESTS_FIXED_MEMORY_VARIABLE_H
#include "cppunit/cpptest.h"
#include "../common/fixed_memory_variable_hash_set.h"
struct test_struct {
char name[512];
};
class FixedMemoryVariableHashTest : public Test::Suite {
typedef void(FixedMemoryVariableHashTest::*TestFunction)(void);
public:
FixedMemoryVariableHashTest() {
size_ = 1024 + 12 + 2008;
data_ = new uint8[size_];
memset(data_, 0, size_);
TEST_ADD(FixedMemoryVariableHashTest::InitTest);
TEST_ADD(FixedMemoryVariableHashTest::LoadTest);
TEST_ADD(FixedMemoryVariableHashTest::InsertTest);
TEST_ADD(FixedMemoryVariableHashTest::RetrieveTest);
TEST_ADD(FixedMemoryVariableHashTest::InsertAgainTest);
TEST_ADD(FixedMemoryVariableHashTest::RetrieveAgainTest);
TEST_ADD(FixedMemoryVariableHashTest::InsertAgainFailTest);
TEST_ADD(FixedMemoryVariableHashTest::RetrieveAgainFailTest);
}
~FixedMemoryVariableHashTest() {
delete[] data_;
}
void InitTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_, 501);
TEST_ASSERT(!hash.exists(0));
TEST_ASSERT(!hash.exists(501));
}
void LoadTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
TEST_ASSERT(!hash.exists(0));
TEST_ASSERT(!hash.exists(501));
}
void InsertTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
test_struct test;
memset(&test, 0, sizeof(test));
strcpy(test.name, "Bill D.");
hash.insert(0, reinterpret_cast<byte*>(&test), sizeof(test));
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(!hash.exists(501));
}
void RetrieveTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(!hash.exists(501));
test_struct test = hash[0];
TEST_ASSERT(strcmp(test.name, "Bill D.") == 0);
}
void InsertAgainTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
test_struct test;
memset(&test, 0, sizeof(test));
strcpy(test.name, "Jimmy P.");
hash.insert(501, reinterpret_cast<byte*>(&test), sizeof(test));
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(hash.exists(501));
}
void RetrieveAgainTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(hash.exists(501));
test_struct test = hash[501];
TEST_ASSERT(strcmp(test.name, "Jimmy P.") == 0);
}
void InsertAgainFailTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
test_struct test;
memset(&test, 0, sizeof(test));
strcpy(test.name, "Tommy M.");
try {
hash.insert(500, reinterpret_cast<byte*>(&test), sizeof(test));
} catch(std::exception&) { }
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(hash.exists(501));
TEST_ASSERT(!hash.exists(500));
}
void RetrieveAgainFailTest() {
EQEmu::FixedMemoryVariableHashSet<test_struct> hash(data_, size_);
TEST_ASSERT(hash.exists(0));
TEST_ASSERT(hash.exists(501));
TEST_ASSERT(!hash.exists(500));
try {
test_struct test = hash[500];
TEST_ASSERT(false);
} catch(std::exception&) { }
}
private:
uint8 *data_;
uint32 size_;
};
#endif

View File

@ -39,6 +39,7 @@
#include "memory_mapped_file_test.h"
#include "ipc_mutex_test.h"
#include "fixed_memory_test.h"
#include "fixed_memory_variable_test.h"
int main() {
try {
@ -48,6 +49,7 @@ int main() {
tests.add(std::auto_ptr<MemoryMappedFileTest>(new MemoryMappedFileTest()));
tests.add(std::auto_ptr<IPCMutexTest>(new IPCMutexTest()));
tests.add(std::auto_ptr<FixedMemoryHashTest>(new FixedMemoryHashTest()));
tests.add(std::auto_ptr<FixedMemoryVariableHashTest>(new FixedMemoryVariableHashTest()));
tests.run(*output, true);
} catch(...) {
return -1;

View File

@ -111,7 +111,6 @@ SET(zone_headers
guild_mgr.h
hate_list.h
horse.h
loottable.h
map.h
masterentity.h
maxskill.h

View File

@ -7867,7 +7867,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
// Verify there are no NODROP or items with a zero price
bool TradeItemsValid = true;
for(int i=0; i<max_items; i++) {
for(uint32 i = 0; i < max_items; i++) {
if(gis->Items[i] == 0) break;
@ -7897,11 +7897,11 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
return;
}
for (int i=0;i<max_items;i++) {
if(gis->Items[i]>0 && gis->Items[i]<database.GetMaxItem() && database.GetItem(gis->Items[i])!=0)
for (uint32 i = 0; i < max_items; i++) {
if(database.GetItem(gis->Items[i])) {
database.SaveTraderItem(this->CharacterID(),gis->Items[i],gis->SerialNumber[i],
gis->Charges[i],ints->ItemCost[i],i);
else {
} else {
//return; //sony doesnt memset so assume done on first bad item
break;
}

View File

@ -665,38 +665,6 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version)
return -1;
}
/*
extern "C" bool extDBLoadDoors(int32 iDoorCount, uint32 iMaxDoorID) { return database.DBLoadDoors(iDoorCount, iMaxDoorID); }
const Door* ZoneDatabase::GetDoor(uint8 door_id, const char* zone_name) {
for(uint32 i=0; i!=max_door_type;i++)
{
const Door* door;
door = GetDoorDBID(i);
if (!door)
continue;
if(door->door_id == door_id && strcasecmp(door->zone_name, zone_name) == 0)
return door;
}
return 0;
}
const Door* ZoneDatabase::GetDoorDBID(uint32 db_id) {
return EMuShareMemDLL.Doors.GetDoor(db_id);
}
bool ZoneDatabase::LoadDoors() {
if (!EMuShareMemDLL.Load())
return false;
int32 tmp = 0;
tmp = GetDoorsCount(&max_door_type);
if (tmp == -1) {
cout << "Error: ZoneDatabase::LoadDoors-ShareMem: GetDoorsCount() returned < 0" << endl;
return false;
}
bool ret = EMuShareMemDLL.Doors.DLLLoadDoors(&extDBLoadDoors, sizeof(Door), &tmp, &max_door_type);
return ret;
}*/
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
char errbuf[MYSQL_ERRMSG_SIZE];

View File

@ -28,234 +28,6 @@ using namespace std;
#define snprintf _snprintf
#endif
#include "../common/EMuShareMem.h"
extern LoadEMuShareMemDLL EMuShareMemDLL;
bool SharedDatabase::extDBLoadLoot() {
return s_usedb->DBLoadLoot();
}
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);
}
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);
}
// Queries the loottable: adds item & coin to the npc
void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) {
_ZP(Database_AddLootTableToNPC);

View File

@ -28,7 +28,7 @@ class NPC;
using namespace std;
#include "spawn2.h"
#include "loottable.h"
#include "../common/loottable.h"
#include "zonedump.h"
#include "QGlobals.h"
#include "../common/rulesys.h"

View File

@ -498,10 +498,6 @@ void Parser::Event(QuestEventID event, uint32 npcid, const char * data, NPC* npc
Parser::Parser() : DEFAULT_QUEST_PREFIX("default") {
MainList.clear();
pMaxNPCID = database.GetMaxNPCType();
/*pNPCqstID = new int32[pMaxNPCID+1];
for (uint32 i=0; i<pMaxNPCID+1; i++)
pNPCqstID[i] = -1;*/
pNPCqstID = new int32[1];
npcarrayindex=1;
}

View File

@ -3,7 +3,8 @@
#include "../common/shareddb.h"
#include "../common/eq_packet_structs.h"
#include "loottable.h"
#include "../common/loottable.h"
#include "zonedump.h"
#include "faction.h"
//#include "doors.h"
@ -169,6 +170,7 @@ struct LootTable_Struct;
class ZoneDatabase : public SharedDatabase {
typedef list<ServerLootItem_Struct*> ItemList;
public:
ZoneDatabase();
ZoneDatabase(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
@ -482,7 +484,7 @@ protected:
uint32 max_faction;
Faction** faction_array;
uint32 max_door_type;
uint32 npc_spells_maxid;
DBnpcspells_Struct** npc_spells_cache;
bool* npc_spells_loadtried;

View File

@ -161,20 +161,6 @@ charname varchar(30) not null, zonename varchar(16)not null, x float not null, y
heading float not null, data blob not null, time timestamp(14), index zonename (zonename));
*/
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;
};
namespace player_lootitem
{
struct ServerLootItem_Struct {