diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index d902bc98e..0bbbaa3fd 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -175,14 +175,14 @@ void ImportSkillCaps(SharedDatabase *db) { continue; } - std::string sql; + int class_id, skill_id, level, cap; class_id = atoi(split[0].c_str()); skill_id = atoi(split[1].c_str()); level = atoi(split[2].c_str()); cap = atoi(split[3].c_str()); - StringFormat(sql, "INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)", + std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)", class_id, skill_id, level, cap); db->RunQuery(sql.c_str(), (uint32)sql.length()); @@ -226,7 +226,7 @@ void ImportBaseData(SharedDatabase *db) { mana_fac = atof(split[8].c_str()); end_fac = atof(split[9].c_str()); - StringFormat(sql, "INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, " + sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, " "mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)", level, class_id, hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac); diff --git a/common/Item.cpp b/common/Item.cpp index 3bdd33866..ff02d1574 100644 --- a/common/Item.cpp +++ b/common/Item.cpp @@ -916,8 +916,7 @@ void Inventory::dumpItemCollection(const std::map &collection) if (!inst || !inst->GetItem()) continue; - std::string slot; - StringFormat(slot, "Slot %d: %s (%d)", it->first, it->second->GetItem()->Name, (inst->GetCharges() <= 0) ? 1 : inst->GetCharges()); + std::string slot = StringFormat("Slot %d: %s (%d)", it->first, it->second->GetItem()->Name, (inst->GetCharges() <= 0) ? 1 : inst->GetCharges()); std::cout << slot << std::endl; dumpBagContents(inst, &it); @@ -936,8 +935,7 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) { if (!baginst || !baginst->GetItem()) continue; - std::string subSlot; - StringFormat(subSlot, " Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first), + std::string subSlot = StringFormat(" Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first), baginst->GetItem()->Name, (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges()); std::cout << subSlot << std::endl; } diff --git a/common/MySQLRequestResult.cpp b/common/MySQLRequestResult.cpp index 56e62ae37..f364bf9b2 100644 --- a/common/MySQLRequestResult.cpp +++ b/common/MySQLRequestResult.cpp @@ -10,35 +10,24 @@ MySQLRequestResult::MySQLRequestResult() MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, uint32 rowCount, uint32 columnCount, uint32 lastInsertedID, uint32 errorNumber, char *errorBuffer) : m_CurrentRow(result), m_OneBeyondRow() { - if (errorBuffer != nullptr) - m_Success = false; - else if (errorBuffer == nullptr && result == nullptr) - { - m_Success = false; - -#ifdef _EQDEBUG - std::cout << "DB Query Error: No Result" << std::endl; -#endif - m_ErrorNumber = UINT_MAX; - m_ErrorBuffer = new char[MYSQL_ERRMSG_SIZE]; - - strcpy(m_ErrorBuffer, "DBcore::RunQuery: No Result"); - } - else - m_Success = true; - - m_Result = result; - m_ErrorBuffer = errorBuffer; + m_Result = result; m_RowsAffected = rowsAffected; m_RowCount = rowCount; m_ColumnCount = columnCount; - // If we actually need the column length / fields it will be - // requested at that time, no need to pull it in just to cache it. - // Normal usage would have it as nullptr most likely anyways. - m_ColumnLengths = nullptr; - m_Fields = nullptr; m_LastInsertedID = lastInsertedID; - m_ErrorNumber = errorNumber; + + // If we actually need the column length / fields it will be + // requested at that time, no need to pull it in just to cache it. + // Normal usage would have it as nullptr most likely anyways. + m_ColumnLengths = nullptr; + m_Fields = nullptr; + + if (errorBuffer != nullptr) + m_Success = false; + + m_Success = true; + m_ErrorNumber = errorNumber; + m_ErrorBuffer = errorBuffer; } void MySQLRequestResult::FreeInternals() @@ -113,7 +102,7 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem) m_ColumnLengths = moveItem.m_ColumnLengths; m_Fields = moveItem.m_Fields; - // Keeps deconstructor from double freeing + // Keeps deconstructor from double freeing // pre move instance. moveItem.ZeroOut(); } @@ -140,8 +129,8 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other) m_ColumnLengths = other.m_ColumnLengths; m_Fields = other.m_Fields; - // Keeps deconstructor from double freeing + // Keeps deconstructor from double freeing // pre move instance. other.ZeroOut(); return *this; -} \ No newline at end of file +} diff --git a/common/MySQLRequestRow.cpp b/common/MySQLRequestRow.cpp index 46bdaffd9..f8c2b4c06 100644 --- a/common/MySQLRequestRow.cpp +++ b/common/MySQLRequestRow.cpp @@ -1,6 +1,6 @@ #include "MySQLRequestRow.h" -MySQLRequestRow::MySQLRequestRow(const MySQLRequestRow& row) +MySQLRequestRow::MySQLRequestRow(const MySQLRequestRow& row) : m_Result(row.m_Result), m_MySQLRow(row.m_MySQLRow) { } @@ -26,13 +26,17 @@ MySQLRequestRow& MySQLRequestRow::operator=(MySQLRequestRow& moveItem) moveItem.m_Result = nullptr; moveItem.m_MySQLRow = nullptr; - + return *this; } MySQLRequestRow::MySQLRequestRow(MYSQL_RES *result) - : m_Result(result), m_MySQLRow(mysql_fetch_row(m_Result)) + : m_Result(result) { + if (result != nullptr) + m_MySQLRow = mysql_fetch_row(result); + else + m_MySQLRow = nullptr; } MySQLRequestRow& MySQLRequestRow::operator++() @@ -41,19 +45,19 @@ MySQLRequestRow& MySQLRequestRow::operator++() return *this; } -MySQLRequestRow MySQLRequestRow::operator++(int) +MySQLRequestRow MySQLRequestRow::operator++(int) { - MySQLRequestRow tmp(*this); - operator++(); + MySQLRequestRow tmp(*this); + operator++(); return tmp; } -bool MySQLRequestRow::operator==(const MySQLRequestRow& rhs) +bool MySQLRequestRow::operator==(const MySQLRequestRow& rhs) { return m_MySQLRow == rhs.m_MySQLRow; } -bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs) +bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs) { return m_MySQLRow != rhs.m_MySQLRow; } diff --git a/common/StringUtil.cpp b/common/StringUtil.cpp index 71bb961e1..80c92fa88 100644 --- a/common/StringUtil.cpp +++ b/common/StringUtil.cpp @@ -38,8 +38,9 @@ // original source: // https://github.com/facebook/folly/blob/master/folly/String.cpp // -void vStringFormat(std::string& output, const char* format, va_list args) +const std::string vStringFormat(const char* format, va_list args) { + std::string output; va_list tmpargs; va_copy(tmpargs,args); @@ -48,11 +49,8 @@ void vStringFormat(std::string& output, const char* format, va_list args) if (characters_used < 0) { // Looks like we have an invalid format string. - // error out. - std::string errorMessage("Invalid format string; snprintf returned negative with format string: "); - errorMessage.append(format); - - throw std::runtime_error(errorMessage); + // return empty string. + return ""; } else if ((unsigned int)characters_used > output.capacity()) { output.resize(characters_used+1); @@ -62,12 +60,10 @@ void vStringFormat(std::string& output, const char* format, va_list args) if (characters_used < 0) { // We shouldn't have a format error by this point, but I can't imagine what error we - // could have by this point. Still, error out and report it. - std::string errorMessage("Invalid format string or unknown vsnprintf error; vsnprintf returned negative with format string: "); - errorMessage.append(format); - - throw std::runtime_error(errorMessage); + // could have by this point. Still, return empty string; + return ""; } + return std::move(output); } else { output.resize(characters_used + 1); @@ -78,24 +74,23 @@ void vStringFormat(std::string& output, const char* format, va_list args) if (characters_used < 0) { // We shouldn't have a format error by this point, but I can't imagine what error we - // could have by this point. still error out and report it. - std::string errorMessage("Invalid format string or unknown vsnprintf error; vsnprintf returned negative with format string: "); - errorMessage.append(format); - - throw std::runtime_error(errorMessage); + // could have by this point. Still, return empty string; + return ""; } - + return std::move(output); } } -void StringFormat(std::string& output, const char* format, ...) +const std::string StringFormat(const char* format, ...) { va_list args; va_start(args, format); - vStringFormat(output,format,args); + std::string output = vStringFormat(format,args); va_end(args); + return std::move(output); } + // normal strncpy doesnt put a null term on copied strings, this one does // ref: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecrt/htm/_wcecrt_strncpy_wcsncpy.asp char* strn0cpy(char* dest, const char* source, uint32 size) { @@ -384,3 +379,15 @@ std::string EscapeString(const std::string &s) { return ret; } + +bool isAlphaNumeric(const char *text) +{ + for (unsigned int charIndex=0; charIndex 'z') && + (text[charIndex] < 'A' || text[charIndex] > 'Z') && + (text[charIndex] < '0' || text[charIndex] > '9')) + return false; + } + + return true; +} \ No newline at end of file diff --git a/common/StringUtil.h b/common/StringUtil.h index 46ff43183..fe7e83edf 100644 --- a/common/StringUtil.h +++ b/common/StringUtil.h @@ -19,11 +19,12 @@ #include #include #include +#include #include "types.h" -void vStringFormat(std::string& output, const char* format, va_list args); -void StringFormat(std::string& output, const char* format, ...); +const std::string vStringFormat(const char* format, va_list args); +const std::string StringFormat(const char* format, ...); std::string EscapeString(const std::string &s); const char *MakeLowerString(const char *source); @@ -51,4 +52,6 @@ char *RemoveApostrophes(const char *s); std::vector SplitString(const std::string &s, char delim); +bool isAlphaNumeric(const char *text); + #endif diff --git a/common/database.cpp b/common/database.cpp index 6fdf6b1af..2d5bdbdcc 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -43,15 +43,10 @@ #include "database.h" #include "eq_packet_structs.h" #include "guilds.h" -//#include "MiscFunctions.h" #include "StringUtil.h" #include "extprofile.h" extern Client client; -/* -This is the amount of time in seconds the client has to enter the zone -server after the world server, or inbetween zones when that is finished -*/ /* Establish a connection to a mysql database with the supplied parameters @@ -100,8 +95,6 @@ void Database::DBInitVars() { varcache_lastupdate = 0; } - - void Database::HandleMysqlError(uint32 errnum) { /* switch(errnum) { case 0: @@ -141,276 +134,212 @@ Database::~Database() } } - /* Check if there is an account with name "name" and password "password" Return the account id or zero if no account matches. Zero will also be returned if there is a database error. */ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; if(strlen(name) >= 50 || strlen(password) >= 50) return(0); char tmpUN[100]; char tmpPW[100]; + DoEscapeString(tmpUN, name, strlen(name)); DoEscapeString(tmpPW, password, strlen(password)); - if (RunQuery(query, MakeAnyLenString(&query, - "SELECT id, status FROM account WHERE name='%s' AND password is not null " + std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND password is not null " "and length(password) > 0 and (password='%s' or password=MD5('%s'))", - tmpUN, tmpPW, tmpPW), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - uint32 id = atoi(row[0]); - if (oStatus) - *oStatus = atoi(row[1]); - mysql_free_result(result); - return id; - } - else - { - mysql_free_result(result); - return 0; - } - mysql_free_result(result); - } - else + tmpUN, tmpPW, tmpPW); + auto results = QueryDatabase(query); + + if (!results.Success()) { - std::cerr << "Error in CheckLogin query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; + std::cerr << "Error in CheckLogin query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - return 0; + auto row = results.begin(); + + uint32 id = atoi(row[0]); + + if (oStatus) + *oStatus = atoi(row[1]); + + return id; } - -//Lieka: Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table. +//Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table. bool Database::CheckBannedIPs(const char* loginIP) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - //std::cout << "Checking against Banned IPs table."<< std::endl; //Lieka: Debugging - if (RunQuery(query, MakeAnyLenString(&query, "SELECT ip_address FROM Banned_IPs WHERE ip_address='%s'", loginIP), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) - { - //std::cout << loginIP << " was present in the banned IPs table" << std::endl; //Lieka: Debugging - mysql_free_result(result); - return true; - } - else - { - //std::cout << loginIP << " was not present in the banned IPs table." << std::endl; //Lieka: Debugging - mysql_free_result(result); - return false; - } - mysql_free_result(result); - } - else + std::string query = StringFormat("SELECT ip_address FROM Banned_IPs WHERE ip_address='%s'", loginIP); + + auto results = QueryDatabase(query); + + if (!results.Success()) { - std::cerr << "Error in CheckBannedIPs query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::cerr << "Error in CheckBannedIPs query '" << query << "' " << results.ErrorMessage() << std::endl; return true; } - return true; + + if (results.RowCount() != 0) + return true; + + return false; } bool Database::AddBannedIP(char* bannedIP, const char* notes) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes); - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes), errbuf)) { - std::cerr << "Error in ReserveName query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in ReserveName query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); + return true; } - //End Lieka Edit bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - mysql_free_result(result); - return true; - } else { - mysql_free_result(result); - return false; - } - mysql_free_result(result); + std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id); - } else { - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) return false; - } + + if (results.RowCount() == 1) + return true; return false; } bool Database::AddGMIP(char* ip_address, char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name); - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name), errbuf)) { - safe_delete_array(query); - return false; - } - safe_delete_array(query); - return true; + auto results = QueryDatabase(query); + + return results.Success(); } void Database::LoginIP(uint32 AccountID, const char* LoginIP) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP); - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP), errbuf)) { - std::cerr << "Error in Log IP query '" << query << "' " << errbuf << std::endl; - } - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) + std::cerr << "Error in Log IP query '" << query << "' " << results.ErrorMessage() << std::endl; } int16 Database::CheckStatus(uint32 account_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`" + " FROM `account` WHERE `id` = %i", account_id); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`" - " FROM `account` WHERE `id` = %i", account_id), errbuf, &result)) + auto results = QueryDatabase(query); + + if (!results.Success()) { - safe_delete_array(query); - - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - - int16 status = atoi(row[0]); - - int32 suspendeduntil = 0; - // MariaDB initalizes with NULL if unix_timestamp() is out of range - if (row[1] != NULL) { - suspendeduntil = atoi(row[1]); - } - - int32 current = atoi(row[2]); - - mysql_free_result(result); - - if(suspendeduntil > current) - return -1; - - return status; - } - else - { - mysql_free_result(result); - return 0; - } - mysql_free_result(result); - } - else - { - std::cerr << "Error in CheckStatus query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; + std::cerr << "Error in CheckStatus query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - return 0; + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + int16 status = atoi(row[0]); + + int32 suspendeduntil = 0; + + // MariaDB initalizes with NULL if unix_timestamp() is out of range + if (row[1] != nullptr) { + suspendeduntil = atoi(row[1]); + } + + int32 current = atoi(row[2]); + + if(suspendeduntil > current) + return -1; + + return status; } uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 querylen; - uint32 last_insert_id; + std::string query; if (password) - querylen = MakeAnyLenString(&query, "INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id); + query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id); else - querylen = MakeAnyLenString(&query, "INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id); + query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id); std::cerr << "Account Attempting to be created:" << name << " " << (int16) status << std::endl; - if (!RunQuery(query, querylen, errbuf, 0, 0, &last_insert_id)) { - std::cerr << "Error in CreateAccount query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return 0; - } - safe_delete_array(query); - if (last_insert_id == 0) { - std::cerr << "Error in CreateAccount query '" << query << "' " << errbuf << std::endl; + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in CreateAccount query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } - return last_insert_id; + if (results.LastInsertedID() == 0) + { + std::cerr << "Error in CreateAccount query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; + } + + return results.LastInsertedID(); } bool Database::DeleteAccount(const char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; + std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name); - std::cerr << "Account Attempting to be deleted:" << name << std::endl; - if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM account WHERE name='%s';",name), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - if (affected_rows == 1) { - return true; - } - } - else { + std::cout << "Account Attempting to be deleted:" << name << std::endl; - std::cerr << "Error in DeleteAccount query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - } + auto results = QueryDatabase(query); - return false; -} - -bool Database::SetLocalPassword(uint32 accid, const char* password) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE account SET password=MD5('%s') where id=%i;", password, accid), errbuf)) { - std::cerr << "Error in SetLocalPassword query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + if (!results.Success()) + { + std::cerr << "Error in DeleteAccount query '" << query << "' " << results.ErrorMessage() << std::endl; + return false; + } + + return results.RowsAffected() == 1; +} + +bool Database::SetLocalPassword(uint32 accid, const char* password) { + std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", password, accid); + + auto results = QueryDatabase(query); + + if (!results.Success()) { + std::cerr << "Error in SetLocalPassword query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); return true; } bool Database::SetAccountStatus(const char* name, int16 status) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; + std::string query = StringFormat("UPDATE account SET status=%i WHERE name='%s';", status, name); std::cout << "Account being GM Flagged:" << name << ", Level: " << (int16) status << std::endl; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE account SET status=%i WHERE name='%s';", status, name), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - return false; - } - safe_delete_array(query); - if (affected_rows == 0) { + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowsAffected() == 0) + { std::cout << "Account: " << name << " does not exist, therefore it cannot be flagged\n"; return false; } @@ -420,15 +349,16 @@ bool Database::SetAccountStatus(const char* name, int16 status) { bool Database::ReserveName(uint32 account_id, char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("INSERT into character_ SET account_id=%i, name='%s', profile=NULL", account_id, name); - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT into character_ SET account_id=%i, name='%s', profile=NULL", account_id, name), errbuf)) { - std::cerr << "Error in ReserveName query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in ReserveName query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); + return true; } @@ -438,318 +368,202 @@ returns false on failure, true otherwise */ bool Database::DeleteCharacter(char *name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query=0; - MYSQL_RES *result; - MYSQL_ROW row; - int charid, matches; - uint32 affected_rows; + std::string query=StringFormat("SELECT id from character_ WHERE name='%s'", name); + int charid; if(!name || !strlen(name)) { - printf("DeleteCharacter: request to delete without a name (empty char slot)\n"); + std::cerr << "DeleteCharacter: request to delete without a name (empty char slot)" << std::endl; return false; } // get id from character_ before deleting record so we can clean up inventory and qglobal #if DEBUG >= 5 - printf("DeleteCharacter: Attempting to delete '%s'\n", name); + std::cout << "DeleteCharacter: Attempting to delete '" << name << "'" << std::endl; #endif - RunQuery(query, MakeAnyLenString(&query, "SELECT id from character_ WHERE name='%s'", name), errbuf, &result); - if (query) + + auto results = QueryDatabase(query); + + if(results.RowCount() != 1) { - safe_delete_array(query); - query = nullptr; - } - matches = mysql_num_rows(result); - if(matches == 1) - { - row = mysql_fetch_row(result); - charid = atoi(row[0]); -#if DEBUG >= 5 - printf("DeleteCharacter: found '%s' with char id: %d\n", name, charid); -#endif - } - else - { - printf("DeleteCharacter: error: got %d rows matching '%s'\n", matches, name); - if(result) - { - mysql_free_result(result); - result = nullptr; - } + std::cerr << "DeleteCharacter error: got " << results.RowCount() << " rows matching '" << name << "'" << std::endl; return false; } - if(result) - { - mysql_free_result(result); - result = nullptr; - } - - + auto row = results.begin(); + charid = atoi(row[0]); #if DEBUG >= 5 - printf("DeleteCharacter: deleting '%s' (id %d): ", name, charid); - printf(" quest_globals"); + std::cout << "DeleteCharacter: found '" << name << "' with char id: " << charid << std::endl; + std::cout << "DeleteCharacter: deleting << '" << name << "' (id " << charid << "): " << std::endl; + std::cout << " quest_globals"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from quest_globals WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from quest_globals WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" character_tasks"); + std::cout << " character_tasks"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from character_tasks WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from character_tasks WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" character_activities"); + std::cout << " character_activities"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from character_activities WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from character_activities WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" character_enabledtasks"); + std::cout << " character_enabledtasks"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from character_enabledtasks WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from character_enabledtasks WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" completed_tasks"); + std::cout << " completed_tasks"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from completed_tasks WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from completed_tasks WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" friends"); + std::cout << " friends"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from friends WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from friends WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" mail"); + std::cout << " mail"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from mail WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat( "DELETE from mail WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" ptimers"); + std::cout << " ptimers"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from timers WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from timers WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" inventory"); + std::cout << " inventory"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from inventory WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE from inventory WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" guild_members"); + std::cout << " guild_members"; #endif + #ifdef BOTS - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM guild_members WHERE char_id='%d' AND GetMobTypeById(%i) = 'C'", charid), errbuf, nullptr, &affected_rows); + query = StringFormat("DELETE FROM guild_members WHERE char_id='%d' AND GetMobTypeById(%i) = 'C'", charid); #else - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM guild_members WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); + query = StringFormat("DELETE FROM guild_members WHERE char_id='%d'", charid); #endif - if(query) - { - safe_delete_array(query); - query = nullptr; - } + QueryDatabase(query); #if DEBUG >= 5 - printf(" recipes"); + std::cout << " recipes"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM char_recipe_list WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM char_recipe_list WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" adventure_stats"); + std::cout << " adventure_stats"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM adventure_stats WHERE player_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM adventure_stats WHERE player_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" zone_flags"); + std::cout << " zone_flags"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM zone_flags WHERE charID='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM zone_flags WHERE charID='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" titles"); + std::cout << " titles"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM titles WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM titles WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" titlesets"); + std::cout << " titlesets"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM player_titlesets WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM player_titlesets WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" keyring"); + std::cout << " keyring"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM keyring WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM keyring WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" factions"); + std::cout << " factions"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM faction_values WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM faction_values WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" instances"); + std::cout << " instances"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM instance_list_player WHERE charid='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM instance_list_player WHERE charid='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf(" _character"); + std::cout << " _character"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE from character_ WHERE id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) + + query = StringFormat("DELETE from character_ WHERE id='%d'", charid); + results = QueryDatabase(query); + + if(results.RowsAffected() != 1) // here we have to have a match or it's an error { - safe_delete_array(query); - query = nullptr; - } - if(affected_rows != 1) // here we have to have a match or it's an error - { - LogFile->write(EQEMuLog::Error, "DeleteCharacter: error: delete operation affected %d rows\n", affected_rows); + LogFile->write(EQEMuLog::Error, "DeleteCharacter: error: delete operation affected %d rows\n", results.RowsAffected()); return false; } #if DEBUG >= 5 - printf(" alternate currency"); + std::cout << " alternate currency"; #endif - RunQuery(query, MakeAnyLenString(&query, "DELETE FROM character_alt_currency WHERE char_id='%d'", charid), errbuf, nullptr, &affected_rows); - if(query) - { - safe_delete_array(query); - query = nullptr; - } + + query = StringFormat("DELETE FROM character_alt_currency WHERE char_id='%d'", charid); + QueryDatabase(query); #if DEBUG >= 5 - printf("\n"); + std::cout << std::endl; #endif - printf("DeleteCharacter: successfully deleted '%s' (id %d)\n", name, charid); + std::cout << "DeleteCharacter: successfully deleted '" << name << "' (id " << charid << ")" << std::endl; return true; } -// Store new character information into the character_ and inventory tables (this won't store starting augments) + +// Store new character information into the character_ and inventory tables bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext) { - char errbuf[MYSQL_ERRMSG_SIZE]; char query[256+sizeof(PlayerProfile_Struct)*2+sizeof(ExtendedProfile_Struct)*2+5]; char* end = query; - uint32 affected_rows = 0; - int i; uint32 charid = 0; - char* charidquery = 0; - char* invquery = 0; - MYSQL_RES *result; - MYSQL_ROW row = 0; char zone[50]; float x, y, z; -// memset(&playeraa, 0, sizeof(playeraa)); - - // get the char id (used in inventory inserts below) - if(!RunQuery - ( - charidquery, - MakeAnyLenString - ( - &charidquery, - "SELECT id FROM character_ where name='%s'", - pp->name - ), - errbuf, - &result - )) { - safe_delete_array(charidquery); - LogFile->write(EQEMuLog::Error, "Error in char store id query: %s: %s", charidquery, errbuf); - return(false); - } - safe_delete_array(charidquery); - - if(mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - if(row[0]) - charid = atoi(row[0]); - } + charid = GetCharacterID(pp->name); if(!charid) { @@ -764,6 +578,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven pp->zone_id = 1; } else strn0cpy(zone, zname, 49); + x=pp->x; y=pp->y; z=pp->z; @@ -779,46 +594,32 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven end += DoEscapeString(end, (char*)ext, sizeof(ExtendedProfile_Struct)); end += sprintf(end, "\' WHERE account_id=%d AND name='%s'",account_id, pp->name); - RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows); + auto results = QueryDatabase(query, (uint32) (end - query)); + // stack assigned query, no need to delete it. - if(!affected_rows) + if(!results.RowsAffected()) { - LogFile->write(EQEMuLog::Error, "StoreCharacter query '%s' %s", query, errbuf); + LogFile->write(EQEMuLog::Error, "StoreCharacter query '%s' %s", query, results.ErrorMessage().c_str()); return false; } - affected_rows = 0; - - - // Doodman: Is this even used? // now the inventory - - for (i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::BANK_BAGS_END;) + std::string invquery; + for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;) { - const ItemInst* newinv = inv->GetItem((int16)i); - if (newinv) + const ItemInst* newinv = inv->GetItem(i); + if (!newinv) { - MakeAnyLenString - ( - &invquery, - "INSERT INTO inventory SET " - "charid=%0u, slotid=%0d, itemid=%0u, charges=%0d, color=%0u", - charid, i, newinv->GetItem()->ID, - newinv->GetCharges(), newinv->GetColor() - ); + invquery = StringFormat("INSERT INTO inventory SET charid=%0u, slotid=%0d, itemid=%0u, charges=%0d, color=%0u", + charid, i, newinv->GetItem()->ID,newinv->GetCharges(), newinv->GetColor()); + auto results = QueryDatabase(invquery); - RunQuery(invquery, strlen(invquery), errbuf, 0, &affected_rows); - if(!affected_rows) - { - LogFile->write(EQEMuLog::Error, "StoreCharacter inventory failed. Query '%s' %s", invquery, errbuf); - } + if (!results.RowsAffected()) + LogFile->write(EQEMuLog::Error, "StoreCharacter inventory failed. Query '%s' %s", invquery.c_str(), results.ErrorMessage().c_str()); #if EQDEBUG >= 9 else - { - LogFile->write(EQEMuLog::Debug, "StoreCharacter inventory succeeded. Query '%s' %s", invquery, errbuf); - } + LogFile->write(EQEMuLog::Debug, "StoreCharacter inventory succeeded. Query '%s'", invquery.c_str()); #endif - safe_delete_array(invquery); } if (i == MainCursor) { @@ -854,220 +655,201 @@ the name "name" or zero if no character with that name was found Zero will also be returned if there is a database error. */ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + std::string query = StringFormat("SELECT account_id, id FROM character_ WHERE name='%s'", charname); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT account_id, id FROM character_ WHERE name='%s'", charname), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - uint32 tmp = atoi(row[0]); // copy to temp var because gotta free the result before exitting this function - if (oCharID) - *oCharID = atoi(row[1]); - mysql_free_result(result); - return tmp; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetAccountIDByChar query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in GetAccountIDByChar query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - return 0; + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + uint32 accountId = atoi(row[0]); + + if (oCharID) + *oCharID = atoi(row[1]); + + return accountId; } // Retrieve account_id for a given char_id uint32 Database::GetAccountIDByChar(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 ret = 0; + std::string query = StringFormat("SELECT account_id FROM character_ WHERE id=%i", char_id); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT account_id FROM character_ WHERE id=%i", char_id), errbuf, &result)) { - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - ret = atoi(row[0]); // copy to temp var because gotta free the result before exitting this function - } - mysql_free_result(result); - } - else { - LogFile->write(EQEMuLog::Error, "Error in GetAccountIDByChar query '%s': %s", query, errbuf); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + LogFile->write(EQEMuLog::Error, "Error in GetAccountIDByChar query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return 0; } - safe_delete_array(query); - return ret; + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); } uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + if (!isAlphaNumeric(accname)) + return 0; + std::string query = StringFormat("SELECT id, status, lsaccount_id FROM account WHERE name='%s'", accname); + auto results = QueryDatabase(query); - for (unsigned int i=0; i 'z') && - (accname[i] < 'A' || accname[i] > 'Z') && - (accname[i] < '0' || accname[i] > '9')) - return 0; + if (!results.Success()) + { + std::cerr << "Error in GetAccountIDByAcc query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, status, lsaccount_id FROM account WHERE name='%s'", accname), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - uint32 tmp = atoi(row[0]); // copy to temp var because gotta free the result before exitting this function - if (status) - *status = atoi(row[1]); - if (lsid) { - if (row[2]) - *lsid = atoi(row[2]); - else - *lsid = 0; - } - mysql_free_result(result); - return tmp; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetAccountIDByAcc query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + uint32 id = atoi(row[0]); + + if (status) + *status = atoi(row[1]); + + if (lsid) + { + if (row[2]) + *lsid = atoi(row[2]); + else + *lsid = 0; } - return 0; + return id; } void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + std::string query = StringFormat("SELECT name, lsaccount_id FROM account WHERE id='%i'", accountid); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT name, lsaccount_id FROM account WHERE id='%i'", accountid), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); + auto results = QueryDatabase(query); - strcpy(name, row[0]); - if (row[1] && oLSAccountID) { - *oLSAccountID = atoi(row[1]); - } - } - - mysql_free_result(result); + if (!results.Success()) + { + std::cerr << "Error in GetAccountName query '" << query << "' " << results.ErrorMessage() << std::endl; + return; } - else { - safe_delete_array(query); - std::cerr << "Error in GetAccountName query '" << query << "' " << errbuf << std::endl; + + if (results.RowCount() != 1) + return; + + auto row = results.begin(); + + strcpy(name, row[0]); + if (row[1] && oLSAccountID) { + *oLSAccountID = atoi(row[1]); } + } void Database::GetCharName(uint32 char_id, char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT name FROM character_ WHERE id='%i'", char_id); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT name FROM character_ WHERE id='%i'", char_id), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - - strcpy(name, row[0]); - } - - mysql_free_result(result); - } - else { - safe_delete_array(query); - std::cerr << "Error in GetCharName query '" << query << "' " << errbuf << std::endl; + if (!results.Success()) + { + std::cerr << "Error in GetCharName query '" << query << "' " << results.ErrorMessage() << std::endl; + return; } + auto row = results.begin(); + strcpy(name, row[0]); } bool Database::LoadVariables() { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; + char *query = nullptr; - if (RunQuery(query, LoadVariables_MQ(&query), errbuf, &result)) { + auto results = QueryDatabase(query, LoadVariables_MQ(&query)); + + if (!results.Success()) + { + std::cerr << "Error in LoadVariables query '" << query << "' " << results.ErrorMessage() << std::endl; safe_delete_array(query); - bool ret = LoadVariables_result(result); - mysql_free_result(result); - return ret; + return false; } - else { - std::cerr << "Error in LoadVariables query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - } - return false; + + safe_delete_array(query); + return LoadVariables_result(std::move(results)); } -uint32 Database::LoadVariables_MQ(char** query) { -// the read of this single variable should be atomic... this was causing strange problems -// LockMutex lock(&Mvarcache); +uint32 Database::LoadVariables_MQ(char** query) +{ return MakeAnyLenString(query, "SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache_lastupdate); } -bool Database::LoadVariables_result(MYSQL_RES* result) { - uint32 i; - MYSQL_ROW row; +// always returns true? not sure about this. +bool Database::LoadVariables_result(MySQLRequestResult results) { + uint32 i = 0; LockMutex lock(&Mvarcache); - if (mysql_num_rows(result) > 0) { - if (!varcache_array) { - varcache_max = mysql_num_rows(result); - varcache_array = new VarCache_Struct*[varcache_max]; - for (i=0; ivarname, row[0]) == 0) { - delete varcache_array[i]; - varcache_array[i] = (VarCache_Struct*) new uint8[sizeof(VarCache_Struct) + strlen(row[1]) + 1]; - strn0cpy(varcache_array[i]->varname, row[0], sizeof(varcache_array[i]->varname)); - strcpy(varcache_array[i]->value, row[1]); - break; - } - } - else { + + if (results.RowCount() == 0) + return true; + + if (!varcache_array) { + varcache_max = results.RowCount(); + varcache_array = new VarCache_Struct*[varcache_max]; + for (i=0; ivarname, row[0]) == 0) { + delete varcache_array[i]; varcache_array[i] = (VarCache_Struct*) new uint8[sizeof(VarCache_Struct) + strlen(row[1]) + 1]; - strcpy(varcache_array[i]->varname, row[0]); + strn0cpy(varcache_array[i]->varname, row[0], sizeof(varcache_array[i]->varname)); strcpy(varcache_array[i]->value, row[1]); break; } } - } - uint32 max_used = 0; - for (i=0; i max_used) - max_used = i; + else { + varcache_array[i] = (VarCache_Struct*) new uint8[sizeof(VarCache_Struct) + strlen(row[1]) + 1]; + strcpy(varcache_array[i]->varname, row[0]); + strcpy(varcache_array[i]->value, row[1]); + break; } } - max_used++; - varcache_max = max_used; } + + uint32 max_used = 0; + for (i=0; i max_used) + max_used = i; + } + } + + varcache_max = max_used + 1; + return true; } @@ -1094,10 +876,7 @@ bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_ } bool Database::SetVariable(const char* varname_in, const char* varvalue_in) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - + char *varname,*varvalue; varname=(char *)malloc(strlen(varname_in)*2+1); @@ -1105,291 +884,244 @@ bool Database::SetVariable(const char* varname_in, const char* varvalue_in) { DoEscapeString(varname, varname_in, strlen(varname_in)); DoEscapeString(varvalue, varvalue_in, strlen(varvalue_in)); - if (RunQuery(query, MakeAnyLenString(&query, "Update variables set value='%s' WHERE varname like '%s'", varvalue, varname), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - if (affected_rows == 1) { - LoadVariables(); // refresh cache - free(varname); - free(varvalue); - return true; - } - else { - if (RunQuery(query, MakeAnyLenString(&query, "Insert Into variables (varname, value) values ('%s', '%s')", varname, varvalue), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - if (affected_rows == 1) { - LoadVariables(); // refresh cache - free(varname); - free(varvalue); - return true; - } - } - } + std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", varvalue, varname); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in SetVariable query '" << query << "' " << results.ErrorMessage() << std::endl; + free(varname); + free(varvalue); + return false; } - else { - std::cerr << "Error in SetVariable query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + + if (results.RowsAffected() == 1) + { + LoadVariables(); // refresh cache + free(varname); + free(varvalue); + return true; } + + query = StringFormat("Insert Into variables (varname, value) values ('%s', '%s')", varname, varvalue); + results = QueryDatabase(query); free(varname); free(varvalue); - return false; + + if (results.RowsAffected() != 1) + return false; + + LoadVariables(); // refresh cache + return true; } uint32 Database::GetMiniLoginAccount(char* ip){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 retid = 0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM account WHERE minilogin_ip='%s'", ip), errbuf, &result)) { - safe_delete_array(query); - if ((row = mysql_fetch_row(result))) - retid = atoi(row[0]); - mysql_free_result(result); - } - else + + std::string query = StringFormat("SELECT id FROM account WHERE minilogin_ip='%s'", ip); + auto results = QueryDatabase(query); + + if (!results.Success()) { - std::cerr << "Error in GetMiniLoginAccount query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::cerr << "Error in GetMiniLoginAccount query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - return retid; + + auto row = results.begin(); + + return atoi(row[0]); } -// Pyro: Get zone starting points from DB +// Get zone starting points from DB bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - // int buf_len = 256; - // int chars = -1; - MYSQL_RES *result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT safe_x, safe_y, safe_z, min_status, min_level, flag_needed FROM zone " + " WHERE short_name='%s' AND (version=%i OR version=0) ORDER BY version DESC", short_name, version); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, - "SELECT safe_x, safe_y, safe_z, min_status, min_level, " - " flag_needed FROM zone " - " WHERE short_name='%s' AND (version=%i OR version=0) ORDER BY version DESC", short_name, version), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) > 0) { - row = mysql_fetch_row(result); - if (safe_x != 0) - *safe_x = atof(row[0]); - if (safe_y != 0) - *safe_y = atof(row[1]); - if (safe_z != 0) - *safe_z = atof(row[2]); - if (minstatus != 0) - *minstatus = atoi(row[3]); - if (minlevel != 0) - *minlevel = atoi(row[4]); - if (flag_needed != nullptr) - strcpy(flag_needed, row[5]); - mysql_free_result(result); - return true; - } - - mysql_free_result(result); - } - else + if (!results.Success()) { - std::cerr << "Error in GetSafePoint query '" << query << "' " << errbuf << std::endl; + std::cerr << "Error in GetSafePoint query '" << query << "' " << results.ErrorMessage() << std::endl; std::cerr << "If it errors, run the following querys:\n"; std::cerr << "ALTER TABLE `zone` CHANGE `minium_level` `min_level` TINYINT(3) UNSIGNED DEFAULT \"0\" NOT NULL;\n"; std::cerr << "ALTER TABLE `zone` CHANGE `minium_status` `min_status` TINYINT(3) UNSIGNED DEFAULT \"0\" NOT NULL;\n"; std::cerr << "ALTER TABLE `zone` ADD flag_needed VARCHAR(128) NOT NULL DEFAULT '';\n"; - - safe_delete_array(query); - } - return false; -} - - -bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name), errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) > 0) { - row = mysql_fetch_row(result); - if (long_name != 0) { - *long_name = strcpy(new char[strlen(row[0])+1], row[0]); - } - if (file_name != 0) { - if (row[1] == 0) - strcpy(file_name, short_name); - else - strcpy(file_name, row[1]); - } - if (safe_x != 0) - *safe_x = atof(row[2]); - if (safe_y != 0) - *safe_y = atof(row[3]); - if (safe_z != 0) - *safe_z = atof(row[4]); - if (graveyard_id != 0) - *graveyard_id = atoi(row[5]); - if (maxclients) - *maxclients = atoi(row[6]); - mysql_free_result(result); - return true; - } - mysql_free_result(result); - } - else - { - std::cerr << "Error in GetZoneLongName query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); return false; } - return false; -} -uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 GraveyardID = 0; + if (results.RowCount() == 0) + return false; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version), errbuf, &result)) - { - if (mysql_num_rows(result) > 0) { - row = mysql_fetch_row(result); - GraveyardID = atoi(row[0]); - } - mysql_free_result(result); - safe_delete_array(query); - return GraveyardID; + auto row = results.begin(); + + if (safe_x != nullptr) + *safe_x = atof(row[0]); + if (safe_y != nullptr) + *safe_y = atof(row[1]); + if (safe_z != nullptr) + *safe_z = atof(row[2]); + if (minstatus != nullptr) + *minstatus = atoi(row[3]); + if (minlevel != nullptr) + *minlevel = atoi(row[4]); + if (flag_needed != nullptr) + strcpy(flag_needed, row[5]); + + return true; +} + +bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) { + + std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name); + auto results = QueryDatabase(query); + + if (!results.Success()) { + std::cerr << "Error in GetZoneLongName query '" << query << "' " << results.ErrorMessage() << std::endl; + return false; } - else - { - std::cerr << "Error in GetZoneGraveyardID query '" << query << "' " << errbuf << std::endl; + + if (results.RowCount() == 0) + return false; + + auto row = results.begin(); + + if (long_name != nullptr) + *long_name = strcpy(new char[strlen(row[0])+1], row[0]); + + if (file_name != nullptr) { + if (row[1] == nullptr) + strcpy(file_name, short_name); + else + strcpy(file_name, row[1]); } - safe_delete_array(query); - return GraveyardID; + + if (safe_x != nullptr) + *safe_x = atof(row[2]); + if (safe_y != nullptr) + *safe_y = atof(row[3]); + if (safe_z != nullptr) + *safe_z = atof(row[4]); + if (graveyard_id != nullptr) + *graveyard_id = atoi(row[5]); + if (maxclients != nullptr) + *maxclients = atoi(row[6]); + + return true; +} + +uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) { + + std::string query = StringFormat("SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in GetZoneGraveyardID query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; + } + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id), errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - if(graveyard_zoneid != 0) - *graveyard_zoneid = atoi(row[0]); - if(graveyard_x != 0) - *graveyard_x = atof(row[1]); - if(graveyard_y != 0) - *graveyard_y = atof(row[2]); - if(graveyard_z != 0) - *graveyard_z = atof(row[3]); - if(graveyard_heading != 0) - *graveyard_heading = atof(row[4]); - mysql_free_result(result); - return true; - } - mysql_free_result(result); - } - else - { - std::cerr << "Error in GetZoneGraveyard query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + if (!results.Success()){ + std::cerr << "Error in GetZoneGraveyard query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - return false; + if (results.RowCount() != 1) + return false; + + auto row = results.begin(); + + if(graveyard_zoneid != nullptr) + *graveyard_zoneid = atoi(row[0]); + if(graveyard_x != nullptr) + *graveyard_x = atof(row[1]); + if(graveyard_y != nullptr) + *graveyard_y = atof(row[2]); + if(graveyard_z != nullptr) + *graveyard_z = atof(row[3]); + if(graveyard_heading != nullptr) + *graveyard_heading = atof(row[4]); + + return true; } bool Database::LoadZoneNames() { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + std::string query("SELECT zoneidnumber, short_name FROM zone"); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT zoneidnumber, short_name FROM zone"), errbuf, &result)) { - safe_delete_array(query); - while ((row = mysql_fetch_row(result))) { - uint32 zoneid = atoi(row[0]); - std::string zonename = row[1]; - zonename_array.insert(std::pair(zoneid,zonename)); - } - } - else { - std::cerr << "Error in LoadZoneNames query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in LoadZoneNames query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - mysql_free_result(result); + + for (auto row= results.begin();row != results.end();++row) + { + uint32 zoneid = atoi(row[0]); + std::string zonename = row[1]; + zonename_array.insert(std::pair(zoneid,zonename)); + } return true; } uint32 Database::GetZoneID(const char* zonename) { - if (zonename == 0) + + if (zonename == nullptr) return 0; - for (auto iter = zonename_array.begin(); iter != zonename_array.end(); ++iter) { - if (strcasecmp(iter->second.c_str(), zonename) == 0) { + + for (auto iter = zonename_array.begin(); iter != zonename_array.end(); ++iter) + if (strcasecmp(iter->second.c_str(), zonename) == 0) return iter->first; - } - } + return 0; } const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) { auto iter = zonename_array.find(zoneID); - if (iter != zonename_array.end()) { + if (iter != zonename_array.end()) return iter->second.c_str(); - } - else { - if (ErrorUnknown) - return "UNKNOWN"; - else - return 0; - } + + if (ErrorUnknown) + return "UNKNOWN"; + return 0; } uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - int peqzone = 0; + + std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version), errbuf, &result)) + if (!results.Success()) { - if (mysql_num_rows(result) > 0) - { - row = mysql_fetch_row(result); - peqzone = atoi(row[0]); - } - safe_delete_array(query); - mysql_free_result(result); - return peqzone; + std::cerr << "Error in GetPEQZone query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - else - { - std::cerr << "Error in GetPEQZone query '" << query << "' " << errbuf << std::endl; - } - safe_delete_array(query); - return peqzone; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); } bool Database::CheckNameFilter(const char* name, bool surname) { std::string str_name = name; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; if(surname) { @@ -1440,137 +1172,117 @@ bool Database::CheckNameFilter(const char* name, bool surname) } } - if (RunQuery(query, MakeAnyLenString(&query, "SELECT name FROM name_filter"), errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - std::string current_row = row[0]; - for(size_t x = 0; x < current_row.size(); ++x) - { - current_row[x] = tolower(current_row[x]); - } + + std::string query("SELECT name FROM name_filter"); + auto results = QueryDatabase(query); - if(str_name.find(current_row) != std::string::npos) - { - return false; - } - } - - mysql_free_result(result); + if (!results.Success()) + { + std::cerr << "Error in CheckNameFilter query '" << query << "' " << results.ErrorMessage() << std::endl; + // false through to true? shouldn't it be falls through to false? return true; } - else + + for (auto row = results.begin();row != results.end();++row) { - std::cerr << "Error in CheckNameFilter query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string current_row = row[0]; + + for(size_t x = 0; x < current_row.size(); ++x) + current_row[x] = tolower(current_row[x]); + + if(str_name.find(current_row) != std::string::npos) + return false; } return true; } bool Database::AddToNameFilter(const char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; + + std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name); + auto results = QueryDatabase(query); - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO name_filter (name) values ('%s')", name), errbuf, 0, &affected_rows)) { - std::cerr << "Error in AddToNameFilter query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + if (!results.Success()) + { + std::cerr << "Error in AddToNameFilter query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); - - if (affected_rows == 0) { + if (results.RowsAffected() == 0) return false; - } return true; } uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID), errbuf, &result)) + std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID); + auto results = QueryDatabase(query); + + if (!results.Success()) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - uint32 account_id = atoi(row[0]); - if (oAccountName) - strcpy(oAccountName, row[1]); - if (oStatus) - *oStatus = atoi(row[2]); - mysql_free_result(result); - return account_id; - } - else - { - mysql_free_result(result); - return 0; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetAccountIDFromLSID query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::cerr << "Error in GetAccountIDFromLSID query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } - return 0; + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + uint32 account_id = atoi(row[0]); + + if (oAccountName) + strcpy(oAccountName, row[1]); + if (oStatus) + *oStatus = atoi(row[2]); + + return account_id; } void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT name, status FROM account WHERE id=%i", id), errbuf, &result)) + if (!results.Success()) { - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - if (oAccountName) - strcpy(oAccountName, row[0]); - if (oStatus) - *oStatus = atoi(row[1]); - } - mysql_free_result(result); + std::cerr << "Error in GetAccountFromID query '" << query << "' " << results.ErrorMessage() << std::endl; + return; } - else - std::cerr << "Error in GetAccountFromID query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + + if (results.RowCount() != 1) + return; + + auto row = results.begin(); + + if (oAccountName) + strcpy(oAccountName, row[0]); + if (oStatus) + *oStatus = atoi(row[1]); } void Database::ClearMerchantTemp(){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "delete from merchantlist_temp"), errbuf)) { - std::cerr << "Error in ClearMerchantTemp query '" << query << "' " << errbuf << std::endl; - } - safe_delete_array(query); + std::string query("delete from merchantlist_temp"); + auto results = QueryDatabase(query); + + if (!results.Success()) + std::cerr << "Error in ClearMerchantTemp query '" << query << "' " << results.ErrorMessage() << std::endl; } bool Database::UpdateName(const char* oldname, const char* newname) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - + std::cout << "Renaming " << oldname << " to " << newname << "..." << std::endl; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET name='%s' WHERE name='%s';", newname, oldname), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - return false; - } - safe_delete_array(query); - if (affected_rows == 0) - { + std::string query = StringFormat("UPDATE character_ SET name='%s' WHERE name='%s';", newname, oldname); + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowsAffected() == 0) return false; - } return true; } @@ -1578,74 +1290,53 @@ bool Database::UpdateName(const char* oldname, const char* newname) { // If the name is used or an error occurs, it returns false, otherwise it returns true bool Database::CheckUsedName(const char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - //if (strlen(name) > 15) - // return false; - if (!RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM character_ where name='%s'", name), errbuf, &result)) { - std::cerr << "Error in CheckUsedName query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT id FROM character_ where name='%s'", name); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in CheckUsedName query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - else { // It was a valid Query, so lets do our counts! - safe_delete_array(query); - uint32 tmp = mysql_num_rows(result); - mysql_free_result(result); - if (tmp > 0) // There is a Name! No change (Return False) - return false; - else // Everything is okay, so we go and do this. - return true; - } + + if (results.RowCount() > 0) + return false; + + return true; } uint8 Database::GetServerType() { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname='ServerType'"), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - uint8 ServerType = atoi(row[0]); - mysql_free_result(result); - return ServerType; - } - else - { - mysql_free_result(result); - return 0; - } - mysql_free_result(result); - } - else - { - std::cerr << "Error in GetServerType query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - return 0; + std::string query("SELECT value FROM variables WHERE varname='ServerType'"); + auto results = QueryDatabase(query); + if (!results.Success()) + { + std::cerr << "Error in GetServerType query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; + } + + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } bool Database::MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - if(zonename == nullptr || strlen(zonename) == 0) - return(false); + return false; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s',zoneid=%i,x=-1, y=-1, z=-1 WHERE name='%s'", zonename,zoneid, charname), errbuf, 0,&affected_rows)) { - std::cerr << "Error in MoveCharacterToZone(name) query '" << query << "' " << errbuf << std::endl; + std::string query = StringFormat("UPDATE character_ SET zonename = '%s',zoneid=%i,x=-1, y=-1, z=-1 WHERE name='%s'", zonename,zoneid, charname); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in MoveCharacterToZone(name) query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); - if (affected_rows == 0) + if (results.RowsAffected() == 0) return false; return true; @@ -1656,50 +1347,40 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename) { } bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s', zoneid=%i, x=-1, y=-1, z=-1 WHERE id=%i", iZonename, GetZoneID(iZonename), iCharID), errbuf, 0,&affected_rows)) { - std::cerr << "Error in MoveCharacterToZone(id) query '" << query << "' " << errbuf << std::endl; + + std::string query = StringFormat("UPDATE character_ SET zonename = '%s', zoneid=%i, x=-1, y=-1, z=-1 WHERE id=%i", iZonename, GetZoneID(iZonename), iCharID); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in MoveCharacterToZone(id) query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); - if (affected_rows == 0) - return false; - - return true; + return results.RowsAffected() != 0; } uint8 Database::CopyCharacter(const char* oldname, const char* newname, uint32 acctid) { - //TODO: Rewrite better function - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + PlayerProfile_Struct* pp; ExtendedProfile_Struct* ext; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile, extprofile FROM character_ WHERE name='%s'", oldname), errbuf, &result)) { - safe_delete_array(query); + std::string query = StringFormat("SELECT profile, extprofile FROM character_ WHERE name='%s'", oldname); + auto results = QueryDatabase(query); - row = mysql_fetch_row(result); - - pp = (PlayerProfile_Struct*)row[0]; - strcpy(pp->name, newname); - - ext = (ExtendedProfile_Struct*)row[1]; - - mysql_free_result(result); - } - - else { - std::cerr << "Error in CopyCharacter read query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + if (!results.Success()) + { + std::cerr << "Error in CopyCharacter read query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } - uint32 affected_rows = 0; + auto row = results.begin(); + + pp = (PlayerProfile_Struct*)row[0]; + strcpy(pp->name, newname); + + ext = (ExtendedProfile_Struct*)row[1]; + char query2[276 + sizeof(PlayerProfile_Struct)*2 + sizeof(ExtendedProfile_Struct)*2 + 1]; char* end=query2; @@ -1709,105 +1390,86 @@ uint8 Database::CopyCharacter(const char* oldname, const char* newname, uint32 a end += DoEscapeString(end, (char*) ext, sizeof(ExtendedProfile_Struct)); end += sprintf(end, "\', account_id=%d, name='%s'", acctid, newname); - if (!RunQuery(query2, (uint32) (end - query2), errbuf, 0, &affected_rows)) { - std::cerr << "Error in CopyCharacter query '" << query << "' " << errbuf << std::endl; + results = QueryDatabase(query2, (uint32) (end - query2)); + + if (!results.Success()) + { + std::cerr << "Error in CopyCharacter query '" << query2 << "' " << results.ErrorMessage() << std::endl; return 0; } - if (affected_rows == 0) { + if (results.RowsAffected() == 0) return 0; - } return 1; } bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO hackers(account,name,hacked) values('%s','%s','%s')", accountname, charactername, hacked), errbuf, 0,&affected_rows)) { - std::cerr << "Error in SetHackerFlag query '" << query << "' " << errbuf << std::endl; - return false; - } - safe_delete_array(query); + + std::string query = StringFormat("INSERT INTO hackers(account,name,hacked) values('%s','%s','%s')", accountname, charactername, hacked); + auto results = QueryDatabase(query); - if (affected_rows == 0) + if (!results.Success()) { + std::cerr << "Error in SetHackerFlag query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - return true; + return results.RowsAffected() != 0; } -bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) { //Utilize the "hacker" table, but also give zone information. +bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) { + + //Utilize the "hacker" table, but also give zone information. + std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone); + auto results = QueryDatabase(query); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone), errbuf, 0,&affected_rows)) { - std::cerr << "Error in SetMQDetectionFlag query '" << query << "' " << errbuf << std::endl; - return false; - } - - safe_delete_array(query); - - if (affected_rows == 0) + if (!results.Success()) { + std::cerr << "Error in SetMQDetectionFlag query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - return true; + return results.RowsAffected() != 0; } uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race) { uint16 race_cap = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - MYSQL_RES *result; - MYSQL_ROW row; - + //Check for a racial cap! - if (RunQuery(query, MakeAnyLenString(&query, "SELECT skillcap from race_skillcaps where skill = %i && race = %i", skillid, in_race), errbuf, &result, &affected_rows)) - { - if (affected_rows != 0) - { - row = mysql_fetch_row(result); - race_cap = atoi(row[0]); - } - delete[] query; - mysql_free_result(result); - } + std::string query = StringFormat("SELECT skillcap from race_skillcaps where skill = %i && race = %i", skillid, in_race); + auto results = QueryDatabase(query); - return race_cap; + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level) { uint8 skill_level = 0, skill_formula = 0; uint16 base_cap = 0, skill_cap = 0, skill_cap2 = 0, skill_cap3 = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - MYSQL_RES *result; - MYSQL_ROW row; + + //Fetch the data from DB. - if (RunQuery(query, MakeAnyLenString(&query, "SELECT level, formula, pre50cap, post50cap, post60cap from skillcaps where skill = %i && class = %i", skillid, in_class), errbuf, &result, &affected_rows)) + std::string query = StringFormat("SELECT level, formula, pre50cap, post50cap, post60cap from skillcaps where skill = %i && class = %i", skillid, in_class); + auto results = QueryDatabase(query); + + if (results.Success() && results.RowsAffected() != 0) { - if (affected_rows != 0) - { - row = mysql_fetch_row(result); - skill_level = atoi(row[0]); - skill_formula = atoi(row[1]); - skill_cap = atoi(row[2]); - if (atoi(row[3]) > skill_cap) - skill_cap2 = (atoi(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level. - skill_cap3 = atoi(row[4]); - } - delete[] query; - mysql_free_result(result); + auto row = results.begin(); + skill_level = atoi(row[0]); + skill_formula = atoi(row[1]); + skill_cap = atoi(row[2]); + if (atoi(row[3]) > skill_cap) + skill_cap2 = (atoi(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level. + skill_cap3 = atoi(row[4]); } int race_skill = GetRaceSkill(skillid,in_race); @@ -1826,685 +1488,619 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 base_cap = in_level*skill_formula+skill_formula; if (base_cap > skill_cap || skill_formula == 0) base_cap = skill_cap; + //If post 50, add post 50 cap to base cap. if (in_level > 50 && skill_cap2 > 0) base_cap += skill_cap2*(in_level-50); + //No cap should ever go above its post50cap if (skill_cap3 > 0 && base_cap > skill_cap3) base_cap = skill_cap3; + //Base cap is now the max value at the person's level, return it! return base_cap; } uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZoneID, uint32* oInstanceID, float* oX, float* oY, float* oZ) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT id, account_id, zonename, instanceid, x, y, z FROM character_ WHERE name='%s'", iName); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, account_id, zonename, instanceid, x, y, z FROM character_ WHERE name='%s'", iName), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - uint32 charid = atoi(row[0]); - if (oAccID) - *oAccID = atoi(row[1]); - if (oZoneID) - *oZoneID = GetZoneID(row[2]); - if(oInstanceID) - *oInstanceID = atoi(row[3]); - if (oX) - *oX = atof(row[4]); - if (oY) - *oY = atof(row[5]); - if (oZ) - *oZ = atof(row[6]); - mysql_free_result(result); - return charid; - } - mysql_free_result(result); + if (!results.Success()) + { + std::cerr << "Error in GetCharacterInfo query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - else { - std::cerr << "Error in GetCharacterInfo query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - } - return 0; + + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + uint32 charid = atoi(row[0]); + if (oAccID) + *oAccID = atoi(row[1]); + if (oZoneID) + *oZoneID = GetZoneID(row[2]); + if(oInstanceID) + *oInstanceID = atoi(row[3]); + if (oX) + *oX = atof(row[4]); + if (oY) + *oY = atof(row[5]); + if (oZ) + *oZ = atof(row[6]); + + return charid; } bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id), errbuf)) { - std::cerr << "Error in UpdateLiveChar query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + + std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in UpdateLiveChar query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } - safe_delete_array(query); return true; } bool Database::GetLiveChar(uint32 account_id, char* cname) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT charname FROM account WHERE id=%i", account_id), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - strcpy(cname,row[0]); - mysql_free_result(result); - return true; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetLiveChar query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + + std::string query = StringFormat("SELECT charname FROM account WHERE id=%i", account_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in GetLiveChar query '" << query << "' " << results.ErrorMessage() << std::endl; + return false; } - return false; + if (results.RowCount() != 1) + return false; + + auto row = results.begin(); + strcpy(cname,row[0]); + + return true; } void Database::SetLFP(uint32 CharID, bool LFP) { - char ErrBuf[MYSQL_ERRMSG_SIZE]; - char *Query = 0; - - if (!RunQuery(Query, MakeAnyLenString(&Query, "update character_ set lfp=%i where id=%i",LFP, CharID), ErrBuf)) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, ErrBuf); - - safe_delete_array(Query); + std::string query = StringFormat("update character_ set lfp=%i where id=%i",LFP, CharID); + auto results = QueryDatabase(query); + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); } void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) { + + std::string query = StringFormat("update character_ set lfp=%i, lfg=%i, firstlogon=%i where id=%i",LFP, LFG, firstlogon, CharID); + auto results = QueryDatabase(query); - char ErrBuf[MYSQL_ERRMSG_SIZE]; - char *Query = 0; - - if (!RunQuery(Query, MakeAnyLenString(&Query, "update character_ set lfp=%i, lfg=%i, firstlogon=%i where id=%i",LFP, LFG, firstlogon, CharID), ErrBuf)) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, ErrBuf); - - safe_delete_array(Query); - + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); } void Database::SetLFG(uint32 CharID, bool LFG) { - char ErrBuf[MYSQL_ERRMSG_SIZE]; - char *Query = 0; - - if (!RunQuery(Query, MakeAnyLenString(&Query, "update character_ set lfg=%i where id=%i",LFG, CharID), ErrBuf)) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, ErrBuf); - - safe_delete_array(Query); + std::string query = StringFormat("update character_ set lfg=%i where id=%i",LFG, CharID); + auto results = QueryDatabase(query); + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); } void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) { + + std::string query = StringFormat( "update character_ set firstlogon=%i where id=%i",firstlogon, CharID); + auto results = QueryDatabase(query); - char ErrBuf[MYSQL_ERRMSG_SIZE]; - char *Query = 0; - - if (!RunQuery(Query, MakeAnyLenString(&Query, "update character_ set firstlogon=%i where id=%i",firstlogon, CharID), ErrBuf)) - LogFile->write(EQEMuLog::Error, "Error updating firstlogon for character %i : %s", CharID, ErrBuf); - - safe_delete_array(Query); - + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error updating firstlogon for character %i : %s", CharID, results.ErrorMessage().c_str()); } void Database::AddReport(std::string who, std::string against, std::string lines) { - char ErrBuf[MYSQL_ERRMSG_SIZE]; - char *Query = 0; + char *escape_str = new char[lines.size()*2+1]; DoEscapeString(escape_str, lines.c_str(), lines.size()); - if (!RunQuery(Query, MakeAnyLenString(&Query, "INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str), ErrBuf)) - LogFile->write(EQEMuLog::Error, "Error adding a report for %s: %s", who.c_str(), ErrBuf); - - safe_delete_array(Query); + std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str); + auto results = QueryDatabase(query); safe_delete_array(escape_str); + + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error adding a report for %s: %s", who.c_str(), results.ErrorMessage().c_str()); } -void Database::SetGroupID(const char* name,uint32 id, uint32 charid, uint32 ismerc){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if(id == 0){ //removing you from table - if (!RunQuery(query, MakeAnyLenString(&query, "delete from group_id where charid=%i and name='%s' and ismerc=%i",charid, name, ismerc), errbuf)) - LogFile->write(EQEMuLog::Error, "Error deleting character from group id: %s", errbuf); +void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc){ + + std::string query; + if (id == 0) + { + // removing from group + query = StringFormat("delete from group_id where charid=%i and name='%s' and ismerc=%i",charid, name, ismerc); + auto results = QueryDatabase(query); + + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); + + return; } - else{ - if (!RunQuery(query, MakeAnyLenString(&query, "replace into group_id set charid=%i, groupid=%i, name='%s', ismerc='%i'",charid, id, name, ismerc), errbuf)) - LogFile->write(EQEMuLog::Error, "Error adding character to group id: %s", errbuf); - } - safe_delete_array(query); + + // adding to group + query = StringFormat("replace into group_id set charid=%i, groupid=%i, name='%s', ismerc='%i'",charid, id, name, ismerc); + auto results = QueryDatabase(query); + + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error adding character to group id: %s", results.ErrorMessage().c_str()); +} + +void Database::ClearAllGroups(void) +{ + std::string query("delete from group_id"); + auto results = QueryDatabase(query); + + if (!results.Success()) + std::cout << "Unable to clear groups: " << results.ErrorMessage() << std::endl; + + return; } void Database::ClearGroup(uint32 gid) { ClearGroupLeader(gid); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if(gid == 0) { //clear all groups - //if (!RunQuery(query, MakeAnyLenString(&query, "update group_id set groupid=0 where groupid!=0"), errbuf)) - if (!RunQuery(query, MakeAnyLenString(&query, "delete from group_id"), errbuf)) - printf("Unable to clear groups: %s\n",errbuf); - } else { //clear a specific group - //if (!RunQuery(query, MakeAnyLenString(&query, "update group_id set groupid=0 where groupid = %lu", gid), errbuf)) - if (!RunQuery(query, MakeAnyLenString(&query, "delete from group_id where groupid = %lu", (unsigned long)gid), errbuf)) - printf("Unable to clear groups: %s\n",errbuf); + + if(gid == 0) + { + //clear all groups + ClearAllGroups(); + return; } - safe_delete_array(query); + + //clear a specific group + std::string query = StringFormat("delete from group_id where groupid = %lu", (unsigned long)gid); + auto results = QueryDatabase(query); + + if (!results.Success()) + std::cout << "Unable to clear groups: " << results.ErrorMessage() << std::endl; } uint32 Database::GetGroupID(const char* name){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 groupid=0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where name='%s'", name), errbuf, &result)) { - if((row = mysql_fetch_row(result))) - { - if(row[0]) - groupid=atoi(row[0]); - } - else - LogFile->write(EQEMuLog::Debug, "Character not in a group: %s", name); - mysql_free_result(result); + + std::string query = StringFormat("SELECT groupid from group_id where name='%s'", name); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + LogFile->write(EQEMuLog::Error, "Error getting group id: %s", results.ErrorMessage().c_str()); + return 0; } - else - LogFile->write(EQEMuLog::Error, "Error getting group id: %s", errbuf); - safe_delete_array(query); - return groupid; + + if (results.RowCount() == 0) + { + LogFile->write(EQEMuLog::Debug, "Character not in a group: %s", name); + return 0; + } + + auto row = results.begin(); + + return atoi(row[0]); } char* Database::GetGroupLeaderForLogin(const char* name,char* leaderbuf){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + PlayerProfile_Struct pp; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile from character_ where name='%s'", name), errbuf, &result)) { - row = mysql_fetch_row(result); - unsigned long* lengths = mysql_fetch_lengths(result); - if (lengths[0] == sizeof(PlayerProfile_Struct)) { - memcpy(&pp, row[0], sizeof(PlayerProfile_Struct)); - strcpy(leaderbuf,pp.groupMembers[0]); - } - mysql_free_result(result); + + std::string query = StringFormat("SELECT profile from character_ where name='%s'", name); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cout << "Unable to get leader name: " << results.ErrorMessage() << std::endl; + return leaderbuf; } - else{ - printf("Unable to get leader name: %s\n",errbuf); - } - safe_delete_array(query); + + if (results.LengthOfColumn(0) != sizeof(PlayerProfile_Struct)) + return leaderbuf; + + auto row = results.begin(); + + memcpy(&pp, row[0], sizeof(PlayerProfile_Struct)); + strcpy(leaderbuf,pp.groupMembers[0]); + return leaderbuf; } void Database::SetGroupLeaderName(uint32 gid, const char* name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "Replace into group_leaders set gid=%lu, leadername='%s'",(unsigned long)gid,name), errbuf)) - printf("Unable to set group leader: %s\n",errbuf); + std::string query = StringFormat("Replace into group_leaders set gid=%lu, leadername='%s'",(unsigned long)gid,name); + auto results = QueryDatabase(query); - safe_delete_array(query); + if (!results.Success()) + std::cout << "Unable to set group leader: " << results.ErrorMessage() << std::endl; } char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank, char* assist, char* puller, char *marknpc, GroupLeadershipAA_Struct* GLAA){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES* result; - MYSQL_ROW row; + + std::string query = StringFormat("SELECT leadername, maintank, assist, puller, marknpc, leadershipaa FROM group_leaders WHERE gid=%lu",(unsigned long)gid); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT leadername, maintank, assist, puller, marknpc, leadershipaa FROM group_leaders WHERE gid=%lu",(unsigned long)gid), - errbuf, &result)) { + if (!results.Success() || results.RowCount() == 0) + { + if(leaderbuf) + strcpy(leaderbuf, "UNKNOWN"); - safe_delete_array(query); + if(maintank) + maintank[0] = '\0'; - row = mysql_fetch_row(result); - unsigned long* Lengths = mysql_fetch_lengths(result); + if(assist) + assist[0] = '\0'; - if(row != nullptr){ + if(puller) + puller[0] = '\0'; - if(leaderbuf) - strcpy(leaderbuf, row[0]); + if(marknpc) + marknpc[0] = '\0'; - if(maintank) - strcpy(maintank, row[1]); - - if(assist) - strcpy(assist, row[2]); - - if(puller) - strcpy(puller, row[3]); - - if(marknpc) - strcpy(marknpc, row[4]); - - if(GLAA && (Lengths[5] == sizeof(GroupLeadershipAA_Struct))) - memcpy(GLAA, row[5], sizeof(GroupLeadershipAA_Struct)); - - mysql_free_result(result); - return leaderbuf; - } + return leaderbuf; } - else - safe_delete_array(query); + + auto row = results.begin(); if(leaderbuf) - strcpy(leaderbuf, "UNKNOWN"); + strcpy(leaderbuf, row[0]); if(maintank) - maintank[0] = 0; + strcpy(maintank, row[1]); if(assist) - assist[0] = 0; + strcpy(assist, row[2]); if(puller) - puller[0] = 0; + strcpy(puller, row[3]); if(marknpc) - marknpc[0] = 0; + strcpy(marknpc, row[4]); + + if(GLAA && results.LengthOfColumn(5) == sizeof(GroupLeadershipAA_Struct)) + memcpy(GLAA, row[5], sizeof(GroupLeadershipAA_Struct)); return leaderbuf; } -void Database::ClearGroupLeader(uint32 gid){ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if(gid == 0) { //clear all group leaders - if (!RunQuery(query, MakeAnyLenString(&query, "DELETE from group_leaders"), errbuf)) - printf("Unable to clear group leaders: %s\n",errbuf); - } else { //clear a specific group leader - if (!RunQuery(query, MakeAnyLenString(&query, "DELETE from group_leaders where gid = %lu", (unsigned long)gid), errbuf)) - printf("Unable to clear group leader: %s\n",errbuf); - } - safe_delete_array(query); +// Clearing all group leaders +void Database::ClearAllGroupLeaders(void) +{ + std::string query("DELETE from group_leaders"); + auto results = QueryDatabase(query); + + if (!results.Success()) + std::cout << "Unable to clear group leaders: " << results.ErrorMessage() << std::endl; + + return; } -bool FetchRowMap(MYSQL_RES *result, std::map &rowmap) -{ -MYSQL_FIELD *fields; -MYSQL_ROW row; -unsigned long num_fields,i; -bool retval=false; - rowmap.clear(); - if (result && (num_fields=mysql_num_fields(result)) && (row = mysql_fetch_row(result))!=nullptr && (fields = mysql_fetch_fields(result))!=nullptr) { - retval=true; - for(i=0;i %u", count,count), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) { - row = mysql_fetch_row(result); - if(atoi(row[0]) <= max) { - count = atoi(row[0]); - mysql_free_result(result); - } else { - mysql_free_result(result); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM instance_list where id > %u ORDER BY id", count), errbuf, &result)) { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) { - count++; - while((row = mysql_fetch_row(result))) { - if(count < atoi(row[0])) { - instance_id = count; - mysql_free_result(result); - return true; - } else if(count > max) { - instance_id = 0; - mysql_free_result(result); - return false; - } else { - count++; - } - } - } else { - instance_id = 0; - mysql_free_result(result); - return false; - } - } else { - safe_delete_array(query); - instance_id = 0; - return false; - } - } - } else { - instance_id = 0; - mysql_free_result(result); - return false; - } - } else { - safe_delete_array(query); + + std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count); + auto results = QueryDatabase(query); + + if (!results.Success()) + { instance_id = 0; return false; } + + if (results.RowCount() == 0) + { + instance_id = 0; + return false; + } + + auto row = results.begin(); + + if (atoi(row[0]) <= max) + { + instance_id = atoi(row[0]); + return true; + } + + query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count); + results = QueryDatabase(query); + + if (!results.Success()) + { + instance_id = 0; + return false; + } + + if (results.RowCount() == 0) + { + instance_id = 0; + return false; + } + + count++; + for (auto row = results.begin();row != results.end();++row) + { + if(count < atoi(row[0])) + { + instance_id = count; + return true; + } + + if(count > max) + { + instance_id = 0; + return false; + } + + count++; + } + instance_id = count; return true; } @@ -2574,214 +2175,114 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id) //perhaps purge any expireds too bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if(RunQuery(query, MakeAnyLenString(&query, "INSERT INTO instance_list (id, zone, version, start_time, duration)" - " values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)", (unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration), errbuf)) - { - safe_delete_array(query); - return true; - } - else - { - safe_delete_array(query); - return false; - } + std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)" + " values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)", + (unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration); + auto results = QueryDatabase(query); + + return results.Success(); } void Database::PurgeExpiredInstances() { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint16 id = 0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM instance_list where " - "(start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0"), errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) > 0) - { - row = mysql_fetch_row(result); - while(row != nullptr) - { - id = atoi(row[0]); - DeleteInstance(id); - row = mysql_fetch_row(result); - } - } - mysql_free_result(result); - } - else - { - safe_delete_array(query); - } + std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0"); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + if (results.RowCount() == 0) + return; + + for (auto row = results.begin();row != results.end();++row) + DeleteInstance(atoi(row[0])); } bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("INSERT INTO instance_list_player(id, charid) values(%lu, %lu)", + (unsigned long)instance_id, (unsigned long)char_id); + auto results = QueryDatabase(query); - if(RunQuery(query, MakeAnyLenString(&query, "INSERT INTO instance_list_player(id, charid) " - "values(%lu, %lu)", (unsigned long)instance_id, (unsigned long)char_id), errbuf)) - { - safe_delete_array(query); - return true; - } - else - { - safe_delete_array(query); - return false; - } + return results.Success(); } bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + + std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu", + (unsigned long)instance_id, (unsigned long)char_id); + auto results = QueryDatabase(query); - if(RunQuery(query, MakeAnyLenString(&query, "DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu", - (unsigned long)instance_id, (unsigned long)char_id), errbuf)) - { - safe_delete_array(query); - return true; - } - else - { - safe_delete_array(query); - return false; - } + return results.Success(); } bool Database::RemoveClientsFromInstance(uint16 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id); + auto results = QueryDatabase(query); - if(RunQuery(query, MakeAnyLenString(&query, "DELETE FROM instance_list_player WHERE id=%lu", - (unsigned long)instance_id), errbuf)) - { - safe_delete_array(query); - return true; - } - else - { - safe_delete_array(query); - return false; - } + return results.Success(); } bool Database::CheckInstanceExists(uint16 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM instance_list where id=%u", instance_id), - errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) - { - mysql_free_result(result); - return true; - } - mysql_free_result(result); + std::string query = StringFormat("SELECT * FROM instance_list where id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) return false; - } - else - { - safe_delete_array(query); + + if (results.RowCount() == 0) return false; - } - return false; + + return true; } void Database::BuryCorpsesInInstance(uint16 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - if(RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET IsBurried=1, instanceid=0 WHERE instanceid=%u", - instance_id), errbuf, &result)) - { - mysql_free_result(result); - } - safe_delete_array(query); + std::string query = StringFormat("UPDATE player_corpses SET IsBurried=1, instanceid=0 WHERE instanceid=%u", instance_id); + auto results = QueryDatabase(query); } uint16 Database::GetInstanceVersion(uint16 instance_id) { - if(instance_id < 1) + if(instance_id == 0) return 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 ret; + std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT version FROM instance_list where id=%u", instance_id), - errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) - { - row = mysql_fetch_row(result); - ret = atoi(row[0]); - mysql_free_result(result); - return ret; - } - else - { - mysql_free_result(result); - return 0; - } - } - else - { - safe_delete_array(query); + if (!results.Success()) return 0; - } - return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } uint16 Database::GetInstanceID(const char* zone, uint32 charid, int16 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint16 ret; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT instance_list.id FROM instance_list, instance_list_player " + std::string query = StringFormat("SELECT instance_list.id FROM instance_list, instance_list_player " "WHERE instance_list.zone=%u AND instance_list.version=%u AND instance_list.id=instance_list_player.id AND " - "instance_list_player.charid=%u LIMIT 1;", GetZoneID(zone), version, charid, charid), errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) - { - row = mysql_fetch_row(result); - ret = atoi(row[0]); - mysql_free_result(result); - return ret; - } - else - { - mysql_free_result(result); - return 0; - } - } - else - { - safe_delete_array(query); + "instance_list_player.charid=%u LIMIT 1;", GetZoneID(zone), version, charid, charid); + auto results = QueryDatabase(query); + + if (!results.Success()) return 0; - } - return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } uint16 Database::GetInstanceID(uint32 zone, uint32 charid, int16 version) @@ -2789,113 +2290,74 @@ uint16 Database::GetInstanceID(uint32 zone, uint32 charid, int16 version) if(!zone) return 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint16 ret; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT instance_list.id FROM instance_list, instance_list_player " + std::string query = StringFormat("SELECT instance_list.id FROM instance_list, instance_list_player " "WHERE instance_list.zone=%u AND instance_list.version=%u AND instance_list.id=instance_list_player.id AND " - "instance_list_player.charid=%u LIMIT 1;", zone, version, charid), errbuf, &result)) - { - safe_delete_array(query); - if (mysql_num_rows(result) != 0) - { - row = mysql_fetch_row(result); - ret = atoi(row[0]); - mysql_free_result(result); - return ret; - } - else - { - mysql_free_result(result); - return 0; - } - } - else - { - safe_delete_array(query); + "instance_list_player.charid=%u LIMIT 1;", zone, version, charid); + auto results = QueryDatabase(query); + + if (!results.Success()) return 0; - } - return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); } void Database::GetCharactersInInstance(uint16 instance_id, std::list &charid_list) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid FROM instance_list_player WHERE id=%u", instance_id), errbuf, &result)) { - safe_delete_array(query); - while ((row = mysql_fetch_row(result))) - { - charid_list.push_back(atoi(row[0])); - } - mysql_free_result(result); - } - else { - LogFile->write(EQEMuLog::Error, "Error in GetCharactersInInstace query '%s': %s", query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("SELECT charid FROM instance_list_player WHERE id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + LogFile->write(EQEMuLog::Error, "Error in GetCharactersInInstace query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return; } + + for(auto row=results.begin();row != results.end();++row) + charid_list.push_back(atoi(row[0])); } void Database::AssignGroupToInstance(uint32 gid, uint32 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + uint32 zone_id = ZoneIDFromInstanceID(instance_id); uint16 version = VersionFromInstanceID(instance_id); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid FROM group_id WHERE groupid=%u", gid), - errbuf, &result)) + std::string query = StringFormat("SELECT charid FROM group_id WHERE groupid=%u", gid); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row=results.begin();row != results.end();++row) { - safe_delete_array(query); - while((row = mysql_fetch_row(result)) != nullptr) - { - uint32 charid = atoi(row[0]); - if(GetInstanceID(zone_id, charid, version) == 0) - { - AddClientToInstance(instance_id, charid); - } - } - mysql_free_result(result); - } - else - { - safe_delete_array(query); + uint32 charid = atoi(row[0]); + if(GetInstanceID(zone_id, charid, version) == 0) + AddClientToInstance(instance_id, charid); } } void Database::AssignRaidToInstance(uint32 rid, uint32 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + uint32 zone_id = ZoneIDFromInstanceID(instance_id); uint16 version = VersionFromInstanceID(instance_id); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid FROM raid_members WHERE raidid=%u", rid), - errbuf, &result)) + std::string query = StringFormat("SELECT charid FROM raid_members WHERE raidid=%u", rid); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row=results.begin();row!=results.end();++row) { - safe_delete_array(query); - while((row = mysql_fetch_row(result)) != nullptr) - { - uint32 charid = atoi(row[0]); - if(GetInstanceID(zone_id, charid, version) == 0) - { - AddClientToInstance(instance_id, charid); - } - } - mysql_free_result(result); - } - else - { - safe_delete_array(query); + uint32 charid = atoi(row[0]); + if(GetInstanceID(zone_id, charid, version) == 0) + AddClientToInstance(instance_id, charid); } } @@ -2934,208 +2396,127 @@ void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 chari void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - if(RunQuery(query, MakeAnyLenString(&query, "UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), " - "duration=%u WHERE id=%u", new_duration, instance_id), errbuf)) - { - safe_delete_array(query); - } - else - { - //error - safe_delete_array(query); - } + std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), " + "duration=%u WHERE id=%u", new_duration, instance_id); + auto results = QueryDatabase(query); } bool Database::GlobalInstance(uint16 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - bool ret; + + std::string query = StringFormat("SELECT is_global from instance_list where id=%u LIMIT 1", instance_id); + auto results = QueryDatabase(query); - if (RunQuery(query, MakeAnyLenString(&query, "SELECT is_global from instance_list where id=%u LIMIT 1", instance_id), errbuf, &result)) - { - safe_delete_array(query); - row = mysql_fetch_row(result); - if(row) - { - ret = (atoi(row[0]) == 1) ? true : false; - } - else - { - mysql_free_result(result); - return false; - } - } - else - { - safe_delete_array(query); + if (!results.Success()) return false; - } - return ret; + + if (results.RowCount() == 0) + return false; + + auto row = results.begin(); + + return (atoi(row[0]) == 1) ? true : false; } void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected = 0; - + std::string field; - if(win) + switch(theme) { - switch(theme) + case 1: { - case 1: - { - field = "guk_wins"; - break; - } - case 2: - { - field = "mir_wins"; - break; - } - case 3: - { - field = "mmc_wins"; - break; - } - case 4: - { - field = "ruj_wins"; - break; - } - case 5: - { - field = "tak_wins"; - break; - } - default: - { - return; - } + field = "guk_"; + break; } - } - else - { - switch(theme) + case 2: { - case 1: - { - field = "guk_losses"; - break; - } - case 2: - { - field = "mir_losses"; - break; - } - case 3: - { - field = "mmc_losses"; - break; - } - case 4: - { - field = "ruj_losses"; - break; - } - case 5: - { - field = "tak_losses"; - break; - } - default: - { - return; - } + field = "mir_"; + break; + } + case 3: + { + field = "mmc_"; + break; + } + case 4: + { + field = "ruj_"; + break; + } + case 5: + { + field = "tak_"; + break; + } + default: + { + return; } } - if(RunQuery(query, MakeAnyLenString(&query, "UPDATE `adventure_stats` SET %s=%s+1 WHERE player_id=%u", - field.c_str(), field.c_str(), char_id), errbuf, nullptr, &affected)) - { - safe_delete_array(query); - } + if (win) + field += "wins"; else - { - //error - safe_delete_array(query); - } + field += "losses"; - if(affected == 0) - { - if(RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `adventure_stats` SET %s=1, player_id=%u", - field.c_str(), char_id), errbuf)) - { - safe_delete_array(query); - } - else - { - //error - safe_delete_array(query); - } - } + std::string query = StringFormat("UPDATE `adventure_stats` SET %s=%s+1 WHERE player_id=%u",field.c_str(), field.c_str(), char_id); + auto results = QueryDatabase(query); + + if (results.RowsAffected() != 0) + return; + + query = StringFormat("INSERT INTO `adventure_stats` SET %s=1, player_id=%u", field.c_str(), char_id); + QueryDatabase(query); } bool Database::GetAdventureStats(uint32 char_id, uint32 &guk_w, uint32 &mir_w, uint32 &mmc_w, uint32 &ruj_w, uint32 &tak_w, uint32 &guk_l, uint32 &mir_l, uint32 &mmc_l, uint32 &ruj_l, uint32 &tak_l) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT `guk_wins`, `mir_wins`, `mmc_wins`, `ruj_wins`, `tak_wins`, " - "`guk_losses`, `mir_losses`, `mmc_losses`, `ruj_losses`, `tak_losses` FROM `adventure_stats` WHERE player_id=%u", - char_id), errbuf, &result)) - { - safe_delete_array(query); - while((row = mysql_fetch_row(result)) != nullptr) - { - guk_w = atoi(row[0]); - mir_w = atoi(row[1]); - mmc_w = atoi(row[2]); - ruj_w = atoi(row[3]); - tak_w = atoi(row[4]); - guk_l = atoi(row[5]); - mir_l = atoi(row[6]); - mmc_l = atoi(row[7]); - ruj_l = atoi(row[8]); - tak_l = atoi(row[9]); - } - mysql_free_result(result); - return true; - } - else - { - safe_delete_array(query); + std::string query = StringFormat("SELECT `guk_wins`, `mir_wins`, `mmc_wins`, `ruj_wins`, `tak_wins`, `guk_losses`, " + "`mir_losses`, `mmc_losses`, `ruj_losses`, `tak_losses` FROM `adventure_stats` WHERE player_id=%u", char_id); + auto results = QueryDatabase(query); + + if (!results.Success()) return false; - } + + if (results.RowCount() == 0) + return false; + + auto row = results.begin(); + + guk_w = atoi(row[0]); + mir_w = atoi(row[1]); + mmc_w = atoi(row[2]); + ruj_w = atoi(row[3]); + tak_w = atoi(row[4]); + guk_l = atoi(row[5]); + mir_l = atoi(row[6]); + mmc_l = atoi(row[7]); + ruj_l = atoi(row[8]); + tak_l = atoi(row[9]); + + return true; } -uint32 Database::GetGuildDBIDByCharID(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - int retVal = 0; +uint32 Database::GetGuildIDByCharID(uint32 char_id) +{ - if (RunQuery(query, MakeAnyLenString(&query, "SELECT guild_id FROM guild_members WHERE char_id='%i'", char_id), errbuf, &result)) { - if (mysql_num_rows(result) == 1) { - MYSQL_ROW row = mysql_fetch_row(result); - retVal = atoi(row[0]); - } - mysql_free_result(result); + std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", char_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + std::cerr << "Error in GetGuildIDByChar query '" << query << "' " << results.ErrorMessage() << std::endl; + return 0; } - else { - std::cerr << "Error in GetAccountIDByChar query '" << query << "' " << errbuf << std::endl; - } - safe_delete_array(query); - return retVal; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } diff --git a/common/database.h b/common/database.h index 300fc9875..9be05f0cd 100644 --- a/common/database.h +++ b/common/database.h @@ -130,7 +130,7 @@ public: uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0); uint32 GetAccountIDByChar(uint32 char_id); uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0); - uint32 GetGuildDBIDByCharID(uint32 char_id); + uint32 GetGuildIDByCharID(uint32 char_id); void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0); void GetCharName(uint32 char_id, char* name); uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0,float* oX = 0, float* oY = 0, float* oZ = 0); @@ -207,6 +207,7 @@ public: char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr); void ClearGroupLeader(uint32 gid = 0); + /* * Raids @@ -223,7 +224,7 @@ public: bool SetVariable(const char* varname, const char* varvalue); bool LoadVariables(); uint32 LoadVariables_MQ(char** query); - bool LoadVariables_result(MYSQL_RES* result); + bool LoadVariables_result(MySQLRequestResult results); /* * General Queries @@ -262,7 +263,20 @@ private: uint32 varcache_max; VarCache_Struct** varcache_array; uint32 varcache_lastupdate; + + + /* + * Groups, utility methods. + */ + void ClearAllGroupLeaders(); + void ClearAllGroups(); + + + /* + * Raid, utility methods. + */ + void ClearAllRaids(); + void ClearAllRaidDetails(); }; -bool FetchRowMap(MYSQL_RES *result, std::map &rowmap); #endif diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 9b6236e5a..3d25236c7 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -80,10 +80,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo pStatus = Error; // error appears to be a disconnect error, may need to try again. - if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) + if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) { - if (retryOnFailureOnce) + if (retryOnFailureOnce) { std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl; MySQLRequestResult requestResult = QueryDatabase(query, querylen, false); @@ -95,18 +95,18 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo } } - + pStatus = Error; - + char *errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); - + std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer); - } - + } + char *errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); @@ -114,21 +114,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; #endif return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer); - + } // successful query. get results. MYSQL_RES* res = mysql_store_result(&mysql); - MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), (uint32)mysql_num_rows(res), (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); + uint32 rowCount = 0; + + if (res != nullptr) + rowCount = (uint32)mysql_num_rows(res); + + MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); #if DEBUG_MYSQL_QUERIES >= 1 - if (requestResult.Success()) + if (requestResult.Success()) { std::cout << "query successful"; if (requestResult.Result()) std::cout << ", " << (int) mysql_num_rows(requestResult.Result()) << " rows returned"; - + std::cout << ", " << requestResult.RowCount() << " rows affected"; std::cout<< std::endl; } diff --git a/common/eq_dictionary.cpp b/common/eq_dictionary.cpp index a1fa5e3e1..4c772689d 100644 --- a/common/eq_dictionary.cpp +++ b/common/eq_dictionary.cpp @@ -237,7 +237,7 @@ std::string EmuConstants::InventorySubName(int16 sub) { return "Unknown Sub"; std::string ret_str; - StringFormat(ret_str, "Container %i", (sub + 1)); // zero-based index..but, count starts at one + ret_str = StringFormat("Container %i", (sub + 1)); // zero-based index..but, count starts at one return ret_str; } @@ -250,7 +250,7 @@ std::string EmuConstants::InventoryAugName(int16 aug) { return "Unknown Aug"; std::string ret_str; - StringFormat(ret_str, "Augment %i", (aug + 1)); // zero-based index..but, count starts at one + ret_str = StringFormat("Augment %i", (aug + 1)); // zero-based index..but, count starts at one return ret_str; } @@ -929,7 +929,7 @@ uint64 EQLimits::PossessionsBitmask(uint32 version) { /*Underfoot*/ 0x000000027FFFFFFF, /*RoF*/ 0x00000003FFFFFFFF, /*RoF2*/ 0, - + /*NPC*/ 0, /*Merc*/ 0, /*Bot*/ 0, @@ -950,7 +950,7 @@ uint64 EQLimits::EquipmentBitmask(uint32 version) { /*Underfoot*/ 0x00000000007FFFFF, /*RoF*/ 0x00000000007FFFFF, /*RoF2*/ 0, - + /*NPC*/ 0, /*Merc*/ 0, /*Bot*/ 0, @@ -971,7 +971,7 @@ uint64 EQLimits::GeneralBitmask(uint32 version) { /*Underfoot*/ 0x000000007F800000, /*RoF*/ 0x00000001FF800000, /*RoF2*/ 0, - + /*NPC*/ 0, /*Merc*/ 0, /*Bot*/ 0, @@ -992,7 +992,7 @@ uint64 EQLimits::CursorBitmask(uint32 version) { /*Underfoot*/ 0x0000000200000000, /*RoF*/ 0x0000000200000000, /*RoF2*/ 0, - + /*NPC*/ 0, /*Merc*/ 0, /*Bot*/ 0, @@ -1013,13 +1013,13 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) { /*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF2*/ false, - + /*NPC*/ false, /*Merc*/ false, /*Bot*/ false, /*Pet*/ false }; - + return false; // not implemented //return local[ValidateMobVersion(version)]; } @@ -1035,7 +1035,7 @@ uint16 EQLimits::ItemCommonSize(uint32 version) { /*Underfoot*/ EmuConstants::ITEM_COMMON_SIZE, /*RoF*/ EmuConstants::ITEM_COMMON_SIZE, /*RoF2*/ 0, - + /*NPC*/ EmuConstants::ITEM_COMMON_SIZE, /*Merc*/ EmuConstants::ITEM_COMMON_SIZE, /*Bot*/ EmuConstants::ITEM_COMMON_SIZE, @@ -1055,7 +1055,7 @@ uint16 EQLimits::ItemContainerSize(uint32 version) { /*Underfoot*/ EmuConstants::ITEM_CONTAINER_SIZE, /*RoF*/ EmuConstants::ITEM_CONTAINER_SIZE, /*RoF2*/ 0, - + /*NPC*/ EmuConstants::ITEM_CONTAINER_SIZE, /*Merc*/ EmuConstants::ITEM_CONTAINER_SIZE, /*Bot*/ EmuConstants::ITEM_CONTAINER_SIZE, @@ -1075,7 +1075,7 @@ bool EQLimits::CoinHasWeight(uint32 version) { /*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT, /*RoF*/ RoF::limits::COIN_HAS_WEIGHT, /*RoF2*/ true, - + /*NPC*/ true, /*Merc*/ true, /*Bot*/ true, @@ -1095,7 +1095,7 @@ uint32 EQLimits::BandoliersCount(uint32 version) { /*Underfoot*/ EmuConstants::BANDOLIERS_COUNT, /*RoF*/ EmuConstants::BANDOLIERS_COUNT, /*RoF2*/ 0, - + /*NPC*/ NOT_USED, /*Merc*/ NOT_USED, /*Bot*/ NOT_USED, @@ -1115,7 +1115,7 @@ uint32 EQLimits::BandolierSize(uint32 version) { /*Underfoot*/ EmuConstants::BANDOLIER_SIZE, /*RoF*/ EmuConstants::BANDOLIER_SIZE, /*RoF2*/ 0, - + /*NPC*/ NOT_USED, /*Merc*/ NOT_USED, /*Bot*/ NOT_USED, @@ -1135,7 +1135,7 @@ uint32 EQLimits::PotionBeltSize(uint32 version) { /*Underfoot*/ EmuConstants::POTION_BELT_SIZE, /*RoF*/ EmuConstants::POTION_BELT_SIZE, /*RoF2*/ 0, - + /*NPC*/ NOT_USED, /*Merc*/ NOT_USED, /*Bot*/ NOT_USED, diff --git a/common/eq_dictionary.cpp.orig b/common/eq_dictionary.cpp.orig new file mode 100644 index 000000000..ecedcbb4e --- /dev/null +++ b/common/eq_dictionary.cpp.orig @@ -0,0 +1,1151 @@ +/* +EQEMu: Everquest Server Emulator + +Copyright (C) 2001-2014 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 "eq_dictionary.h" +#include "StringUtil.h" + +// +// class EmuConstants +// +uint16 EmuConstants::InventoryMapSize(int16 map) { + switch (map) { + case MapPossessions: + return MAP_POSSESSIONS_SIZE; + case MapBank: + return MAP_BANK_SIZE; + case MapSharedBank: + return MAP_SHARED_BANK_SIZE; + case MapTrade: + return MAP_TRADE_SIZE; + case MapWorld: + return MAP_WORLD_SIZE; + case MapLimbo: + return MAP_LIMBO_SIZE; + case MapTribute: + return MAP_TRIBUTE_SIZE; + case MapTrophyTribute: + return MAP_TROPHY_TRIBUTE_SIZE; + case MapGuildTribute: + return MAP_GUILD_TRIBUTE_SIZE; + case MapMerchant: + return MAP_MERCHANT_SIZE; + case MapDeleted: + return MAP_DELETED_SIZE; + case MapCorpse: + return MAP_CORPSE_SIZE; + case MapBazaar: + return MAP_BAZAAR_SIZE; + case MapInspect: + return MAP_INSPECT_SIZE; + case MapRealEstate: + return MAP_REAL_ESTATE_SIZE; + case MapViewMODPC: + return MAP_VIEW_MOD_PC_SIZE; + case MapViewMODBank: + return MAP_VIEW_MOD_BANK_SIZE; + case MapViewMODSharedBank: + return MAP_VIEW_MOD_SHARED_BANK_SIZE; + case MapViewMODLimbo: + return MAP_VIEW_MOD_LIMBO_SIZE; + case MapAltStorage: + return MAP_ALT_STORAGE_SIZE; + case MapArchived: + return MAP_ARCHIVED_SIZE; + case MapMail: + return MAP_MAIL_SIZE; + case MapGuildTrophyTribute: + return MAP_GUILD_TROPHY_TRIBUTE_SIZE; + case MapKrono: + return MAP_KRONO_SIZE; + case MapOther: + return MAP_OTHER_SIZE; + default: + return NOT_USED; + } +} + +/* +std::string EmuConstants::InventoryLocationName(Location_Struct location) { + // not ready for implementation... + std::string ret_str; + StringFormat(ret_str, "%s, %s, %s, %s", InventoryMapName(location.map), InventoryMainName(location.main), InventorySubName(location.sub), InventoryAugName(location.aug)); + return ret_str; +} +*/ + +std::string EmuConstants::InventoryMapName(int16 map) { + switch (map) { + case INVALID_INDEX: + return "Invalid Map"; + case MapPossessions: + return "Possessions"; + case MapBank: + return "Bank"; + case MapSharedBank: + return "Shared Bank"; + case MapTrade: + return "Trade"; + case MapWorld: + return "World"; + case MapLimbo: + return "Limbo"; + case MapTribute: + return "Tribute"; + case MapTrophyTribute: + return "Trophy Tribute"; + case MapGuildTribute: + return "Guild Tribute"; + case MapMerchant: + return "Merchant"; + case MapDeleted: + return "Deleted"; + case MapCorpse: + return "Corpse"; + case MapBazaar: + return "Bazaar"; + case MapInspect: + return "Inspect"; + case MapRealEstate: + return "Real Estate"; + case MapViewMODPC: + return "View MOD PC"; + case MapViewMODBank: + return "View MOD Bank"; + case MapViewMODSharedBank: + return "View MOD Shared Bank"; + case MapViewMODLimbo: + return "View MOD Limbo"; + case MapAltStorage: + return "Alt Storage"; + case MapArchived: + return "Archived"; + case MapMail: + return "Mail"; + case MapGuildTrophyTribute: + return "Guild Trophy Tribute"; + case MapKrono: + return "Krono"; + case MapOther: + return "Other"; + default: + return "Unknown Map"; + } +} + +std::string EmuConstants::InventoryMainName(int16 main) { + switch (main) { + case INVALID_INDEX: + return "Invalid Main"; + case MainCharm: + return "Charm"; + case MainEar1: + return "Ear 1"; + case MainHead: + return "Head"; + case MainFace: + return "Face"; + case MainEar2: + return "Ear 2"; + case MainNeck: + return "Neck"; + case MainShoulders: + return "Shoulders"; + case MainArms: + return "Arms"; + case MainBack: + return "Back"; + case MainWrist1: + return "Wrist 1"; + case MainWrist2: + return "Wrist 2"; + case MainRange: + return "Range"; + case MainHands: + return "Hands"; + case MainPrimary: + return "Primary"; + case MainSecondary: + return "Secondary"; + case MainFinger1: + return "Finger 1"; + case MainFinger2: + return "Finger 2"; + case MainChest: + return "Chest"; + case MainLegs: + return "Legs"; + case MainFeet: + return "Feet"; + case MainWaist: + return "Waist"; + case MainPowerSource: + return "Power Source"; + case MainAmmo: + return "Ammo"; + case MainGeneral1: + return "General 1"; + case MainGeneral2: + return "General 2"; + case MainGeneral3: + return "General 3"; + case MainGeneral4: + return "General 4"; + case MainGeneral5: + return "General 5"; + case MainGeneral6: + return "General 6"; + case MainGeneral7: + return "General 7"; + case MainGeneral8: + return "General 8"; + /* + case MainGeneral9: + return "General 9"; + case MainGeneral10: + return "General 10"; + */ + case MainCursor: + return "Cursor"; + default: + return "Unknown Main"; + } +} + +std::string EmuConstants::InventorySubName(int16 sub) { + if (sub == INVALID_INDEX) + return "Invalid Sub"; + + if ((uint16)sub >= ITEM_CONTAINER_SIZE) + return "Unknown Sub"; + + std::string ret_str; + ret_str = StringFormat("Container %i", (sub + 1)); // zero-based index..but, count starts at one + + return ret_str; +} + +std::string EmuConstants::InventoryAugName(int16 aug) { + if (aug == INVALID_INDEX) + return "Invalid Aug"; + + if ((uint16)aug >= ITEM_COMMON_SIZE) + return "Unknown Aug"; + + std::string ret_str; + ret_str = StringFormat("Augment %i", (aug + 1)); // zero-based index..but, count starts at one + + return ret_str; +} + +<<<<<<< HEAD +// +// class ClientLimits +======= +// legacy-related functions +// +// these should work for the first-stage coversions..but, once the new system is up and going..conversions will be incompatible +// without limiting server functions and other aspects, such as augment control, bag size, etc. A complete remapping will be +// required when bag sizes over 10 and direct manipulation of augments are implemented, due to the massive increase in range usage. +// +// (current personal/cursor bag range {251..340}, or 90 slots ... conversion translated range would be {10000..12804}, or 2805 slots... +// these would have to be hard-coded into all perl code to allow access to full range of the new system - actual limits would be +// less, based on bag size..but, the range must be full and consistent to avoid translation issues -- similar changes to other ranges +// (240 versus 6120 slots for bank bags, for example...)) +/* +int EmuConstants::ServerToPerlSlot(int server_slot) { // set r/s + switch (server_slot) { + case legacy::SLOT_CURSOR_END: + return legacy::SLOT_CURSOR_END; + case INVALID_INDEX: + return legacy::SLOT_INVALID; + case MainPowerSource: + return legacy::SLOT_POWER_SOURCE; + case MainAmmo: + return legacy::SLOT_AMMO; + case MainCursor: + return legacy::SLOT_CURSOR; + case legacy::SLOT_TRADESKILL: + return legacy::SLOT_TRADESKILL; + case legacy::SLOT_AUGMENT: + return legacy::SLOT_AUGMENT; + default: + int perl_slot = legacy::SLOT_INVALID; + + // activate the internal checks as needed + if (server_slot >= EmuConstants::EQUIPMENT_BEGIN && server_slot <= MainWaist) { + perl_slot = server_slot; + } + else if (server_slot >= EmuConstants::GENERAL_BEGIN && server_slot <= EmuConstants::GENERAL_END) { + perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BEGIN - EmuConstants::GENERAL_BEGIN; + //if (perl_slot < legacy::SLOT_PERSONAL_BEGIN || perl_slot > legacy::SLOT_PERSONAL_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::GENERAL_BAGS_BEGIN && server_slot <= EmuConstants::GENERAL_BAGS_END) { + perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BAGS_BEGIN - EmuConstants::GENERAL_BAGS_BEGIN; + //if (perl_slot < legacy::SLOT_PERSONAL_BAGS_BEGIN || perl_slot > legacy::SLOT_PERSONAL_BAGS_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::CURSOR_BAG_BEGIN && server_slot <= EmuConstants::CURSOR_BAG_END) { + perl_slot = server_slot;// + legacy::SLOT_CURSOR_BAG_BEGIN - EmuConstants::CURSOR_BAG_BEGIN; + //if (perl_slot < legacy::SLOT_CURSOR_BAG_BEGIN || perl_slot > legacy::SLOT_CURSOR_BAG_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::TRIBUTE_BEGIN && server_slot <= EmuConstants::TRIBUTE_END) { + perl_slot = server_slot;// + legacy::SLOT_TRIBUTE_BEGIN - EmuConstants::TRADE_BEGIN; + //if (perl_slot < legacy::SLOT_TRIBUTE_BEGIN || perl_slot > legacy::SLOT_TRIBUTE_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::BANK_BEGIN && server_slot <= EmuConstants::BANK_END) { + perl_slot = server_slot;// + legacy::SLOT_BANK_BEGIN - EmuConstants::BANK_BEGIN; + //if (perl_slot < legacy::SLOT_BANK_BEGIN || perl_slot > legacy::SLOT_BANK_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::BANK_BAGS_BEGIN && server_slot <= EmuConstants::BANK_BAGS_END) { + perl_slot = server_slot;// + legacy::SLOT_BANK_BAGS_BEGIN - EmuConstants::BANK_BAGS_BEGIN; + //if (perl_slot < legacy::SLOT_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_BANK_BAGS_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::SHARED_BANK_BEGIN && server_slot <= EmuConstants::SHARED_BANK_END) { + perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BEGIN - EmuConstants::SHARED_BANK_BEGIN; + //if (perl_slot < legacy::SLOT_SHARED_BANK_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && server_slot <= EmuConstants::SHARED_BANK_BAGS_END) { + perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BAGS_BEGIN - EmuConstants::SHARED_BANK_BAGS_BEGIN; + //if (perl_slot < legacy::SLOT_SHARED_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_BAGS_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::TRADE_BEGIN && server_slot <= EmuConstants::TRADE_END) { + perl_slot = server_slot;// + legacy::SLOT_TRADE_BEGIN - EmuConstants::TRADE_BEGIN; + //if (perl_slot < legacy::SLOT_TRADE_BEGIN || perl_slot > legacy::SLOT_TRADE_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::TRADE_BAGS_BEGIN && server_slot <= EmuConstants::TRADE_BAGS_END) { + perl_slot = server_slot;// + legacy::SLOT_TRADE_BAGS_BEGIN - EmuConstants::TRADE_BAGS_BEGIN; + //if (perl_slot < legacy::SLOT_TRADE_BAGS_BEGIN || perl_slot > legacy::SLOT_TRADE_BAGS_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= EmuConstants::WORLD_BEGIN && server_slot <= EmuConstants::WORLD_END) { + perl_slot = server_slot;// + legacy::SLOT_WORLD_BEGIN - EmuConstants::WORLD_BEGIN; + //if (perl_slot < legacy::SLOT_WORLD_BEGIN || perl_slot > legacy::SLOT_WORLD_END) + // perl_slot = legacy::SLOT_INVALID; + } + else if (server_slot >= 8000 && server_slot <= 8999) { // this range may be limited to 36 in the future (client size) + perl_slot = server_slot; + } + + return perl_slot; + } +} +*/ +/* +int EmuConstants::PerlToServerSlot(int perl_slot) { // set r/s + switch (perl_slot) { + case legacy::SLOT_CURSOR_END: + return legacy::SLOT_CURSOR_END; + case legacy::SLOT_INVALID: + return INVALID_INDEX; + case legacy::SLOT_POWER_SOURCE: + return MainPowerSource; + case legacy::SLOT_AMMO: + return MainAmmo; + case legacy::SLOT_CURSOR: + return MainCursor; + case legacy::SLOT_TRADESKILL: + return legacy::SLOT_TRADESKILL; + case legacy::SLOT_AUGMENT: + return legacy::SLOT_AUGMENT; + default: + int server_slot = INVALID_INDEX; + + // activate the internal checks as needed + if (perl_slot >= legacy::SLOT_EQUIPMENT_BEGIN && perl_slot <= legacy::SLOT_WAIST) { + server_slot = perl_slot; + } + else if (perl_slot >= legacy::SLOT_PERSONAL_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_END) { + server_slot = perl_slot;// + EmuConstants::GENERAL_BEGIN - legacy::SLOT_PERSONAL_BEGIN; + //if (server_slot < EmuConstants::GENERAL_BEGIN || server_slot > EmuConstants::GENERAL_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_PERSONAL_BAGS_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_BAGS_END) { + server_slot = perl_slot;// + EmuConstants::GENERAL_BAGS_BEGIN - legacy::SLOT_PERSONAL_BAGS_BEGIN; + //if (server_slot < EmuConstants::GENERAL_BAGS_BEGIN || server_slot > EmuConstants::GENERAL_BAGS_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_CURSOR_BAG_BEGIN && perl_slot <= legacy::SLOT_CURSOR_BAG_END) { + server_slot = perl_slot;// + EmuConstants::CURSOR_BAG_BEGIN - legacy::SLOT_CURSOR_BAG_BEGIN; + //if (server_slot < EmuConstants::CURSOR_BAG_BEGIN || server_slot > EmuConstants::CURSOR_BAG_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_TRIBUTE_BEGIN && perl_slot <= legacy::SLOT_TRIBUTE_END) { + server_slot = perl_slot;// + EmuConstants::TRIBUTE_BEGIN - legacy::SLOT_TRIBUTE_BEGIN; + //if (server_slot < EmuConstants::TRIBUTE_BEGIN || server_slot > EmuConstants::TRIBUTE_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_BANK_BEGIN && perl_slot <= legacy::SLOT_BANK_END) { + server_slot = perl_slot;// + EmuConstants::BANK_BEGIN - legacy::SLOT_BANK_BEGIN; + //if (server_slot < EmuConstants::BANK_BEGIN || server_slot > EmuConstants::BANK_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_BANK_BAGS_END) { + server_slot = perl_slot;// + EmuConstants::BANK_BAGS_BEGIN - legacy::SLOT_BANK_BAGS_BEGIN; + //if (server_slot < EmuConstants::BANK_BAGS_BEGIN || server_slot > EmuConstants::BANK_BAGS_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_SHARED_BANK_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_END) { + server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BEGIN - legacy::SLOT_SHARED_BANK_BEGIN; + //if (server_slot < EmuConstants::SHARED_BANK_BEGIN || server_slot > EmuConstants::SHARED_BANK_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_SHARED_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_BAGS_END) { + server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BAGS_BEGIN - legacy::SLOT_SHARED_BANK_BAGS_END; + //if (server_slot < EmuConstants::SHARED_BANK_BAGS_BEGIN || server_slot > EmuConstants::SHARED_BANK_BAGS_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_TRADE_BEGIN && perl_slot <= legacy::SLOT_TRADE_END) { + server_slot = perl_slot;// + EmuConstants::TRADE_BEGIN - legacy::SLOT_TRADE_BEGIN; + //if (server_slot < EmuConstants::TRADE_BEGIN || server_slot > EmuConstants::TRADE_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_TRADE_BAGS_BEGIN && perl_slot <= legacy::SLOT_TRADE_BAGS_END) { + server_slot = perl_slot;// + EmuConstants::TRADE_BAGS_BEGIN - legacy::SLOT_TRADE_BAGS_BEGIN; + //if (server_slot < EmuConstants::TRADE_BAGS_BEGIN || server_slot > EmuConstants::TRADE_BAGS_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= legacy::SLOT_WORLD_BEGIN && perl_slot <= legacy::SLOT_WORLD_END) { + server_slot = perl_slot;// + EmuConstants::WORLD_BEGIN - legacy::SLOT_WORLD_BEGIN; + //if (server_slot < EmuConstants::WORLD_BEGIN || server_slot > EmuConstants::WORLD_END) + // server_slot = INVALID_INDEX; + } + else if (perl_slot >= 8000 && perl_slot <= 8999) { // this range may be limited to 36 in the future (client size) + server_slot = perl_slot; + } + + return server_slot; + } +} +*/ + +// +// class EQLimits +>>>>>>> upstream/master +// +// client validation +bool EQLimits::IsValidClientVersion(uint32 version) { + if (version < _EQClientCount) + return true; + + return false; +} + +uint32 EQLimits::ValidateClientVersion(uint32 version) { + if (version < _EQClientCount) + return version; + + return EQClientUnknown; +} + +EQClientVersion EQLimits::ValidateClientVersion(EQClientVersion version) { + if (version >= EQClientUnknown) + if (version < _EQClientCount) + return version; + + return EQClientUnknown; +} + +// npc validation +bool EQLimits::IsValidNPCVersion(uint32 version) { + if (version >= _EQClientCount) + if (version < _EmuClientCount) + return true; + + return false; +} + +uint32 EQLimits::ValidateNPCVersion(uint32 version) { + if (version >= _EQClientCount) + if (version < _EmuClientCount) + return version; + + return EQClientUnknown; +} + +EQClientVersion EQLimits::ValidateNPCVersion(EQClientVersion version) { + if (version >= _EQClientCount) + if (version < _EmuClientCount) + return version; + + return EQClientUnknown; +} + +// mob validation +bool EQLimits::IsValidMobVersion(uint32 version) { + if (version < _EmuClientCount) + return true; + + return false; +} + +uint32 EQLimits::ValidateMobVersion(uint32 version) { + if (version < _EmuClientCount) + return version; + + return EQClientUnknown; +} + +EQClientVersion EQLimits::ValidateMobVersion(EQClientVersion version) { + if (version >= EQClientUnknown) + if (version < _EmuClientCount) + return version; + + return EQClientUnknown; +} + +// inventory +uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { + // not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...) + // a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified + // ALL of these values need to be verified before pushing to live + // + // make sure that you transcribe the actual value from 'defaults' to here before updating or client crashes will ensue..and/or... + // insert older clients inside of the progression of client order + // + // MAP_POSSESSIONS_SIZE does not reflect all actual _constants size due to bitmask-use compatibility + // + // when setting NPC-based values, try to adhere to an EmuConstants:: or NOT_USED value to avoid unnecessary issues + + static const uint16 local[_MapCount][_EmuClientCount] = { + // server and database are sync'd to current MapPossessions's client as set in 'using namespace RoF::slots;' and + // 'EmuConstants::MAP_POSSESSIONS_SIZE' - use/update EquipmentBitmask(), GeneralBitmask() and CursorBitmask() + // for partial range validation checks and 'EmuConstants::MAP_POSSESSIONS_SIZE' for full range iterations + { // local[MainPossessions] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*Titanium*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*SoF*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*SoD*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*Underfoot*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*RoF*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*RoF2*/ 0, + +/*NPC*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*Merc*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*Bot*/ EmuConstants::MAP_POSSESSIONS_SIZE, +/*Pet*/ EmuConstants::MAP_POSSESSIONS_SIZE + }, + { // local[MapBank] +/*Unknown*/ NOT_USED, +/*62*/ Client62::consts::MAP_BANK_SIZE, +/*Titanium*/ Titanium::consts::MAP_BANK_SIZE, +/*SoF*/ EmuConstants::MAP_BANK_SIZE, +/*SoD*/ EmuConstants::MAP_BANK_SIZE, +/*Underfoot*/ EmuConstants::MAP_BANK_SIZE, +/*RoF*/ EmuConstants::MAP_BANK_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }, + { // local[MapSharedBank] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*Titanium*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*SoF*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*SoD*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*Underfoot*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*RoF*/ EmuConstants::MAP_SHARED_BANK_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }, + { // local[MapTrade] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_TRADE_SIZE, +/*Titanium*/ EmuConstants::MAP_TRADE_SIZE, +/*SoF*/ EmuConstants::MAP_TRADE_SIZE, +/*SoD*/ EmuConstants::MAP_TRADE_SIZE, +/*Underfoot*/ EmuConstants::MAP_TRADE_SIZE, +/*RoF*/ EmuConstants::MAP_TRADE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 4, +/*Merc*/ 4, +/*Bot*/ EmuConstants::MAP_TRADE_SIZE, // client thinks this is another client +/*Pet*/ 4 + }, + { // local[MapWorld] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_WORLD_SIZE, +/*Titanium*/ EmuConstants::MAP_WORLD_SIZE, +/*SoF*/ EmuConstants::MAP_WORLD_SIZE, +/*SoD*/ EmuConstants::MAP_WORLD_SIZE, +/*Underfoot*/ EmuConstants::MAP_WORLD_SIZE, +/*RoF*/ EmuConstants::MAP_WORLD_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }, + { // local[MapLimbo] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_LIMBO_SIZE, +/*Titanium*/ EmuConstants::MAP_LIMBO_SIZE, +/*SoF*/ EmuConstants::MAP_LIMBO_SIZE, +/*SoD*/ EmuConstants::MAP_LIMBO_SIZE, +/*Underfoot*/ EmuConstants::MAP_LIMBO_SIZE, +/*RoF*/ EmuConstants::MAP_LIMBO_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }, + { // local[MapTribute] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*Titanium*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*SoF*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*SoD*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*Underfoot*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*RoF*/ EmuConstants::MAP_TRIBUTE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapTrophyTribute] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_TROPHY_TRIBUTE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapGuildTribute] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_GUILD_TRIBUTE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapMerchant] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_MERCHANT_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapDeleted] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_DELETED_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapCorpse] +/*Unknown*/ NOT_USED, +/*62*/ Client62::consts::MAP_CORPSE_SIZE, +/*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE, +/*SoF*/ SoF::consts::MAP_CORPSE_SIZE, +/*SoD*/ SoD::consts::MAP_CORPSE_SIZE, +/*Underfoot*/ Underfoot::consts::MAP_CORPSE_SIZE, +/*RoF*/ RoF::consts::MAP_CORPSE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapBazaar] +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::MAP_BAZAAR_SIZE, +/*Titanium*/ EmuConstants::MAP_BAZAAR_SIZE, +/*SoF*/ EmuConstants::MAP_BAZAAR_SIZE, +/*SoD*/ EmuConstants::MAP_BAZAAR_SIZE, +/*Underfoot*/ EmuConstants::MAP_BAZAAR_SIZE, +/*RoF*/ EmuConstants::MAP_BAZAAR_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, // this may need to be 'EmuConstants::MAP_BAZAAR_SIZE' if offline client traders respawn as an npc +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapInspect] +/*Unknown*/ NOT_USED, +/*62*/ Client62::consts::MAP_INSPECT_SIZE, +/*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE, +/*SoF*/ SoF::consts::MAP_INSPECT_SIZE, +/*SoD*/ SoD::consts::MAP_INSPECT_SIZE, +/*Underfoot*/ Underfoot::consts::MAP_INSPECT_SIZE, +/*RoF*/ RoF::consts::MAP_INSPECT_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }, + { // local[MapRealEstate] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_REAL_ESTATE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapViewMODPC] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_VIEW_MOD_PC_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapViewMODBank] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_VIEW_MOD_BANK_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapViewMODSharedBank] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_VIEW_MOD_SHARED_BANK_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapViewMODLimbo] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_VIEW_MOD_LIMBO_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapAltStorage] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_ALT_STORAGE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapArchived] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_ARCHIVED_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapMail] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_MAIL_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapGuildTrophyTribute] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_GUILD_TROPHY_TRIBUTE_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapKrono] +/*Unknown*/ NOT_USED, +/*62*/ NOT_USED, +/*Titanium*/ NOT_USED, +/*SoF*/ NOT_USED, +/*SoD*/ NOT_USED, +/*Underfoot*/ NOT_USED, +/*RoF*/ EmuConstants::MAP_KRONO_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }, + { // local[MapOther] +/*Unknown*/ NOT_USED, +/*62*/ 0, +/*Titanium*/ 0, +/*SoF*/ 0, +/*SoD*/ 0, +/*Underfoot*/ 0, +/*RoF*/ EmuConstants::MAP_OTHER_SIZE, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + } + }; + + if ((uint16)map < _MapCount) + return local[map][ValidateMobVersion(version)]; + + return NOT_USED; +} + +uint64 EQLimits::PossessionsBitmask(uint32 version) { + // these are for the new inventory system (RoF)..not the current (Ti) one... + // 0x0000000000200000 is SlotPowerSource (SoF+) + // 0x0000000080000000 is SlotGeneral9 (RoF+) + // 0x0000000100000000 is SlotGeneral10 (RoF+) + + static const uint64 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ 0x000000027FDFFFFF, +/*Titanium*/ 0x000000027FDFFFFF, +/*SoF*/ 0x000000027FFFFFFF, +/*SoD*/ 0x000000027FFFFFFF, +/*Underfoot*/ 0x000000027FFFFFFF, +/*RoF*/ 0x00000003FFFFFFFF, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }; + + return NOT_USED; + //return local[ValidateMobVersion(version)]; +} + +uint64 EQLimits::EquipmentBitmask(uint32 version) { + static const uint64 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ 0x00000000005FFFFF, +/*Titanium*/ 0x00000000005FFFFF, +/*SoF*/ 0x00000000007FFFFF, +/*SoD*/ 0x00000000007FFFFF, +/*Underfoot*/ 0x00000000007FFFFF, +/*RoF*/ 0x00000000007FFFFF, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }; + + return NOT_USED; + //return local[ValidateMobVersion(version)]; +} + +uint64 EQLimits::GeneralBitmask(uint32 version) { + static const uint64 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ 0x000000007F800000, +/*Titanium*/ 0x000000007F800000, +/*SoF*/ 0x000000007F800000, +/*SoD*/ 0x000000007F800000, +/*Underfoot*/ 0x000000007F800000, +/*RoF*/ 0x00000001FF800000, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }; + + return NOT_USED; + //return local[ValidateMobVersion(version)]; +} + +uint64 EQLimits::CursorBitmask(uint32 version) { + static const uint64 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ 0x0000000200000000, +/*Titanium*/ 0x0000000200000000, +/*SoF*/ 0x0000000200000000, +/*SoD*/ 0x0000000200000000, +/*Underfoot*/ 0x0000000200000000, +/*RoF*/ 0x0000000200000000, +/*RoF2*/ 0, + +/*NPC*/ 0, +/*Merc*/ 0, +/*Bot*/ 0, +/*Pet*/ 0 + }; + + return NOT_USED; + //return local[ValidateMobVersion(version)]; +} + +bool EQLimits::AllowsEmptyBagInBag(uint32 version) { + static const bool local[_EmuClientCount] = { +/*Unknown*/ false, +/*62*/ Client62::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*RoF2*/ false, + +/*NPC*/ false, +/*Merc*/ false, +/*Bot*/ false, +/*Pet*/ false + }; + + return false; // not implemented + //return local[ValidateMobVersion(version)]; +} + +// items +uint16 EQLimits::ItemCommonSize(uint32 version) { + static const uint16 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::ITEM_COMMON_SIZE, +/*Titanium*/ EmuConstants::ITEM_COMMON_SIZE, +/*SoF*/ EmuConstants::ITEM_COMMON_SIZE, +/*SoD*/ EmuConstants::ITEM_COMMON_SIZE, +/*Underfoot*/ EmuConstants::ITEM_COMMON_SIZE, +/*RoF*/ EmuConstants::ITEM_COMMON_SIZE, +/*RoF2*/ 0, + +/*NPC*/ EmuConstants::ITEM_COMMON_SIZE, +/*Merc*/ EmuConstants::ITEM_COMMON_SIZE, +/*Bot*/ EmuConstants::ITEM_COMMON_SIZE, +/*Pet*/ EmuConstants::ITEM_COMMON_SIZE + }; + + return local[ValidateMobVersion(version)]; +} + +uint16 EQLimits::ItemContainerSize(uint32 version) { + static const uint16 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*Titanium*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*SoF*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*SoD*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*Underfoot*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*RoF*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*RoF2*/ 0, + +/*NPC*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*Merc*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*Bot*/ EmuConstants::ITEM_CONTAINER_SIZE, +/*Pet*/ EmuConstants::ITEM_CONTAINER_SIZE + }; + + return local[ValidateMobVersion(version)]; +} + +bool EQLimits::CoinHasWeight(uint32 version) { + static const bool local[_EmuClientCount] = { +/*Unknown*/ true, +/*62*/ Client62::limits::COIN_HAS_WEIGHT, +/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT, +/*SoF*/ SoF::limits::COIN_HAS_WEIGHT, +/*SoD*/ SoD::limits::COIN_HAS_WEIGHT, +/*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT, +/*RoF*/ RoF::limits::COIN_HAS_WEIGHT, +/*RoF2*/ true, + +/*NPC*/ true, +/*Merc*/ true, +/*Bot*/ true, +/*Pet*/ true + }; + + return local[ValidateMobVersion(version)]; +} + +uint32 EQLimits::BandoliersCount(uint32 version) { + static const uint32 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::BANDOLIERS_COUNT, +/*Titanium*/ EmuConstants::BANDOLIERS_COUNT, +/*SoF*/ EmuConstants::BANDOLIERS_COUNT, +/*SoD*/ EmuConstants::BANDOLIERS_COUNT, +/*Underfoot*/ EmuConstants::BANDOLIERS_COUNT, +/*RoF*/ EmuConstants::BANDOLIERS_COUNT, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }; + + return local[ValidateMobVersion(version)]; +} + +uint32 EQLimits::BandolierSize(uint32 version) { + static const uint32 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::BANDOLIER_SIZE, +/*Titanium*/ EmuConstants::BANDOLIER_SIZE, +/*SoF*/ EmuConstants::BANDOLIER_SIZE, +/*SoD*/ EmuConstants::BANDOLIER_SIZE, +/*Underfoot*/ EmuConstants::BANDOLIER_SIZE, +/*RoF*/ EmuConstants::BANDOLIER_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }; + + return local[ValidateMobVersion(version)]; +} + +uint32 EQLimits::PotionBeltSize(uint32 version) { + static const uint32 local[_EmuClientCount] = { +/*Unknown*/ NOT_USED, +/*62*/ EmuConstants::POTION_BELT_SIZE, +/*Titanium*/ EmuConstants::POTION_BELT_SIZE, +/*SoF*/ EmuConstants::POTION_BELT_SIZE, +/*SoD*/ EmuConstants::POTION_BELT_SIZE, +/*Underfoot*/ EmuConstants::POTION_BELT_SIZE, +/*RoF*/ EmuConstants::POTION_BELT_SIZE, +/*RoF2*/ 0, + +/*NPC*/ NOT_USED, +/*Merc*/ NOT_USED, +/*Bot*/ NOT_USED, +/*Pet*/ NOT_USED + }; + + return local[ValidateMobVersion(version)]; +} diff --git a/common/logsys_eqemu.cpp b/common/logsys_eqemu.cpp index 5086114f5..e1e75996c 100644 --- a/common/logsys_eqemu.cpp +++ b/common/logsys_eqemu.cpp @@ -33,9 +33,7 @@ void log_message(LogType type, const char *fmt, ...) { } void log_messageVA(LogType type, const char *fmt, va_list args) { - std::string prefix_buffer; - - StringFormat(prefix_buffer, "[%s] ", log_type_info[type].name); + std::string prefix_buffer = StringFormat("[%s] ", log_type_info[type].name); LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args); } diff --git a/utils/sql/git/required/2014_06_25_AA_Updates..sql b/utils/sql/git/required/2014_06_25_AA_Updates..sql new file mode 100644 index 000000000..3d7a048b6 --- /dev/null +++ b/utils/sql/git/required/2014_06_25_AA_Updates..sql @@ -0,0 +1,34 @@ +-- AA MGB update +UPDATE altadv_vars SET spellid = 5228 WHERE skill_id = 128; +UPDATE aa_actions SET spell_id = 5228, nonspell_action = 0 WHERE aaid = 128; + +-- AA Project Illusion update +UPDATE altadv_vars SET spellid = 5227 WHERE skill_id = 643; +UPDATE aa_actions SET spell_id = 5227, nonspell_action = 0 WHERE aaid = 643; + +-- AA Improved Reclaim Energy +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('180', '1', '241', '95', '0'); + +-- AA Headshot +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '1', '217', '0', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '2', '346', '46', '0'); + +-- AA Anatomy (Rogue Assassinate) +INSERT INTO `altadv_vars` (`skill_id`, `name`, `cost`, `max_level`, `hotkey_sid`, `hotkey_sid2`, `title_sid`, `desc_sid`, `type`, `spellid`, `prereq_skill`, `prereq_minpoints`, `spell_type`, `spell_refresh`, `classes`, `berserker`, `class_type`, `cost_inc`, `aa_expansion`, `special_category`, `sof_type`, `sof_cost_inc`, `sof_max_level`, `sof_next_skill`, `clientver`, `account_time_required`, `sof_current_level`,`sof_next_id`,`level_inc`) VALUES ('1604', 'Anatomy', '5', '3', '4294967295', '4294967295', '1604', '1604', '1', '4294967295', '0', '0', '0', '0', '512', '0', '60', '1', '10', '4294967295', '3', '0', '3', '1604', '1', '0', '0', '0', '0'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '1', '439', '0', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '2', '345', '48', '0'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '1', '439', '0', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '2', '345', '51', '0'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '1', '439', '0', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '2', '345', '53', '0'); + +-- AA Finishing Blow Fix +DELETE FROM aa_effects WHERE aaid = 199 AND slot = 2; +DELETE FROM aa_effects WHERE aaid = 200 AND slot = 2; +DELETE FROM aa_effects WHERE aaid = 201 AND slot = 2; +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '1', '278', '500', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '2', '440', '50', '200'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '1', '278', '500', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '2', '440', '52', '200'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '1', '278', '500', '32000'); +INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '2', '440', '54', '200'); \ No newline at end of file diff --git a/world/world_logsys.cpp b/world/world_logsys.cpp index f60186a86..d7f798b6c 100644 --- a/world/world_logsys.cpp +++ b/world/world_logsys.cpp @@ -12,8 +12,7 @@ void log_message_clientVA(LogType type, Client *who, const char *fmt, va_list args) { - std::string prefix_buffer; - StringFormat(prefix_buffer,"[%s] %s: ", log_type_info[type].name, who->GetAccountName()); + std::string prefix_buffer = StringFormat("[%s] %s: ", log_type_info[type].name, who->GetAccountName()); LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args); } @@ -31,11 +30,11 @@ void log_message_zoneVA(LogType type, ZoneServer *who, const char *fmt, va_list const char *zone_name=who->GetZoneName(); if (zone_name == nullptr) - StringFormat(zone_tag,"[%d]", who->GetID()); + zone_tag = StringFormat("[%d]", who->GetID()); else - StringFormat(zone_tag,"[%d] [%s]",who->GetID(),zone_name); + zone_tag = StringFormat("[%d] [%s]",who->GetID(),zone_name); - StringFormat(prefix_buffer, "[%s] %s ", log_type_info[type].name, zone_tag.c_str()); + prefix_buffer = StringFormat("[%s] %s ", log_type_info[type].name, zone_tag.c_str()); LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args); } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index f748ddc68..bd6708a88 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -2015,7 +2015,7 @@ float Mob::GetSpecialProcChances(uint16 hand) ProcBonus += static_cast(mydex/35) + static_cast(itembonuses.HeroicDEX / 25); ProcChance += ProcChance * ProcBonus / 100.0f; } else { - /*PRE 2014 CHANGE Dev Quote - "Elidroth SOE:Proc chance is a function of your base hardcapped Dexterity / 35 + Heroic Dexterity / 25.” + /*PRE 2014 CHANGE Dev Quote - "Elidroth SOE:Proc chance is a function of your base hardcapped Dexterity / 35 + Heroic Dexterity / 25.” Kayen: Most reports suggest a ~ 6% chance to Headshot which consistent with above.*/ ProcChance = (static_cast(mydex/35) + static_cast(itembonuses.HeroicDEX / 25))/100.0f;