Merge remote-tracking branch 'remotes/origin/master' into blob_conversion

Conflicts:
	common/database.cpp
	common/mysql_request_result.h
	common/shareddb.cpp
This commit is contained in:
akkadius
2014-09-07 04:11:09 -05:00
67 changed files with 1201 additions and 703 deletions
+1
View File
@@ -92,6 +92,7 @@ SET(common_sources
)
SET(common_headers
any.h
base_packet.h
base_data.h
bodytypes.h
+190
View File
@@ -0,0 +1,190 @@
/*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing.
#ifndef EQEMU_COMMON_ANY_H
#define EQEMU_COMMON_ANY_H
#include <algorithm>
#include <typeinfo>
namespace EQEmu
{
class Any
{
public:
Any()
: content(nullptr)
{
}
template<typename ValueType>
Any(const ValueType &value)
: content(new Holder<ValueType>(value))
{
}
Any(const Any &other)
: content(other.content ? other.content->clone() : 0)
{
}
~Any()
{
if(content)
delete content;
}
Any& swap(Any &rhs)
{
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType>
Any& operator=(const ValueType &rhs)
{
Any(rhs).swap(*this);
return *this;
}
Any& operator=(Any rhs)
{
rhs.swap(*this);
return *this;
}
bool empty() const
{
return !content;
}
const std::type_info& type() const
{
return content ? content->type() : typeid(void);
}
class Placeholder
{
public:
virtual ~Placeholder()
{
}
virtual const std::type_info& type() const = 0;
virtual Placeholder* clone() const = 0;
};
template<typename ValueType>
class Holder : public Placeholder
{
public:
Holder(const ValueType &value)
: held(value)
{
}
virtual const std::type_info& type() const
{
return typeid(ValueType);
}
virtual Placeholder* clone() const
{
return new Holder(held);
}
ValueType held;
private:
Holder& operator=(const Holder&);
};
private:
template<typename ValueType>
friend ValueType* any_cast(Any*);
template<typename ValueType>
friend ValueType* unsafe_any_cast(Any*);
Placeholder* content;
};
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
}
};
template<typename ValueType>
ValueType* any_cast(Any* operand)
{
return operand &&
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
}
template<typename ValueType>
inline const ValueType* any_cast(const Any* operand)
{
return any_cast<ValueType>(const_cast<Any*>(operand));
}
template<typename ValueType>
ValueType any_cast(Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
nonref* result = any_cast<nonref>(&operand);
if(!result)
throw bad_any_cast();
return *result;
}
template<typename ValueType>
inline ValueType any_cast(const Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
return any_cast<const nonref&>(const_cast<Any&>(operand));
}
template<typename ValueType>
inline ValueType* unsafe_any_cast(Any* operand)
{
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
}
template<typename ValueType>
inline const ValueType* unsafe_any_cast(const Any* operand)
{
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
}
}
#endif
+3
View File
@@ -132,6 +132,9 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat
return 0;
}
if(results.RowCount() == 0)
return 0;
auto row = results.begin();
uint32 id = atoi(row[0]);
+1
View File
@@ -540,3 +540,4 @@ N(OP_OpenInventory),
N(OP_OpenContainer),
N(OP_Marquee),
N(OP_ClientTimeStamp),
N(OP_GuildPromote),
+15 -4
View File
@@ -2290,10 +2290,13 @@ struct Stun_Struct { // 4 bytes total
};
struct AugmentItem_Struct {
/*00*/ int16 container_slot;
/*02*/ char unknown02[2];
/*04*/ int32 augment_slot;
/*08*/
/*00*/ uint32 container_index;
/*04*/ int32 container_slot;
/*08*/ uint32 augment_index;
/*12*/ int32 augment_slot;
/*16*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented
/*20*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug
/*24*/
};
// OP_Emote
@@ -4464,6 +4467,14 @@ struct GuildBankPromote_Struct
/*12*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
};
struct GuildPromoteStruct {
/*000*/ char target[64];
/*064*/ char name[64];
/*128*/ uint32 rank;
/*132*/ uint32 myrank;
/*136*/
};
struct GuildBankPermissions_Struct
{
/*00*/ uint32 Action; // 6
+1 -1
View File
@@ -534,7 +534,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
//_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
if (!ack_req) {
NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size));
+5
View File
@@ -474,6 +474,11 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
return(true);
}
bool BaseGuildManager::ForceRankUpdate(uint32 charid) {
SendRankUpdate(charid);
return(true);
}
bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
{
if(!DBSetAltFlag(charid, is_alt))
+1
View File
@@ -54,6 +54,7 @@ public:
bool SetGuild(uint32 charid, uint32 guild_id, uint8 rank);
bool SetGuildRank(uint32 charid, uint8 rank);
bool SetBankerFlag(uint32 charid, bool is_banker);
bool ForceRankUpdate(uint32 charid);
bool GetAltFlag(uint32 CharID);
bool SetAltFlag(uint32 charid, bool is_alt);
bool GetBankerFlag(uint32 CharID);
+12 -1
View File
@@ -683,6 +683,13 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
if ((main_inst->GetID() == inst->GetID()) && (main_inst->GetCharges() < main_inst->GetItem()->StackSize))
return free_slot;
}
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
const ItemInst* main_inst = m_inv[free_slot];
if (!main_inst)
continue;
if (main_inst->IsType(ItemClassContainer)) { // if item-specific containers already have bad items, we won't fix it here...
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
@@ -732,8 +739,12 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
if (!main_inst)
return free_slot;
}
if (main_inst->IsType(ItemClassContainer)) {
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
const ItemInst* main_inst = m_inv[free_slot];
if (main_inst && main_inst->IsType(ItemClassContainer)) {
if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver))
continue;
+3 -3
View File
@@ -92,8 +92,8 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p);
class Mob;
extern void log_message_mob(LogType type, Mob *who, const char *fmt, ...);
#define mlog( type, format, ...) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_message_mob(type, this, format, ##__VA_ARGS__); \
} \
@@ -150,16 +150,16 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p);
class Mob;
extern void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length);
#define mhex( type, data, len) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_hex_mob(type, this, data, len); \
} \
} while(false)
extern void log_packet_mob(LogType type, Mob *who, const BasePacket *p);
#define mpkt( type, packet) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_packet_mob(type, this, packet); \
} \
+1 -1
View File
@@ -40,7 +40,7 @@ public:
MySQLRequestResult& operator=(MySQLRequestResult&& other);
bool Success() const { return m_Success;}
std::string ErrorMessage() const { return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string(""); }
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
uint32 ErrorNumber() const {return m_ErrorNumber;}
uint32 RowsAffected() const {return m_RowsAffected;}
uint32 RowCount() const {return m_RowCount;}
-1
View File
@@ -64,6 +64,5 @@ bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs)
char* MySQLRequestRow::operator[](int index)
{
return m_MySQLRow[index];
}
+32 -7
View File
@@ -1,4 +1,3 @@
#include "../debug.h"
#include "rof.h"
#include "../opcodemgr.h"
@@ -1974,7 +1973,14 @@ ENCODE(OP_ZoneSpawns)
else
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
/* Translate older ranks to new values */
switch (emu->guildrank) {
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
}
}
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
@@ -2406,7 +2412,15 @@ ENCODE(OP_GuildMemberList) {
PutFieldN(level);
PutFieldN(banker);
PutFieldN(class_);
PutFieldN(rank);
/* Translate older ranks to new values */
switch (emu_e->rank) {
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
}
PutFieldN(time_last_on);
PutFieldN(tribute_enable);
e->unknown01 = 0;
@@ -3330,7 +3344,15 @@ ENCODE(OP_SetGuildRank)
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct);
eq->GuildID = emu->Unknown00;
OUT(Rank);
/* Translate older ranks to new values */
switch (emu->Rank) {
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
default: { eq->Rank = emu->Rank; break; }
}
memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName));
OUT(Banker);
eq->Unknown76 = 1;
@@ -4660,8 +4682,11 @@ DECODE(OP_AugmentItem) {
SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
emu->container_slot = RoFToServerSlot(eq->container_slot);
//emu->augment_slot = eq->augment_slot;
emu->augment_slot = RoFToServerSlot(eq->augment_slot);
emu->container_index = eq->container_index;
emu->augment_index = eq->augment_index;
emu->dest_inst_id = eq->dest_inst_id;
emu->augment_action = eq->augment_action;
FINISH_DIRECT_DECODE();
}
@@ -5068,7 +5093,7 @@ char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint
memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct));
isbs.augtype = item->AugType;
isbs.augdistiller = 0;
isbs.augdistiller = 65535;
isbs.augrestrict = item->AugRestrict;
+3 -3
View File
@@ -2519,10 +2519,10 @@ struct Stun_Struct { // 8 bytes total
struct AugmentItem_Struct {
/*00*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented
/*04*/ uint32 unknown04; // Seen 0
/*04*/ uint32 container_index; // Seen 0
/*08*/ ItemSlotStruct container_slot; // Slot of the item being augmented
/*20*/ uint32 unknown20; // Seen 0
/*24*/ ItemSlotStruct distiller_slot; // Slot of the distiller to use (if one applies)
/*20*/ uint32 augment_index; // Seen 0
/*24*/ ItemSlotStruct augment_slot; // Slot of the distiller to use (if one applies)
/*36*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug
/*36*/ //int32 augment_slot;
/*40*/
+20 -9
View File
@@ -125,19 +125,22 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
{
iter_queue it;
int i;
bool ret=true;
iter_queue it;
int i;
bool ret = true;
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
// Delete cursor items
if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid=%i AND ( (slotid >=8000 and slotid<=8999) or slotid=%i or (slotid>=%i and slotid<=%i))", char_id, MainCursor,EmuConstants::CURSOR_BAG_BEGIN,EmuConstants::CURSOR_BAG_END), errbuf))) {
for(it=start,i=8000;it!=end;++it,i++) {
ItemInst *inst=*it;
if (!(ret=SaveInventory(char_id,inst,(i==8000) ? MainCursor : i)))
if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid = %i AND ((slotid >= 8000 AND slotid <= 8999) OR slotid = %i OR (slotid >= %i AND slotid <= %i))",
char_id, MainCursor, EmuConstants::CURSOR_BAG_BEGIN, EmuConstants::CURSOR_BAG_END), errbuf))) {
for (it = start, i = 8000; it != end; ++it, i++) {
ItemInst *inst = *it;
if (!(ret = SaveInventory(char_id, inst, (i == 8000) ? MainCursor : i)))
break;
}
} else {
}
else {
std::cout << "Clearing cursor failed: " << errbuf << std::endl;
}
safe_delete_array(query);
@@ -1506,6 +1509,13 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
int tempid = 0;
int counter = 0;
if(result && mysql_field_count(getMySQL()) <= SPELL_LOAD_FIELD_COUNT) {
_log(SPELLS__LOAD_ERR, "Fatal error loading spells: Spell field count < SPELL_LOAD_FIELD_COUNT(%u)", SPELL_LOAD_FIELD_COUNT);
mysql_free_result(result);
return;
}
while (row = mysql_fetch_row(result)) {
tempid = atoi(row[0]);
if(tempid >= max_spells) {
@@ -2027,7 +2037,8 @@ void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Str
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)) {
std::string msg = EscapeString(message->text);
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", msg.c_str(), botid), errbuf)) {
std::cerr << "Error in SetBotInspectMessage query '" << query << "' " << errbuf << std::endl;
}
+2
View File
@@ -621,6 +621,8 @@ typedef enum {
// number. note that the id field is counted as 0, this way the numbers
// here match the numbers given to sep in the loading function net.cpp
//
#define SPELL_LOAD_FIELD_COUNT 231
struct SPDat_Spell_Struct
{
/* 000 */ int id; // not used