Compare commits

..

15 Commits

283 changed files with 16979 additions and 21308 deletions
+12
View File
@@ -31,6 +31,7 @@
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_MAP_DIR
#EQEMU_ENABLE_PROFILING
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
#Can change this if you really want but you should upgrade!
@@ -257,6 +258,7 @@ OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
OPTION(EQEMU_ENABLE_PROFILING "Enable CPU profiler. Note: will slow down execution time." OFF)
#C++11 stuff
IF(NOT MSVC)
@@ -331,6 +333,16 @@ IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
IF(EQEMU_ENABLE_PROFILING)
ADD_DEFINITIONS(-DEQPERF_ENABLED)
ADD_DEFINITIONS(-DEQP_MULTITHREAD)
INCLUDE_DIRECTORIES("eqperf")
ADD_SUBDIRECTORY(eqperf)
SET(PERF_LIBS eqperf)
ELSE(EQEMU_ENABLE_PROFILING)
SET(PERF_LIBS "")
ENDIF(EQEMU_ENABLE_PROFILING)
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
+207 -323
View File
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -11,15 +11,17 @@ ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(export_client_files common ${PERF_LIBS} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(export_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(export_client_files "Ws2_32.lib")
TARGET_LINK_LIBRARIES(export_client_files "rpcrt4")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(export_client_files "WS2_32")
TARGET_LINK_LIBRARIES(export_client_files "rpcrt4")
ENDIF(MINGW)
IF(UNIX)
@@ -30,6 +32,7 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(export_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "pthread")
TARGET_LINK_LIBRARIES(export_client_files "uuid")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
+1 -34
View File
@@ -32,7 +32,6 @@ EQEmuLogSys Log;
void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db);
void ExportBaseData(SharedDatabase *db);
void ExportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientExport);
@@ -63,7 +62,6 @@ int main(int argc, char **argv) {
ExportSpells(&database);
ExportSkillCaps(&database);
ExportBaseData(&database);
ExportDBStrings(&database);
Log.CloseFileLogs();
@@ -196,38 +194,7 @@ void ExportBaseData(SharedDatabase *db) {
fprintf(f, "%s\n", line.c_str());
}
}
fclose(f);
}
void ExportDBStrings(SharedDatabase *db) {
Log.Out(Logs::General, Logs::Status, "Exporting DB Strings...");
FILE *f = fopen("export/dbstr_us.txt", "w");
if(!f) {
Log.Out(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
return;
}
fprintf(f, "Major^Minor^String(New)\n");
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
auto results = db->QueryDatabase(query);
if(results.Success()) {
for(auto row = results.begin(); row != results.end(); ++row) {
std::string line;
unsigned int fields = results.ColumnCount();
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
if(rowIndex != 0)
line.push_back('^');
if(row[rowIndex] != nullptr) {
line += row[rowIndex];
}
}
fprintf(f, "%s\n", line.c_str());
}
} else {
}
fclose(f);
+4 -1
View File
@@ -11,15 +11,17 @@ ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(import_client_files common ${PERF_LIBS} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(import_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(import_client_files "Ws2_32.lib")
TARGET_LINK_LIBRARIES(import_client_files "rpcrt4")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(import_client_files "WS2_32")
TARGET_LINK_LIBRARIES(import_client_files "rpcrt4")
ENDIF(MINGW)
IF(UNIX)
@@ -30,6 +32,7 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(import_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "pthread")
TARGET_LINK_LIBRARIES(import_client_files "uuid")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
+1 -55
View File
@@ -30,7 +30,6 @@ EQEmuLogSys Log;
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
void ImportBaseData(SharedDatabase *db);
void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport);
@@ -60,7 +59,6 @@ int main(int argc, char **argv) {
ImportSpells(&database);
ImportSkillCaps(&database);
ImportBaseData(&database);
ImportDBStrings(&database);
Log.CloseFileLogs();
@@ -204,6 +202,7 @@ void ImportSkillCaps(SharedDatabase *db) {
continue;
}
int class_id, skill_id, level, cap;
class_id = atoi(split[0].c_str());
skill_id = atoi(split[1].c_str());
@@ -263,56 +262,3 @@ void ImportBaseData(SharedDatabase *db) {
fclose(f);
}
void ImportDBStrings(SharedDatabase *db) {
Log.Out(Logs::General, Logs::Status, "Importing DB Strings...");
FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) {
Log.Out(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
return;
}
std::string delete_sql = "DELETE FROM db_str";
db->QueryDatabase(delete_sql);
char buffer[2048];
bool first = true;
while(fgets(buffer, 2048, f)) {
if(first) {
first = false;
continue;
}
for(int i = 0; i < 2048; ++i) {
if(buffer[i] == '\n') {
buffer[i] = 0;
break;
}
}
auto split = SplitString(buffer, '^');
if(split.size() < 2) {
continue;
}
std::string sql;
int id, type;
std::string value;
id = atoi(split[0].c_str());
type = atoi(split[1].c_str());
if(split.size() >= 3) {
value = ::EscapeString(split[2]);
}
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
id, type, value.c_str());
db->QueryDatabase(sql);
}
fclose(f);
}
+3 -22
View File
@@ -30,23 +30,15 @@ SET(common_sources
faction.cpp
guild_base.cpp
guilds.cpp
inventory.cpp
inventory_db_data_model.cpp
ipc_mutex.cpp
item.cpp
item_container.cpp
item_container_default_serialization.cpp
item_container_personal_serialization.cpp
item_instance.cpp
md5.cpp
memory_buffer.cpp
memory_mapped_file.cpp
misc.cpp
misc_functions.cpp
mutex.cpp
mysql_request_result.cpp
mysql_request_row.cpp
opcode_map.cpp
opcodemgr.cpp
packet_dump.cpp
packet_dump_file.cpp
@@ -56,7 +48,6 @@ SET(common_sources
proc_launcher.cpp
ptimer.cpp
races.cpp
rdtsc.cpp
rulesys.cpp
serverinfo.cpp
shareddb.cpp
@@ -69,6 +60,7 @@ SET(common_sources
timeoutmgr.cpp
timer.cpp
unix.cpp
uuid.cpp
worldconn.cpp
xml_parser.cpp
platform.cpp
@@ -142,25 +134,15 @@ SET(common_headers
global_define.h
guild_base.h
guilds.h
inventory.h
inventory_data_model.h
inventory_db_data_model.h
inventory_null_data_model.h
ipc_mutex.h
item.h
item_container.h
item_container_default_serialization.h
item_container_personal_serialization.h
item_container_serialization_strategy.h
item_data.h
item_fieldlist.h
item_instance.h
item_struct.h
languages.h
linked_list.h
loottable.h
mail_oplist.h
md5.h
memory_buffer.h
memory_mapped_file.h
misc.h
misc_functions.h
@@ -175,12 +157,10 @@ SET(common_headers
packet_functions.h
platform.h
proc_launcher.h
profiler.h
ptimer.h
queue.h
races.h
random.h
rdtsc.h
rulesys.h
ruletypes.h
seperator.h
@@ -199,6 +179,7 @@ SET(common_headers
types.h
unix.h
useperl.h
uuid.h
version.h
worldconn.h
xml_parser.h
-1
View File
@@ -63,7 +63,6 @@ public:
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
uint8 ReadUInt8(uint32 Offset) const { uint8 value = *(uint8 *)(pBuffer + Offset); return value; }
+12 -88
View File
@@ -1,24 +1,3 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CLIENTVERSIONS_H
#define CLIENTVERSIONS_H
@@ -67,87 +46,32 @@ static const char* ClientVersionName(ClientVersion version)
switch (version)
{
case ClientVersion::Unknown:
return "Unknown";
return "ClientVersion::Unknown";
case ClientVersion::Client62:
return "Client62";
return "ClientVersion::Client62";
case ClientVersion::Titanium:
return "Titanium";
return "ClientVersion::Titanium";
case ClientVersion::SoF:
return "SoF";
return "ClientVersion::SoF";
case ClientVersion::SoD:
return "SoD";
return "ClientVersion::SoD";
case ClientVersion::UF:
return "UF";
return "ClientVersion::UF";
case ClientVersion::RoF:
return "RoF";
return "ClientVersion::RoF";
case ClientVersion::RoF2:
return "RoF2";
return "ClientVersion::RoF2";
case ClientVersion::MobNPC:
return "MobNPC";
return "ClientVersion::MobNPC";
case ClientVersion::MobMerc:
return "MobMerc";
return "ClientVersion::MobMerc";
case ClientVersion::MobBot:
return "MobBot";
return "ClientVersion::MobBot";
case ClientVersion::MobPet:
return "MobPet";
return "ClientVersion::MobPet";
default:
return "<ERROR> Invalid ClientVersion";
};
}
static uint32 ClientBitFromVersion(ClientVersion clientVersion)
{
switch (clientVersion)
{
case ClientVersion::Unknown:
case ClientVersion::Client62:
return 0;
case ClientVersion::Titanium:
case ClientVersion::SoF:
case ClientVersion::SoD:
case ClientVersion::UF:
case ClientVersion::RoF:
case ClientVersion::RoF2:
case ClientVersion::MobNPC:
case ClientVersion::MobMerc:
case ClientVersion::MobBot:
case ClientVersion::MobPet:
return ((uint32)1 << (static_cast<unsigned int>(clientVersion) - 1));
default:
return 0;
}
}
static ClientVersion ClientVersionFromBit(uint32 clientVersionBit)
{
switch (clientVersionBit)
{
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown):
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)):
return ClientVersion::Unknown;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)):
return ClientVersion::Titanium;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)):
return ClientVersion::SoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoD) - 1)):
return ClientVersion::SoD;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::UF) - 1)):
return ClientVersion::UF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF) - 1)):
return ClientVersion::RoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)):
return ClientVersion::RoF2;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobNPC) - 1)):
return ClientVersion::MobNPC;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobMerc) - 1)):
return ClientVersion::MobMerc;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobBot) - 1)):
return ClientVersion::MobBot;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobPet) - 1)):
return ClientVersion::MobPet;
default:
return ClientVersion::Unknown;
}
}
#endif /* CLIENTVERSIONS_H */
+11 -11
View File
@@ -23,23 +23,23 @@
namespace EQEmu
{
template <typename T, typename U, typename V>
T Clamp(const T& value, const U& lower, const V& upper) {
return std::max(static_cast<T>(lower), std::min(value, static_cast<T>(upper)));
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
}
template <typename T, typename U>
T ClampLower(const T& value, const U& lower) {
return std::max(static_cast<T>(lower), value);
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
}
template <typename T, typename U>
T ClampUpper(const T& value, const U& upper) {
return std::min(value, static_cast<T>(upper));
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
}
template <typename T, typename U, typename V>
bool ValueWithin(const T& value, const U& lower, const V& upper) {
template <typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) {
return value >= lower && value <= upper;
}
+91 -21
View File
@@ -57,11 +57,13 @@ Establish a connection to a mysql database with the supplied parameters
Database::Database(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
{
_eqp
DBInitVars();
Connect(host, user, passwd, database, port);
}
bool Database::Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port) {
_eqp
uint32 errnum= 0;
char errbuf[MYSQL_ERRMSG_SIZE];
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
@@ -75,6 +77,7 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
}
void Database::DBInitVars() {
_eqp
varcache_array = 0;
varcache_max = 0;
varcache_lastupdate = 0;
@@ -86,6 +89,7 @@ void Database::DBInitVars() {
Database::~Database()
{
_eqp
unsigned int x;
if (varcache_array) {
for (x=0; x<varcache_max; x++) {
@@ -101,7 +105,7 @@ Database::~Database()
Zero will also be returned if there is a database error.
*/
uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) {
_eqp
if(strlen(name) >= 50 || strlen(password) >= 50)
return(0);
@@ -137,6 +141,7 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat
//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)
{
_eqp
std::string query = StringFormat("SELECT ip_address FROM Banned_IPs WHERE ip_address='%s'", loginIP);
auto results = QueryDatabase(query);
@@ -153,6 +158,7 @@ bool Database::CheckBannedIPs(const char* loginIP)
}
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
_eqp
std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -162,6 +168,7 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) {
}
bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) {
_eqp
std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id);
auto results = QueryDatabase(query);
@@ -175,17 +182,20 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) {
}
bool Database::AddGMIP(char* ip_address, char* name) {
_eqp
std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name);
auto results = QueryDatabase(query);
return results.Success();
}
void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
_eqp
std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP);
QueryDatabase(query);
}
int16 Database::CheckStatus(uint32 account_id) {
_eqp
std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`"
" FROM `account` WHERE `id` = %i", account_id);
@@ -215,6 +225,7 @@ int16 Database::CheckStatus(uint32 account_id) {
}
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) {
_eqp
std::string query;
if (password)
@@ -238,6 +249,7 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta
}
bool Database::DeleteAccount(const char* name) {
_eqp
std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name);
Log.Out(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name);
@@ -250,6 +262,7 @@ bool Database::DeleteAccount(const char* name) {
}
bool Database::SetLocalPassword(uint32 accid, const char* password) {
_eqp
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", EscapeString(password).c_str(), accid);
auto results = QueryDatabase(query);
@@ -262,6 +275,7 @@ bool Database::SetLocalPassword(uint32 accid, const char* password) {
}
bool Database::SetAccountStatus(const char* name, int16 status) {
_eqp
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;
@@ -282,6 +296,7 @@ bool Database::SetAccountStatus(const char* name, int16 status) {
/* This initially creates the character during character create */
bool Database::ReserveName(uint32 account_id, char* name) {
_eqp
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
@@ -302,6 +317,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
returns false on failure, true otherwise
*/
bool Database::DeleteCharacter(char *name) {
_eqp
uint32 charid = 0;
if(!name || !strlen(name)) {
Log.Out(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)");
@@ -359,6 +375,7 @@ bool Database::DeleteCharacter(char *name) {
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
_eqp
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -677,7 +694,8 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
}
/* This only for new Character creation storing */
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv) {
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) {
_eqp
uint32 charid = 0;
char zone[50];
float x, y, z;
@@ -732,6 +750,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
}
uint32 Database::GetCharacterID(const char *name) {
_eqp
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
auto row = results.begin();
@@ -748,6 +767,7 @@ uint32 Database::GetCharacterID(const char *name) {
Zero will also be returned if there is a database error.
*/
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
_eqp
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", EscapeString(charname).c_str());
auto results = QueryDatabase(query);
@@ -772,6 +792,7 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
// Retrieve account_id for a given char_id
uint32 Database::GetAccountIDByChar(uint32 char_id) {
_eqp
std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -786,6 +807,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
}
uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) {
_eqp
if (!isAlphaNumeric(accname))
return 0;
@@ -817,6 +839,7 @@ uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32*
}
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
_eqp
std::string query = StringFormat("SELECT `name`, `lsaccount_id` FROM `account` WHERE `id` = '%i'", accountid);
auto results = QueryDatabase(query);
@@ -837,6 +860,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
}
void Database::GetCharName(uint32 char_id, char* name) {
_eqp
std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE id='%i'", char_id);
auto results = QueryDatabase(query);
@@ -851,6 +875,7 @@ void Database::GetCharName(uint32 char_id, char* name) {
}
bool Database::LoadVariables() {
_eqp
char *query = nullptr;
auto results = QueryDatabase(query, LoadVariables_MQ(&query));
@@ -867,12 +892,14 @@ bool Database::LoadVariables() {
uint32 Database::LoadVariables_MQ(char** query)
{
_eqp
return MakeAnyLenString(query, "SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache_lastupdate);
}
// always returns true? not sure about this.
bool Database::LoadVariables_result(MySQLRequestResult results)
{
_eqp
uint32 i = 0;
LockMutex lock(&Mvarcache);
@@ -935,6 +962,7 @@ bool Database::LoadVariables_result(MySQLRequestResult results)
// Gets variable from 'variables' table
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
_eqp
varvalue[0] = '\0';
LockMutex lock(&Mvarcache);
@@ -956,7 +984,7 @@ bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_
}
bool Database::SetVariable(const char* varname_in, const char* varvalue_in) {
_eqp
char *varname,*varvalue;
varname=(char *)malloc(strlen(varname_in)*2+1);
@@ -996,6 +1024,7 @@ bool Database::SetVariable(const char* varname_in, const char* varvalue_in) {
uint32 Database::GetMiniLoginAccount(char* ip)
{
_eqp
std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip);
auto results = QueryDatabase(query);
@@ -1008,7 +1037,7 @@ uint32 Database::GetMiniLoginAccount(char* ip)
// 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) {
_eqp
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);
@@ -1038,7 +1067,7 @@ bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe
}
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) {
_eqp
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);
@@ -1076,7 +1105,7 @@ bool Database::GetZoneLongName(const char* short_name, char** long_name, char* f
}
uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
_eqp
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);
@@ -1091,7 +1120,7 @@ uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
}
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
_eqp
std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id);
auto results = QueryDatabase(query);
@@ -1119,6 +1148,7 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
}
bool Database::LoadZoneNames() {
_eqp
std::string query("SELECT zoneidnumber, short_name FROM zone");
auto results = QueryDatabase(query);
@@ -1139,7 +1169,7 @@ bool Database::LoadZoneNames() {
}
uint32 Database::GetZoneID(const char* zonename) {
_eqp
if (zonename == nullptr)
return 0;
@@ -1151,6 +1181,7 @@ uint32 Database::GetZoneID(const char* zonename) {
}
const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) {
_eqp
auto iter = zonename_array.find(zoneID);
if (iter != zonename_array.end())
@@ -1163,7 +1194,7 @@ const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) {
}
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
_eqp
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);
@@ -1181,6 +1212,7 @@ uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
bool Database::CheckNameFilter(const char* name, bool surname)
{
_eqp
std::string str_name = name;
if(surname)
@@ -1257,7 +1289,7 @@ bool Database::CheckNameFilter(const char* name, bool surname)
}
bool Database::AddToNameFilter(const char* name) {
_eqp
std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name);
auto results = QueryDatabase(query);
@@ -1273,6 +1305,7 @@ bool Database::AddToNameFilter(const char* name) {
}
uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) {
_eqp
uint32 account_id = 0;
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID);
auto results = QueryDatabase(query);
@@ -1297,7 +1330,7 @@ uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* o
}
void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
_eqp
std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id);
auto results = QueryDatabase(query);
@@ -1317,10 +1350,12 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
}
void Database::ClearMerchantTemp(){
_eqp
QueryDatabase("DELETE FROM merchantlist_temp");
}
bool Database::UpdateName(const char* oldname, const char* newname) {
_eqp
std::cout << "Renaming " << oldname << " to " << newname << "..." << std::endl;
std::string query = StringFormat("UPDATE `character_data` SET `name` = '%s' WHERE `name` = '%s';", newname, oldname);
auto results = QueryDatabase(query);
@@ -1336,6 +1371,7 @@ 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) {
_eqp
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1349,6 +1385,7 @@ bool Database::CheckUsedName(const char* name) {
}
uint8 Database::GetServerType() {
_eqp
std::string query("SELECT `value` FROM `variables` WHERE `varname` = 'ServerType' LIMIT 1");
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1363,6 +1400,7 @@ uint8 Database::GetServerType() {
}
bool Database::MoveCharacterToZone(const char* charname, const char* zonename, uint32 zoneid) {
_eqp
if(zonename == nullptr || strlen(zonename) == 0)
return false;
@@ -1380,10 +1418,12 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename, u
}
bool Database::MoveCharacterToZone(const char* charname, const char* zonename) {
_eqp
return MoveCharacterToZone(charname, zonename, GetZoneID(zonename));
}
bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
_eqp
std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", iZonename, GetZoneID(iZonename), iCharID);
auto results = QueryDatabase(query);
@@ -1395,6 +1435,7 @@ bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
}
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
_eqp
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
auto results = QueryDatabase(query);
@@ -1406,6 +1447,7 @@ bool Database::SetHackerFlag(const char* accountname, const char* charactername,
}
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
_eqp
//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);
@@ -1420,6 +1462,7 @@ bool Database::SetMQDetectionFlag(const char* accountname, const char* character
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
{
_eqp
uint16 race_cap = 0;
//Check for a racial cap!
@@ -1438,6 +1481,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
{
_eqp
uint8 skill_level = 0, skill_formula = 0;
uint16 base_cap = 0, skill_cap = 0, skill_cap2 = 0, skill_cap3 = 0;
@@ -1487,6 +1531,7 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
}
uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZoneID, uint32* oInstanceID, float* oX, float* oY, float* oZ) {
_eqp
std::string query = StringFormat("SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'", iName);
auto results = QueryDatabase(query);
@@ -1510,7 +1555,7 @@ uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZo
}
bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
_eqp
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id);
auto results = QueryDatabase(query);
@@ -1522,7 +1567,7 @@ bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
}
bool Database::GetLiveChar(uint32 account_id, char* cname) {
_eqp
std::string query = StringFormat("SELECT charname FROM account WHERE id=%i", account_id);
auto results = QueryDatabase(query);
@@ -1541,26 +1586,31 @@ bool Database::GetLiveChar(uint32 account_id, char* cname) {
}
void Database::SetLFP(uint32 CharID, bool LFP) {
_eqp
std::string query = StringFormat("UPDATE `character_data` SET `lfp` = %i WHERE `id` = %i",LFP, CharID);
QueryDatabase(query);
}
void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) {
_eqp
std::string query = StringFormat("update `character_data` SET `lfp` = %i, `lfg` = %i, `firstlogon` = %i WHERE `id` = %i",LFP, LFG, firstlogon, CharID);
QueryDatabase(query);
}
void Database::SetLFG(uint32 CharID, bool LFG) {
_eqp
std::string query = StringFormat("update `character_data` SET `lfg` = %i WHERE `id` = %i",LFG, CharID);
QueryDatabase(query);
}
void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) {
_eqp
std::string query = StringFormat( "UPDATE `character_data` SET `firstlogon` = %i WHERE `id` = %i",firstlogon, CharID);
QueryDatabase(query);
}
void Database::AddReport(std::string who, std::string against, std::string lines) {
_eqp
char *escape_str = new char[lines.size()*2+1];
DoEscapeString(escape_str, lines.c_str(), lines.size());
@@ -1570,6 +1620,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
}
void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc) {
_eqp
std::string query;
if (id == 0) {
// removing from group
@@ -1589,12 +1640,14 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
void Database::ClearAllGroups(void)
{
_eqp
std::string query("DELETE FROM `group_id`");
QueryDatabase(query);
return;
}
void Database::ClearGroup(uint32 gid) {
_eqp
ClearGroupLeader(gid);
if(gid == 0)
@@ -1610,6 +1663,7 @@ void Database::ClearGroup(uint32 gid) {
}
uint32 Database::GetGroupID(const char* name){
_eqp
std::string query = StringFormat("SELECT groupid from group_id where name='%s'", name);
auto results = QueryDatabase(query);
@@ -1620,7 +1674,7 @@ uint32 Database::GetGroupID(const char* name){
if (results.RowCount() == 0)
{
// Commenting this out until logging levels can prevent this from going to console
//Log.Out(Logs::General, Logs::None,, "Character not in a group: %s", name);
//Log.Out(Logs::General, Logs::None, "Character not in a group: %s", name);
return 0;
}
@@ -1631,6 +1685,7 @@ uint32 Database::GetGroupID(const char* name){
/* Is this really getting used properly... A half implementation ? Akkadius */
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
_eqp
strcpy(leaderbuf, "");
uint32 group_id = 0;
@@ -1655,6 +1710,7 @@ char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
}
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
_eqp
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", EscapeString(name).c_str(), gid);
auto result = QueryDatabase(query);
@@ -1673,6 +1729,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank, char* assist, char* puller, char *marknpc, char *mentoree, int *mentor_percent, GroupLeadershipAA_Struct* GLAA)
{
_eqp
std::string query = StringFormat("SELECT `leadername`, `maintank`, `assist`, `puller`, `marknpc`, `mentoree`, `mentor_percent`, `leadershipaa` FROM `group_leaders` WHERE `gid` = %lu",(unsigned long)gid);
auto results = QueryDatabase(query);
@@ -1732,6 +1789,7 @@ char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* mainta
// Clearing all group leaders
void Database::ClearAllGroupLeaders(void) {
_eqp
std::string query("DELETE from group_leaders");
auto results = QueryDatabase(query);
@@ -1742,7 +1800,7 @@ void Database::ClearAllGroupLeaders(void) {
}
void Database::ClearGroupLeader(uint32 gid) {
_eqp
if(gid == 0)
{
ClearAllGroupLeaders();
@@ -1757,7 +1815,7 @@ void Database::ClearGroupLeader(uint32 gid) {
}
uint8 Database::GetAgreementFlag(uint32 acctid) {
_eqp
std::string query = StringFormat("SELECT rulesflag FROM account WHERE id=%i",acctid);
auto results = QueryDatabase(query);
@@ -1773,11 +1831,13 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
}
void Database::SetAgreementFlag(uint32 acctid) {
_eqp
std::string query = StringFormat("UPDATE account SET rulesflag=1 where id=%i", acctid);
QueryDatabase(query);
}
void Database::ClearRaid(uint32 rid) {
_eqp
if(rid == 0)
{
//clear all raids
@@ -1794,7 +1854,7 @@ void Database::ClearRaid(uint32 rid) {
}
void Database::ClearAllRaids(void) {
_eqp
std::string query("delete from raid_members");
auto results = QueryDatabase(query);
@@ -1804,7 +1864,7 @@ void Database::ClearAllRaids(void) {
void Database::ClearAllRaidDetails(void)
{
_eqp
std::string query("delete from raid_details");
auto results = QueryDatabase(query);
@@ -1813,7 +1873,7 @@ void Database::ClearAllRaidDetails(void)
}
void Database::ClearRaidDetails(uint32 rid) {
_eqp
if(rid == 0)
{
//clear all raids
@@ -1832,7 +1892,8 @@ void Database::ClearRaidDetails(uint32 rid) {
// returns 0 on error or no raid for that character, or
// the raid id that the character is a member of.
uint32 Database::GetRaidID(const char* name)
{
{
_eqp
std::string query = StringFormat("SELECT `raidid` FROM `raid_members` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
@@ -1853,6 +1914,7 @@ uint32 Database::GetRaidID(const char* name)
const char* Database::GetRaidLeaderName(uint32 raid_id)
{
_eqp
// Would be a good idea to fix this to be a passed in variable and
// make the caller responsible. static local variables like this are
// not guaranteed to be thread safe (nor is the internal guard
@@ -1884,6 +1946,7 @@ const char* Database::GetRaidLeaderName(uint32 raid_id)
void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
char *assist, char *puller, char *marknpc, char *mentoree, int *mentor_percent, GroupLeadershipAA_Struct *GLAA)
{
_eqp
std::string query = StringFormat(
"SELECT maintank, assist, puller, marknpc, mentoree, mentor_percent, leadershipaa FROM raid_leaders WHERE gid = %lu AND rid = %lu",
(unsigned long)gid, (unsigned long)rid);
@@ -1941,6 +2004,7 @@ void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
void Database::GetRaidLeadershipInfo(uint32 rid, char *maintank,
char *assist, char *puller, char *marknpc, RaidLeadershipAA_Struct *RLAA)
{
_eqp
std::string query = StringFormat(
"SELECT maintank, assist, puller, marknpc, leadershipaa FROM raid_leaders WHERE gid = %lu AND rid = %lu",
(unsigned long)0xFFFFFFFF, (unsigned long)rid);
@@ -1984,6 +2048,7 @@ void Database::GetRaidLeadershipInfo(uint32 rid, char *maintank,
void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid)
{
_eqp
std::string query = StringFormat("UPDATE raid_leaders SET leadershipaa = '' WHERE gid = %lu AND rid = %lu",
(unsigned long)gid, (unsigned long)rid);
auto results = QueryDatabase(query);
@@ -2001,6 +2066,7 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid)
// Clearing all raid leaders
void Database::ClearAllRaidLeaders(void)
{
_eqp
std::string query("DELETE from raid_leaders");
QueryDatabase(query);
return;
@@ -2008,6 +2074,7 @@ void Database::ClearAllRaidLeaders(void)
void Database::ClearRaidLeader(uint32 gid, uint32 rid)
{
_eqp
if (rid == 0) {
ClearAllRaidLeaders();
return;
@@ -2019,7 +2086,7 @@ void Database::ClearRaidLeader(uint32 gid, uint32 rid)
void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win)
{
_eqp
std::string field;
switch(theme)
@@ -2072,6 +2139,7 @@ void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win)
bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
{
_eqp
std::string query = StringFormat(
"SELECT "
"`guk_wins`, "
@@ -2118,6 +2186,7 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
uint32 Database::GetGuildIDByCharID(uint32 character_id)
{
_eqp
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", character_id);
auto results = QueryDatabase(query);
@@ -2133,6 +2202,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings)
{
_eqp
std::string query =
"SELECT "
"log_category_id, "
+2 -3
View File
@@ -27,7 +27,6 @@
#include "dbcore.h"
#include "linked_list.h"
#include "eq_packet_structs.h"
#include "inventory.h"
#include <cmath>
#include <string>
@@ -37,7 +36,7 @@
//atoi is not uint32 or uint32 safe!!!!
#define atoul(str) strtoul(str, nullptr, 10)
class InventoryOld;
class Inventory;
class MySQLRequestResult;
class Client;
@@ -103,7 +102,7 @@ public:
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
bool UpdateName(const char* oldname, const char* newname);
/* General Information Queries */
+18 -29
View File
@@ -157,29 +157,18 @@ namespace Convert {
/*84*/ uint32 Points;
/*88*/
} PVPStatsEntry_Struct;
static const size_t BANDOLIERS_SIZE = 4;
static const size_t BANDOLIER_ITEM_COUNT = 4;
struct BandolierItem_Struct {
uint32 ID;
uint32 Icon;
char Name[64];
uint32 item_id;
uint32 icon;
char item_name[64];
};
struct Bandolier_Struct {
char Name[32];
Convert::BandolierItem_Struct Items[Convert::BANDOLIER_ITEM_COUNT];
};
static const size_t POTION_BELT_ITEM_COUNT = 4;
struct PotionBeltItem_Struct {
uint32 ID;
uint32 Icon;
char Name[64];
char name[32];
Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
};
struct PotionBelt_Struct {
Convert::PotionBeltItem_Struct Items[Convert::POTION_BELT_ITEM_COUNT];
Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
};
struct SuspendedMinion_Struct
{
/*000*/ uint16 SpellID;
@@ -357,7 +346,7 @@ namespace Convert {
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Convert::Bandolier_Struct bandoliers[Convert::BANDOLIERS_SIZE];
/*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@@ -494,7 +483,7 @@ bool Database::CheckDatabaseConversions() {
/* Check for a new version of this script, the arg passed
would have to be higher than the copy they have downloaded
locally and they will re fetch */
system("perl eqemu_update.pl V 7");
system("perl eqemu_update.pl V 2");
/* Run Automatic Database Upgrade Script */
system("perl eqemu_update.pl ran_from_world");
@@ -1441,15 +1430,15 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Bandolier Convert */
first_entry = 0; rquery = "";
for (i = 0; i < Convert::BANDOLIERS_SIZE; i++){
if (strlen(pp->bandoliers[i].Name) < 32) {
for (int si = 0; si < Convert::BANDOLIER_ITEM_COUNT; si++){
if (pp->bandoliers[i].Items[si].ID > 0){
for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){
if (strlen(pp->bandoliers[i].name) < 32) {
for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){
if (pp->bandoliers[i].items[si].item_id > 0){
if (first_entry != 1) {
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
}
}
}
@@ -1457,13 +1446,13 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Potion Belt Convert */
first_entry = 0; rquery = "";
for (i = 0; i < Convert::POTION_BELT_ITEM_COUNT; i++){
if (pp->potionbelt.Items[i].ID > 0){
for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){
if (pp->potionbelt.items[i].item_id > 0){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
}
}
+2 -3
View File
@@ -348,7 +348,6 @@ N(OP_OpenTributeMaster),
N(OP_PDeletePetition),
N(OP_PetBuffWindow),
N(OP_PetCommands),
N(OP_PetHoTT),
N(OP_Petition),
N(OP_PetitionBug),
N(OP_PetitionCheckIn),
@@ -365,8 +364,6 @@ N(OP_PetitionUnCheckout),
N(OP_PetitionUpdate),
N(OP_PickPocket),
N(OP_PlayerProfile),
N(OP_PlayerStateAdd),
N(OP_PlayerStateRemove),
N(OP_PlayEverquestRequest),
N(OP_PlayEverquestResponse),
N(OP_PlayMP3),
@@ -522,6 +519,8 @@ N(OP_VetRewardsAvaliable),
N(OP_VoiceMacroIn),
N(OP_VoiceMacroOut),
N(OP_WeaponEquip1),
N(OP_WeaponEquip2),
N(OP_WeaponUnequip2),
N(OP_WearChange),
N(OP_Weather),
N(OP_Weblink),
+22
View File
@@ -50,6 +50,7 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET in_s
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
id = 0;
Server = nullptr;
pOldFormat = iOldFormat;
@@ -76,6 +77,7 @@ EmuTCPConnection::EmuTCPConnection(bool iOldFormat, EmuTCPServer* iRelayServer,
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
Server = iRelayServer;
if (Server)
RelayServer = true;
@@ -98,6 +100,7 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConne
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
Server = iServer;
RelayLink = iRelayLink;
RelayServer = true;
@@ -117,6 +120,7 @@ EmuTCPConnection::~EmuTCPConnection() {
}
EmuTCPNetPacket_Struct* EmuTCPConnection::MakePacket(ServerPacket* pack, uint32 iDestination) {
_eqp
int32 size = sizeof(EmuTCPNetPacket_Struct) + pack->size;
if (pack->compressed) {
size += 4;
@@ -144,6 +148,7 @@ EmuTCPNetPacket_Struct* EmuTCPConnection::MakePacket(ServerPacket* pack, uint32
}
SPackSendQueue* EmuTCPConnection::MakeOldPacket(ServerPacket* pack) {
_eqp
SPackSendQueue* spsq = (SPackSendQueue*) new uchar[sizeof(SPackSendQueue) + pack->size + 4];
if (pack->pBuffer != 0 && pack->size != 0)
memcpy((char *) &spsq->buffer[4], (char *) pack->pBuffer, pack->size);
@@ -154,6 +159,7 @@ SPackSendQueue* EmuTCPConnection::MakeOldPacket(ServerPacket* pack) {
}
bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
_eqp
if (!Connected())
return false;
eTCPMode tmp = GetMode();
@@ -214,6 +220,7 @@ bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
}
bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps) {
_eqp
if (RemoteID)
return false;
if (!Connected())
@@ -254,6 +261,7 @@ bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps) {
}
ServerPacket* EmuTCPConnection::PopPacket() {
_eqp
ServerPacket* ret;
if (!MOutQueueLock.trylock())
return nullptr;
@@ -263,12 +271,14 @@ ServerPacket* EmuTCPConnection::PopPacket() {
}
void EmuTCPConnection::InModeQueuePush(EmuTCPNetPacket_Struct* tnps) {
_eqp
MSendQueue.lock();
InModeQueue.push(tnps);
MSendQueue.unlock();
}
void EmuTCPConnection::OutQueuePush(ServerPacket* pack) {
_eqp
MOutQueueLock.lock();
OutQueue.push(pack);
MOutQueueLock.unlock();
@@ -276,6 +286,7 @@ void EmuTCPConnection::OutQueuePush(ServerPacket* pack) {
bool EmuTCPConnection::LineOutQueuePush(char* line) {
_eqp
#if defined(GOTFRAGS) && 0
if (strcmp(line, "**CRASHME**") == 0) {
int i = 0;
@@ -369,6 +380,7 @@ bool EmuTCPConnection::LineOutQueuePush(char* line) {
}
void EmuTCPConnection::Disconnect(bool iSendRelayDisconnect) {
_eqp
TCPConnection::Disconnect();
if (RelayLink) {
@@ -378,6 +390,7 @@ void EmuTCPConnection::Disconnect(bool iSendRelayDisconnect) {
}
bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
_eqp
if(!TCPConnection::ConnectIP(irIP, irPort, errbuf))
return(false);
@@ -432,6 +445,7 @@ bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
}
void EmuTCPConnection::ClearBuffers() {
_eqp
TCPConnection::ClearBuffers();
LockMutex lock2(&MOutQueueLock);
@@ -448,6 +462,7 @@ void EmuTCPConnection::ClearBuffers() {
}
void EmuTCPConnection::SendNetErrorPacket(const char* reason) {
_eqp
#if TCPC_DEBUG >= 1
struct in_addr in;
in.s_addr = GetrIP();
@@ -469,6 +484,7 @@ void EmuTCPConnection::SendNetErrorPacket(const char* reason) {
}
void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisconnect) {
_eqp
if (iSendRelayDisconnect) {
ServerPacket* pack = new ServerPacket(0, 5);
pack->pBuffer[0] = 3;
@@ -482,6 +498,7 @@ void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisco
bool EmuTCPConnection::ProcessReceivedData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
timeout_timer.Start();
@@ -505,6 +522,7 @@ bool EmuTCPConnection::ProcessReceivedData(char* errbuf) {
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
int32 base = 0;
@@ -621,6 +639,7 @@ bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
}
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
_eqp
int32 base = 0;
int32 size = 4;
uchar* buffer;
@@ -695,6 +714,7 @@ bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
}
void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) {
_eqp
uint8 opcode = pack->pBuffer[0];
uint8* data = &pack->pBuffer[1];
switch (opcode) {
@@ -780,6 +800,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) {
}
bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) {
_eqp
sent_something = false;
if(!TCPConnection::SendData(sent_something, errbuf))
return(false);
@@ -799,6 +820,7 @@ bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) {
}
bool EmuTCPConnection::RecvData(char* errbuf) {
_eqp
if(!TCPConnection::RecvData(errbuf)) {
if (OutQueue.count())
return(true);
+8
View File
@@ -9,6 +9,7 @@ EmuTCPServer::EmuTCPServer(uint16 iPort, bool iOldFormat)
}
EmuTCPServer::~EmuTCPServer() {
_eqp
MInQueue.lock();
while(!m_InQueue.empty()) {
delete m_InQueue.front();
@@ -18,23 +19,27 @@ EmuTCPServer::~EmuTCPServer() {
}
void EmuTCPServer::Process() {
_eqp
CheckInQueue();
TCPServer<EmuTCPConnection>::Process();
}
void EmuTCPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort)
{
_eqp
EmuTCPConnection *conn = new EmuTCPConnection(ID, this, in_socket, irIP, irPort, pOldFormat);
AddConnection(conn);
}
void EmuTCPServer::SendPacket(ServerPacket* pack) {
_eqp
EmuTCPNetPacket_Struct* tnps = EmuTCPConnection::MakePacket(pack);
SendPacket(&tnps);
}
void EmuTCPServer::SendPacket(EmuTCPNetPacket_Struct** tnps) {
_eqp
MInQueue.lock();
m_InQueue.push(*tnps);
MInQueue.unlock();
@@ -42,6 +47,7 @@ void EmuTCPServer::SendPacket(EmuTCPNetPacket_Struct** tnps) {
}
void EmuTCPServer::CheckInQueue() {
_eqp
EmuTCPNetPacket_Struct* tnps = 0;
while (( tnps = InQueuePop() )) {
@@ -57,6 +63,7 @@ void EmuTCPServer::CheckInQueue() {
}
EmuTCPNetPacket_Struct* EmuTCPServer::InQueuePop() {
_eqp
EmuTCPNetPacket_Struct* ret = nullptr;
MInQueue.lock();
if(!m_InQueue.empty()) {
@@ -69,6 +76,7 @@ EmuTCPNetPacket_Struct* EmuTCPServer::InQueuePop() {
EmuTCPConnection *EmuTCPServer::FindConnection(uint32 iID) {
_eqp
vitr cur, end;
cur = m_list.begin();
end = m_list.end();
+2 -49
View File
@@ -21,53 +21,6 @@
#include "skills.h"
#include "types.h"
/*
** Light Types
**
*/
enum LightTypes
{
lightTypeNone = 0,
lightTypeCandle,
lightTypeTorch,
lightTypeTinyGlowingSkull,
lightTypeSmallLantern,
lightTypeSteinOfMoggok,
lightTypeLargeLantern,
lightTypeFlamelessLantern,
lightTypeGlobeOfStars,
lightTypeLightGlobe,
lightTypeLightstone,
lightTypeGreaterLightstone,
lightTypeFireBeetleEye,
lightTypeColdlight,
lightTypeUnknown1,
lightTypeUnknown2
};
#define LIGHT_TYPES_COUNT 16
/*
** Light Levels
**
*/
enum LightLevels
{
lightLevelUnlit = 0,
lightLevelCandle,
lightLevelTorch,
lightLevelSmallMagic,
lightLevelRedLight,
lightLevelBlueLight,
lightLevelSmallLantern,
lightLevelMagicLantern,
lightLevelLargeLantern,
lightLevelLargeMagic,
lightLevelBrilliant
};
#define LIGHT_LEVELS_COUNT 11
/*
** Item attributes
**
@@ -102,7 +55,7 @@ enum ItemClassTypes
**
** (ref: database and eqstr_us.txt)
**
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013])
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013] -U)
*/
enum ItemUseTypes : uint8
{
@@ -306,7 +259,7 @@ enum AugmentationRestrictionTypes : uint8 {
/*
** Container use types
**
** This correlates to world 'object.type' (object.h/Object.cpp) as well as ItemData.BagType
** This correlates to world 'object.type' (object.h/Object.cpp) as well as Item_Struct.BagType
**
** (ref: database, web forums and eqstr_us.txt)
*/
+115 -102
View File
@@ -1,7 +1,7 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
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
@@ -25,10 +25,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// class EmuConstants
//
uint16 EmuConstants::InventoryMapSize(int16 indexMap)
{
switch (indexMap)
{
uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
switch (indexMap) {
case MapPossessions:
return MAP_POSSESSIONS_SIZE;
case MapBank:
@@ -85,8 +83,7 @@ uint16 EmuConstants::InventoryMapSize(int16 indexMap)
}
/*
std::string EmuConstants::InventoryLocationName(Location_Struct location)
{
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));
@@ -94,10 +91,8 @@ std::string EmuConstants::InventoryLocationName(Location_Struct location)
}
*/
std::string EmuConstants::InventoryMapName(int16 indexMap)
{
switch (indexMap)
{
std::string EmuConstants::InventoryMapName(int16 indexMap) {
switch (indexMap) {
case INVALID_INDEX:
return "Invalid Map";
case MapPossessions:
@@ -105,7 +100,7 @@ std::string EmuConstants::InventoryMapName(int16 indexMap)
case MapBank:
return "Bank";
case MapSharedBank:
return "SharedBank";
return "Shared Bank";
case MapTrade:
return "Trade";
case MapWorld:
@@ -115,9 +110,9 @@ std::string EmuConstants::InventoryMapName(int16 indexMap)
case MapTribute:
return "Tribute";
case MapTrophyTribute:
return "TrophyTribute";
return "Trophy Tribute";
case MapGuildTribute:
return "GuildTribute";
return "Guild Tribute";
case MapMerchant:
return "Merchant";
case MapDeleted:
@@ -129,23 +124,23 @@ std::string EmuConstants::InventoryMapName(int16 indexMap)
case MapInspect:
return "Inspect";
case MapRealEstate:
return "RealEstate";
return "Real Estate";
case MapViewMODPC:
return "ViewMODPC";
return "View MOD PC";
case MapViewMODBank:
return "ViewMODBank";
return "View MOD Bank";
case MapViewMODSharedBank:
return "ViewMODSharedBank";
return "View MOD Shared Bank";
case MapViewMODLimbo:
return "ViewMODLimbo";
return "View MOD Limbo";
case MapAltStorage:
return "AltStorage";
return "Alt Storage";
case MapArchived:
return "Archived";
case MapMail:
return "Mail";
case MapGuildTrophyTribute:
return "GuildTrophyTribute";
return "Guild Trophy Tribute";
case MapKrono:
return "Krono";
case MapOther:
@@ -155,22 +150,20 @@ std::string EmuConstants::InventoryMapName(int16 indexMap)
}
}
std::string EmuConstants::InventoryMainName(int16 indexMain)
{
switch (indexMain)
{
std::string EmuConstants::InventoryMainName(int16 indexMain) {
switch (indexMain) {
case INVALID_INDEX:
return "Invalid Main";
case MainCharm:
return "Charm";
case MainEar1:
return "Ear1";
return "Ear 1";
case MainHead:
return "Head";
case MainFace:
return "Face";
case MainEar2:
return "Ear2";
return "Ear 2";
case MainNeck:
return "Neck";
case MainShoulders:
@@ -180,9 +173,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain)
case MainBack:
return "Back";
case MainWrist1:
return "Wrist1";
return "Wrist 1";
case MainWrist2:
return "Wrist2";
return "Wrist 2";
case MainRange:
return "Range";
case MainHands:
@@ -192,9 +185,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain)
case MainSecondary:
return "Secondary";
case MainFinger1:
return "Finger1";
return "Finger 1";
case MainFinger2:
return "Finger2";
return "Finger 2";
case MainChest:
return "Chest";
case MainLegs:
@@ -204,30 +197,30 @@ std::string EmuConstants::InventoryMainName(int16 indexMain)
case MainWaist:
return "Waist";
case MainPowerSource:
return "PowerSource";
return "Power Source";
case MainAmmo:
return "Ammo";
case MainGeneral1:
return "General1";
return "General 1";
case MainGeneral2:
return "General2";
return "General 2";
case MainGeneral3:
return "General3";
return "General 3";
case MainGeneral4:
return "General4";
return "General 4";
case MainGeneral5:
return "General5";
return "General 5";
case MainGeneral6:
return "General6";
return "General 6";
case MainGeneral7:
return "General7";
return "General 7";
case MainGeneral8:
return "General8";
return "General 8";
/*
case MainGeneral9:
return "General9";
return "General 9";
case MainGeneral10:
return "General10";
return "General 10";
*/
case MainCursor:
return "Cursor";
@@ -236,8 +229,7 @@ std::string EmuConstants::InventoryMainName(int16 indexMain)
}
}
std::string EmuConstants::InventorySubName(int16 indexSub)
{
std::string EmuConstants::InventorySubName(int16 indexSub) {
if (indexSub == INVALID_INDEX)
return "Invalid Sub";
@@ -245,13 +237,12 @@ std::string EmuConstants::InventorySubName(int16 indexSub)
return "Unknown Sub";
std::string ret_str;
ret_str = StringFormat("Container%i", (indexSub + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Container %i", (indexSub + 1)); // zero-based index..but, count starts at one
return ret_str;
}
std::string EmuConstants::InventoryAugName(int16 indexAug)
{
std::string EmuConstants::InventoryAugName(int16 indexAug) {
if (indexAug == INVALID_INDEX)
return "Invalid Aug";
@@ -259,7 +250,7 @@ std::string EmuConstants::InventoryAugName(int16 indexAug)
return "Unknown Aug";
std::string ret_str;
ret_str = StringFormat("Augment%i", (indexAug + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Augment %i", (indexAug + 1)); // zero-based index..but, count starts at one
return ret_str;
}
@@ -269,16 +260,14 @@ std::string EmuConstants::InventoryAugName(int16 indexAug)
// class EQLimits
//
// client validation
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion)
{
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion)
{
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return clientVersion;
@@ -286,16 +275,14 @@ ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion)
}
// npc validation
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion)
{
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion)
{
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
@@ -303,47 +290,22 @@ ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion)
}
// mob validation
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion)
{
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion)
{
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
return ClientVersion::Unknown;
}
// database
size_t EQLimits::CharacterCreationLimit(ClientVersion clientVersion)
{
static const size_t local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*Client62*/ NOT_USED,
/*Titanium*/ Titanium::consts::CHARACTER_CREATION_LIMIT,
/*SoF*/ SoF::consts::CHARACTER_CREATION_LIMIT,
/*SoD*/ SoD::consts::CHARACTER_CREATION_LIMIT,
/*UF*/ UF::consts::CHARACTER_CREATION_LIMIT,
/*RoF*/ RoF::consts::CHARACTER_CREATION_LIMIT,
/*RoF2*/ RoF2::consts::CHARACTER_CREATION_LIMIT,
/*MobNPC*/ NOT_USED,
/*MobMerc*/ NOT_USED,
/*MobBot*/ NOT_USED,
/*MobPet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
// inventory
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion)
{
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
// 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
@@ -742,8 +704,7 @@ uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion)
return NOT_USED;
}
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion)
{
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
// these are for the new inventory system (RoF)..not the current (Ti) one...
// 0x0000000000200000 is SlotPowerSource (SoF+)
// 0x0000000080000000 is SlotGeneral9 (RoF+)
@@ -769,8 +730,7 @@ uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion)
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion)
{
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x00000000005FFFFF,
@@ -791,8 +751,7 @@ uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion)
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion)
{
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000007F800000,
@@ -813,8 +772,7 @@ uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion)
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion)
{
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x0000000200000000,
@@ -835,8 +793,7 @@ uint64 EQLimits::CursorBitmask(ClientVersion clientVersion)
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion)
{
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
@@ -857,8 +814,7 @@ bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion)
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion)
{
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
@@ -879,8 +835,7 @@ bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion)
}
// items
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion)
{
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_COMMON_SIZE,
@@ -900,8 +855,7 @@ uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion)
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion)
{
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_CONTAINER_SIZE,
@@ -921,8 +875,7 @@ uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion)
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::CoinHasWeight(ClientVersion clientVersion)
{
bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ true,
/*62*/ true,
@@ -941,3 +894,63 @@ bool EQLimits::CoinHasWeight(ClientVersion clientVersion)
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandoliersCount(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*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*/ EmuConstants::BANDOLIERS_COUNT,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandolierSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*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*/ EmuConstants::BANDOLIER_SIZE,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::PotionBeltSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*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*/ EmuConstants::POTION_BELT_SIZE,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
+20 -16
View File
@@ -1,7 +1,7 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
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
@@ -42,15 +42,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//using namespace RoF2::maps; // server inventory maps enumeration (code and database sync'd to reference)
//using namespace RoF::slots; // server possessions slots enumeration (code and database sync'd to reference)
class EmuConstants
{
class EmuConstants {
// an immutable value is required to initialize arrays, etc... use this class as a repository for those
public:
// database
static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client
static const size_t CHARACTER_CREATION_LIMIT = RoF2::consts::CHARACTER_CREATION_LIMIT;
// inventory
static uint16 InventoryMapSize(int16 indexMap);
//static std::string InventoryLocationName(Location_Struct location);
@@ -143,18 +140,23 @@ public:
static const uint16 ITEM_COMMON_SIZE = RoF::consts::ITEM_COMMON_SIZE;
static const uint16 ITEM_CONTAINER_SIZE = Titanium::consts::ITEM_CONTAINER_SIZE;
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t BANDOLIERS_SIZE = RoF2::consts::BANDOLIERS_SIZE; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = RoF2::consts::BANDOLIER_ITEM_COUNT; // number of equipment slots in bandolier instance
// player profile
//static const uint32 CLASS_BITMASK = 0; // needs value
//static const uint32 RACE_BITMASK = 0; // needs value
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t POTION_BELT_ITEM_COUNT = RoF2::consts::POTION_BELT_ITEM_COUNT;
// BANDOLIERS_COUNT sets maximum limit..active limit will need to be handled by the appropriate AA
static const uint32 BANDOLIERS_COUNT = Titanium::consts::BANDOLIERS_COUNT; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
static const size_t TEXT_LINK_BODY_LENGTH = RoF2::consts::TEXT_LINK_BODY_LENGTH;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
// legacy-related functions
//static int ServerToPerlSlot(int slot); // encode
//static int PerlToServerSlot(int slot); // decode
};
class EQLimits
{
class EQLimits {
// values should default to a non-beneficial value..unless value conflicts with intended operation
//
// EmuConstants may be used as references..but, not every reference needs to be in EmuConstants (i.e., AllowsEmptyBagInBag(), CoinHasWeight(), etc...)
@@ -172,9 +174,6 @@ public:
static bool IsValidMobClientVersion(ClientVersion clientVersion);
static ClientVersion ValidateMobClientVersion(ClientVersion clientVersion);
// database
static size_t CharacterCreationLimit(ClientVersion clientVersion);
// inventory
static uint16 InventoryMapSize(int16 indexMap, ClientVersion clientVersion);
static uint64 PossessionsBitmask(ClientVersion clientVersion);
@@ -191,6 +190,11 @@ public:
// player profile
static bool CoinHasWeight(ClientVersion clientVersion);
static uint32 BandoliersCount(ClientVersion clientVersion);
static uint32 BandolierSize(ClientVersion clientVersion);
static uint32 PotionBeltSize(ClientVersion clientVersion);
};
#endif /* EQ_DICTIONARY_H */
+38 -77
View File
@@ -40,9 +40,11 @@ EQPacket::EQPacket(EmuOpcode op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
emu_opcode(op)
{
_eqp
}
void EQPacket::build_raw_header_dump(char *buffer, uint16 seq) const {
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -51,17 +53,20 @@ void EQPacket::build_raw_header_dump(char *buffer, uint16 seq) const {
void EQPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
}
void EQPacket::build_header_dump(char *buffer) const {
_eqp
sprintf(buffer, "[EmuOpCode 0x%04x Size=%u]", emu_opcode, size);
}
void EQPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -76,6 +81,7 @@ void EQPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQProtocolPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -84,6 +90,7 @@ void EQProtocolPacket::build_raw_header_dump(char *buffer, uint16 seq) const
void EQProtocolPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -91,11 +98,13 @@ void EQProtocolPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQProtocolPacket::build_header_dump(char *buffer) const
{
_eqp
sprintf(buffer, "[ProtoOpCode 0x%04x Size=%u]",opcode,size);
}
void EQProtocolPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -110,6 +119,7 @@ void EQProtocolPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -122,6 +132,7 @@ void EQApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
void EQApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -129,6 +140,7 @@ void EQApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQApplicationPacket::build_header_dump(char *buffer) const
{
_eqp
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x Size=%u]\n", emu_opcode,size);
#else
@@ -138,6 +150,7 @@ void EQApplicationPacket::build_header_dump(char *buffer) const
void EQApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -156,6 +169,7 @@ void EQApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQRawApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -168,6 +182,7 @@ void EQRawApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) con
void EQRawApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -175,6 +190,7 @@ void EQRawApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQRawApplicationPacket::build_header_dump(char *buffer) const
{
_eqp
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x (0x%04x) Size=%u]\n", emu_opcode, opcode,size);
#else
@@ -184,6 +200,7 @@ void EQRawApplicationPacket::build_header_dump(char *buffer) const
void EQRawApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -202,6 +219,7 @@ void EQRawApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
uint32 EQProtocolPacket::serialize(unsigned char *dest) const
{
_eqp
if (opcode>0xff) {
*(uint16 *)dest=opcode;
} else {
@@ -215,6 +233,7 @@ uint32 EQProtocolPacket::serialize(unsigned char *dest) const
uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
{
_eqp
uint8 OpCodeBytes = app_opcode_size;
if (app_opcode_size==1)
@@ -236,29 +255,10 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
bool result=false;
_eqp
bool result=false;
if (opcode==OP_Combined && size+rhs->size+5<256) {
unsigned char *tmpbuffer=new unsigned char [size+rhs->size+3];
memcpy(tmpbuffer,pBuffer,size);
@@ -284,61 +284,12 @@ bool result=false;
}
return result;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
bool valid=false;
_eqp
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
@@ -357,8 +308,9 @@ bool valid=false;
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
uint32 newlen=0;
uint32 flag_offset=0;
_eqp
uint32 newlen=0;
uint32 flag_offset=0;
newbuf[0]=buffer[0];
if (buffer[0]==0x00) {
flag_offset=2;
@@ -382,7 +334,8 @@ uint32 flag_offset=0;
}
uint32 EQProtocolPacket::Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize) {
uint32 flag_offset=1,newlength;
_eqp
uint32 flag_offset=1,newlength;
//dump_message_column(buffer,length,"Before: ");
newbuf[0]=buffer[0];
if (buffer[0]==0) {
@@ -405,6 +358,7 @@ uint32 flag_offset=1,newlength;
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
_eqp
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
@@ -430,6 +384,7 @@ void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
_eqp
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
@@ -453,10 +408,12 @@ void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
_eqp
return(new EQApplicationPacket(*this));
}
EQRawApplicationPacket *EQProtocolPacket::MakeAppPacket() const {
_eqp
EQRawApplicationPacket *res = new EQRawApplicationPacket(opcode, pBuffer, size);
res->copyInfo(this);
return(res);
@@ -466,10 +423,13 @@ EQRawApplicationPacket::EQRawApplicationPacket(uint16 opcode, const unsigned cha
: EQApplicationPacket(OP_Unknown, buf, len),
opcode(opcode)
{
_eqp
}
EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const uint32 len)
: EQApplicationPacket(OP_Unknown, buf+sizeof(uint16), len-sizeof(uint16))
{
_eqp
if(GetExecutablePlatform() != ExePlatformUCS) {
opcode = *((const uint16 *) buf);
if(opcode == 0x0000)
@@ -503,16 +463,17 @@ EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const u
}
void DumpPacket(const EQApplicationPacket* app, bool iShowInfo) {
_eqp
if (iShowInfo) {
std::cout << "Dumping Applayer: 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec;
std::cout << " size:" << app->size << std::endl;
}
DumpPacketHex(app->pBuffer, app->size);
// DumpPacketAscii(app->pBuffer, app->size);
}
std::string DumpPacketToString(const EQApplicationPacket* app){
_eqp
std::ostringstream out;
out << DumpPacketHexToString(app->pBuffer, app->size);
return out.str();
}
}
+182 -212
View File
@@ -15,7 +15,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQ_PACKET_STRUCTS_H
#define EQ_PACKET_STRUCTS_H
@@ -25,7 +24,7 @@
#include <list>
#include <time.h>
#include "../common/version.h"
//#include "../common/item_data.h"
//#include "../common/item_struct.h"
static const uint32 BUFF_COUNT = 25;
static const uint32 MAX_MERC = 100;
@@ -124,89 +123,83 @@ struct LDoNTrapTemplate
///////////////////////////////////////////////////////////////////////////////
// All clients translate the character select information to some degree
struct Inventory_Slot_Struct
{
int16 type;
int16 slot;
int16 bag;
int16 aug;
};
/*
** Color_Struct
** Size: 4 bytes
** Used for convenience
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct EquipStruct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2; // Same as material?
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/ uint32 heroforgemodel;
/*16*/ uint32 material2; // Same as material?
/*20*/
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
uint32 heroforgemodel;
uint32 material2;
Color_Struct color;
};
// RoF2-based hybrid struct
struct CharacterSelectEntry_Struct
{
char Name[64];
uint8 Class;
uint32 Race;
uint8 Level;
uint8 ShroudClass;
uint32 ShroudRace;
uint16 Zone;
uint16 Instance;
uint8 Gender;
uint8 Face;
CharSelectEquip Equip[9];
uint8 Unknown15; // Seen FF
uint8 Unknown19; // Seen FF
uint32 DrakkinTattoo;
uint32 DrakkinDetails;
uint32 Deity;
uint32 PrimaryIDFile;
uint32 SecondaryIDFile;
uint8 HairColor;
uint8 BeardColor;
uint8 EyeColor1;
uint8 EyeColor2;
uint8 HairStyle;
uint8 Beard;
uint8 GoHome; // Seen 0 for new char and 1 for existing
uint8 Tutorial; // Seen 1 for new char or 0 for existing
uint32 DrakkinHeritage;
uint8 Unknown1; // Seen 0
uint8 Enabled; // Originally labeled as 'CharEnabled' - unknown purpose and setting
uint32 LastLogin;
uint8 Unknown2; // Seen 0
};
struct CharacterSelect_Struct
{
uint32 CharCount; //number of chars in this packet
uint32 TotalChars; //total number of chars allowed?
CharacterSelectEntry_Struct Entries[0];
/*
** Character Selection Struct
** Length: 1704 Bytes
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 race[10]; // Characters Race
/*0040*/ //Color_Struct cs_colors[10][9]; // Characters Equipment Colors
/*0400*/ uint8 beardcolor[10]; // Characters beard Color
/*0410*/ uint8 hairstyle[10]; // Characters hair style
/*0420*/ //uint32 equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
/*0000*/ CharSelectEquip equip[10][9];
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
/*0820*/ uint32 drakkin_heritage[10]; // added for SoF
/*0860*/ uint32 drakkin_tattoo[10]; // added for SoF
/*0900*/ uint32 drakkin_details[10]; // added for SoF
/*0940*/ uint32 deity[10]; // Characters Deity
/*0980*/ uint8 gohome[10]; // 1=Go Home available, 0=not
/*0990*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
/*1000*/ uint8 beard[10]; // Characters Beard Type
/*1010*/ uint8 unknown902[10]; // 10x ff
/*1020*/ uint32 primary[10]; // Characters primary IDFile number
/*1060*/ uint8 haircolor[10]; // Characters Hair Color
/*1070*/ uint8 unknown0962[2]; // 2x 00
/*1072*/ uint32 zone[10]; // Characters Current Zone
/*1112*/ uint8 class_[10]; // Characters Classes
/*1022*/ uint8 face[10]; // Characters Face Type
/*1032*/ char name[10][64]; // Characters Names
/*1672*/ uint8 gender[10]; // Characters Gender
/*1682*/ uint8 eyecolor1[10]; // Characters Eye Color
/*1692*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
/*1702*/ uint8 level[10]; // Characters Levels
/*1712*/
};
/*
@@ -281,8 +274,7 @@ struct Spawn_Struct {
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
/*0147*/ uint8 unknown0147[4];
/*0151*/ uint8 level; // Spawn Level
// None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
/*0152*/ uint32 PlayerState; // Controls animation stuff
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
/*0156*/ uint8 beardcolor; // Beard color
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
@@ -375,11 +367,6 @@ union
};
struct PlayerState_Struct {
/*00*/ uint32 spawn_id;
/*04*/ uint32 state;
};
/*
** New Spawn
** Length: 176 Bytes
@@ -561,7 +548,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*020*/
@@ -574,7 +561,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
@@ -592,8 +579,14 @@ struct BuffRemoveRequest_Struct
struct PetBuff_Struct {
/*000*/ uint32 petid;
/*004*/ uint32 spellid[BUFF_COUNT+5];
/*124*/ int32 ticsremaining[BUFF_COUNT+5];
/*004*/ uint32 spellid[BUFF_COUNT];
/*104*/ uint32 unknown700;
/*108*/ uint32 unknown701;
/*112*/ uint32 unknown702;
/*116*/ uint32 unknown703;
/*120*/ uint32 unknown704;
/*124*/ uint32 ticsremaining[BUFF_COUNT];
/*224*/ uchar unknown705[20];
/*244*/ uint32 buffcount;
};
@@ -734,7 +727,6 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges;
};
@@ -764,46 +756,29 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[EmuConstants::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[EmuConstants::POTION_BELT_ITEM_COUNT];
};
struct MovePotionToBelt_Struct
{
struct MovePotionToBelt_Struct {
uint32 Action;
uint32 SlotNumber;
uint32 ItemID;
@@ -1128,7 +1103,7 @@ struct PlayerProfile_Struct
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_SIZE];
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@@ -1169,7 +1144,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1274,7 +1249,7 @@ struct ZoneChange_Struct {
// Whatever you send to the client in RequestClientZoneChange_Struct.type, the client will send back
// to the server in ZoneChange_Struct.zone_reason. My guess is this is a memo field of sorts.
// 27 January 2008
// WildcardX 27 January 2008
struct RequestClientZoneChange_Struct {
/*00*/ uint16 zone_id;
@@ -1288,8 +1263,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*04*/
};
@@ -1327,9 +1302,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 11 */ uint32 unknown11;
/* 15 */ uint32 sequence; // see above notes in Action_Struct
/* 19 */ uint32 unknown19;
/* 23 */
};
@@ -1566,7 +1541,7 @@ struct DeleteItem_Struct {
/*0012*/
};
struct MoveItemOld_Struct
struct MoveItem_Struct
{
/*0000*/ uint32 from_slot;
/*0004*/ uint32 to_slot;
@@ -1574,19 +1549,6 @@ struct MoveItemOld_Struct
/*0012*/
};
struct MoveItem_Struct
{
int16 from_type;
int16 from_slot;
int16 from_bag_slot;
int16 from_aug_slot;
int16 to_type;
int16 to_slot;
int16 to_bag_slot;
int16 to_aug_slot;
uint32 number_in_stack;
};
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
// info at the moment..but, it is forwarded on to the server for handling/future use)
@@ -1978,11 +1940,13 @@ Unknowns:
struct Merchant_Sell_Struct {
uint32 npcid;
uint32 playerid;
uint32 itemslot;
int32 quantity;
uint32 price;
/*000*/ uint32 npcid; // Merchant NPC's entity id
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown016[3];
/*020*/ uint32 price;
};
struct Merchant_Purchase_Struct {
/*000*/ uint32 npcid; // Merchant NPC's entity id
@@ -2118,7 +2082,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2168,24 +2132,24 @@ struct Illusion_Struct_Old {
// OP_Sound - Size: 68
struct QuestReward_Struct
{
/*000*/ uint32 mob_id; // ID of mob awarding the client
/*004*/ uint32 target_id;
/*008*/ uint32 exp_reward;
/*012*/ uint32 faction;
/*016*/ int32 faction_mod;
/*020*/ uint32 copper; // Gives copper to the client
/*024*/ uint32 silver; // Gives silver to the client
/*028*/ uint32 gold; // Gives gold to the client
/*032*/ uint32 platinum; // Gives platinum to the client
/*036*/ uint32 item_id;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044;
/*048*/ uint32 unknown048;
/*052*/ uint32 unknown052;
/*056*/ uint32 unknown056;
/*060*/ uint32 unknown060;
/*064*/ uint32 unknown064;
/*068*/
/*000*/ uint32 from_mob; // ID of mob awarding the client
/*004*/ uint32 unknown004;
/*008*/ uint32 unknown008;
/*012*/ uint32 unknown012;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020;
/*024*/ uint32 silver; // Gives silver to the client
/*028*/ uint32 gold; // Gives gold to the client
/*032*/ uint32 platinum; // Gives platinum to the client
/*036*/ uint32 unknown036;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044;
/*048*/ uint32 unknown048;
/*052*/ uint32 unknown052;
/*056*/ uint32 unknown056;
/*060*/ uint32 unknown060;
/*064*/ uint32 unknown064;
/*068*/
};
// Size: 8
@@ -2441,11 +2405,11 @@ struct InspectResponse_Struct {
/*004*/ uint32 playerid;
/*008*/ char itemnames[23][64];
/*1480*/uint32 itemicons[23];
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess)
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess) -U
/*1860*/
};
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed)
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed) -U
struct InspectMessage_Struct {
/*000*/ char text[256];
/*256*/
@@ -2554,9 +2518,9 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint16 size; //
/*10*/ uint16 solidtype; //
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint16 unknown008; //
/*10*/ uint16 unknown010; //
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
/*18*/ uint16 zone_instance; //
@@ -2573,8 +2537,8 @@ struct Object_Struct {
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*92*/
};
// 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
@@ -2631,7 +2595,7 @@ struct CloseContainer_Struct {
*/
struct Door_Struct
{
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it //changed both to 32
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it: Daeken M. BlackBlade //changed both to 32: Trevius
/*0032*/ float yPos; // y loc
/*0036*/ float xPos; // x loc
/*0040*/ float zPos; // z loc
@@ -2797,8 +2761,7 @@ struct BazaarWelcome_Struct {
BazaarWindowStart_Struct Beginning;
uint32 Traders;
uint32 Items;
uint32 Unknown012;
uint32 Unknown016;
uint8 Unknown012[8];
};
struct BazaarSearch_Struct {
@@ -3183,7 +3146,6 @@ struct Trader_ShowItems_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Unknown08[3];
/*020*/
};
struct TraderBuy_Struct{
@@ -3229,10 +3191,9 @@ struct TraderDelItem_Struct{
struct TraderClick_Struct{
/*000*/ uint32 TraderID;
/*004*/ uint32 Code;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Approval;
/*016*/
};
struct FormattedMessage_Struct{
@@ -4050,7 +4011,7 @@ struct MarkNPC_Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ int32 tics_remaining[BUFF_COUNT];
/*100*/ uint32 tics_remaining[BUFF_COUNT];
};
struct RaidGeneral_Struct {
@@ -4143,35 +4104,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -4296,6 +4252,14 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -4313,12 +4277,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4566,12 +4530,19 @@ struct InternalVeteranReward
/*012*/ InternalVeteranRewardItem items[8];
};
struct VeteranClaim
struct VeteranClaimReply
{
/*000*/ char name[64]; //name + other data
/*000*/ char name[64];
/*064*/ uint32 claim_id;
/*068*/ uint32 reject_field;
/*072*/ uint32 unknown072;
};
struct VeteranClaimRequest
{
/*000*/ char name_data[64]; //name + other data
/*064*/ uint32 claim_id;
/*068*/ uint32 unknown068;
/*072*/ uint32 action;
};
struct GMSearchCorpse_Struct
@@ -4743,7 +4714,7 @@ struct BuffIconEntry_Struct
{
uint32 buff_slot;
uint32 spell_id;
int32 tics_remaining;
uint32 tics_remaining;
uint32 num_hits;
};
@@ -4752,7 +4723,6 @@ struct BuffIcon_Struct
uint32 entity_id;
uint8 all_buffs;
uint16 count;
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
BuffIconEntry_Struct entries[0];
};
+106 -78
View File
@@ -50,6 +50,7 @@
uint16 EQStream::MaxWindowSize=2048;
void EQStream::init(bool resetSession) {
_eqp
// we only reset these statistics if it is a 'new' connection
if ( resetSession )
{
@@ -72,8 +73,6 @@ void EQStream::init(bool resetSession) {
RateThreshold=RATEBASE/250;
DecayRate=DECAYBASE/250;
BytesWritten=0;
sent_packet_count = 0;
received_packet_count = 0;
SequencedBase = 0;
NextSequencedSend = 0;
@@ -94,6 +93,7 @@ void EQStream::init(bool resetSession) {
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
{
_eqp
EQRawApplicationPacket *ap=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
@@ -103,6 +103,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
{
_eqp
EQRawApplicationPacket *ap=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
ap = new EQRawApplicationPacket(buf, len);
@@ -110,6 +111,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf
}
EQProtocolPacket *EQStream::MakeProtocolPacket(const unsigned char *buf, uint32 len) {
_eqp
uint16 proto_opcode = ntohs(*(const uint16 *)buf);
//advance over opcode.
@@ -121,6 +123,7 @@ EQProtocolPacket *EQStream::MakeProtocolPacket(const unsigned char *buf, uint32
void EQStream::ProcessPacket(EQProtocolPacket *p)
{
_eqp
uint32 processed=0, subpacket_length=0;
if (p == nullptr)
return;
@@ -466,45 +469,37 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_SessionStatRequest: {
if(p->Size() < sizeof(ClientSessionStats))
if(p->Size() < sizeof(SessionStats))
{
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
break;
}
#ifndef COLLECTOR
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
SessionStats *Stats=(SessionStats *)p->pBuffer;
Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
AdjustRates(ntohl(ClientStats->average_delta));
(unsigned long)ntohl(Stats->packets_received), (unsigned long)ntohl(Stats->packets_sent), (unsigned long)ntohl(Stats->last_local_delta),
(unsigned long)ntohl(Stats->low_delta), (unsigned long)ntohl(Stats->average_delta),
(unsigned long)ntohl(Stats->high_delta), (unsigned long)ntohl(Stats->last_remote_delta));
uint64 x=Stats->packets_received;
Stats->packets_received=Stats->packets_sent;
Stats->packets_sent=x;
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse,p->pBuffer,p->size));
AdjustRates(ntohl(Stats->average_delta));
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
if (RETRANSMIT_TIMEOUT_MULT && ntohl(ClientStats->average_delta)) {
if(RETRANSMIT_TIMEOUT_MULT && ntohl(Stats->average_delta)) {
//recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value
if ((ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta)) > (ntohl(ClientStats->average_delta) * 2)) {
retransmittimeout = (ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta))
if((ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) > (ntohl(Stats->average_delta) * 2)) {
retransmittimeout = (ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta))
* RETRANSMIT_TIMEOUT_MULT;
} else {
retransmittimeout = ntohl(ClientStats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
retransmittimeout = ntohl(Stats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
}
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
}
}
ServerSessionStats *ServerStats = (ServerSessionStats *)p->pBuffer;
//ServerStats->RequestID = ClientStats->RequestID; // no change
ServerStats->ServerTime = htonl(Timer::GetCurrentTime());
ServerStats->packets_sent_echo = ClientStats->packets_sent; // still in htonll format
ServerStats->packets_received_echo = ClientStats->packets_received; // still in htonll format
ServerStats->packets_sent = htonll(GetPacketsSent());
ServerStats->packets_received = htonll(GetPacketsReceived());
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse, p->pBuffer, p->size));
#endif
}
break;
@@ -526,6 +521,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
void EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
{
_eqp
if(p == nullptr)
return;
@@ -537,6 +533,7 @@ void EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
{
_eqp
EQApplicationPacket *pack=*p;
*p = nullptr; //clear caller's pointer.. effectively takes ownership
@@ -566,6 +563,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
{
_eqp
uint32 chunksize, used;
uint32 length;
@@ -583,18 +581,16 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->size);
unsigned char *tmpbuff=new unsigned char[p->size+3];
length=p->serialize(opcode, tmpbuff);
if (length != p->Size())
Log.Out(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
EQProtocolPacket *out=new EQProtocolPacket(OP_Fragment,nullptr,MaxLen-4);
*(uint32 *)(out->pBuffer+2)=htonl(length);
*(uint32 *)(out->pBuffer+2)=htonl(p->Size());
used=MaxLen-10;
memcpy(out->pBuffer+6,tmpbuff,used);
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Put size %d in the packet" __L, used, p->size, p->Size());
SequencedPush(out);
@@ -605,7 +601,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
out->size=chunksize+2;
SequencedPush(out);
used+=chunksize;
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, p->size);
}
delete p;
delete[] tmpbuff;
@@ -624,34 +620,36 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
void EQStream::SequencedPush(EQProtocolPacket *p)
{
_eqp
#ifdef COLLECTOR
delete p;
#else
MOutboundQueue.lock();
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, NextOutSeq, p->size, SequencedBase);
*(uint16 *)(p->pBuffer)=htons(NextOutSeq);
SequencedQueue.push_back(p);
NextOutSeq++;
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
MOutboundQueue.unlock();
#endif
}
void EQStream::NonSequencedPush(EQProtocolPacket *p)
{
_eqp
#ifdef COLLECTOR
delete p;
#else
@@ -664,7 +662,8 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
void EQStream::SendAck(uint16 seq)
{
uint16 Seq=htons(seq);
_eqp
uint16 Seq=htons(seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
SetLastAckSent(seq);
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
@@ -672,8 +671,9 @@ uint16 Seq=htons(seq);
void EQStream::SendOutOfOrderAck(uint16 seq)
{
_eqp
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
uint16 Seq=htons(seq);
uint16 Seq=htons(seq);
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
}
@@ -874,8 +874,9 @@ void EQStream::Write(int eq_fd)
void EQStream::WritePacket(int eq_fd, EQProtocolPacket *p)
{
uint32 length;
sockaddr_in address;
_eqp
uint32 length;
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr=remote_ip;
address.sin_port=remote_port;
@@ -912,7 +913,8 @@ sockaddr_in address;
void EQStream::SendSessionResponse()
{
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
_eqp
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
SessionResponse *Response=(SessionResponse *)out->pBuffer;
Response->Session=htonl(Session);
Response->MaxLength=htonl(MaxLen);
@@ -934,7 +936,8 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(Ses
void EQStream::SendSessionRequest()
{
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(SessionRequest));
_eqp
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(SessionRequest));
SessionRequest *Request=(SessionRequest *)out->pBuffer;
memset(Request,0,sizeof(SessionRequest));
Request->Session=htonl(time(nullptr));
@@ -947,6 +950,7 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(Sess
void EQStream::_SendDisconnect()
{
_eqp
if(GetState() == CLOSED)
return;
@@ -959,6 +963,7 @@ void EQStream::_SendDisconnect()
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
{
_eqp
MInboundQueue.lock();
InboundQueue.push_back(p);
MInboundQueue.unlock();
@@ -966,7 +971,8 @@ void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
EQApplicationPacket *EQStream::PopPacket()
{
EQRawApplicationPacket *p=nullptr;
_eqp
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -991,7 +997,8 @@ EQRawApplicationPacket *p=nullptr;
EQRawApplicationPacket *EQStream::PopRawPacket()
{
EQRawApplicationPacket *p=nullptr;
_eqp
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -1018,7 +1025,8 @@ EQRawApplicationPacket *p=nullptr;
EQRawApplicationPacket *EQStream::PeekPacket()
{
EQRawApplicationPacket *p=nullptr;
_eqp
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -1032,7 +1040,8 @@ EQRawApplicationPacket *p=nullptr;
void EQStream::InboundQueueClear()
{
EQApplicationPacket *p=nullptr;
_eqp
EQApplicationPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
@@ -1050,7 +1059,8 @@ EQApplicationPacket *p=nullptr;
bool EQStream::HasOutgoingData()
{
bool flag;
_eqp
bool flag;
//once closed, we have nothing more to say
if(CheckClosed())
@@ -1075,7 +1085,8 @@ bool flag;
void EQStream::OutboundQueueClear()
{
EQProtocolPacket *p=nullptr;
_eqp
EQProtocolPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
@@ -1097,7 +1108,8 @@ EQProtocolPacket *p=nullptr;
void EQStream::PacketQueueClear()
{
EQProtocolPacket *p=nullptr;
_eqp
EQProtocolPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
@@ -1113,6 +1125,7 @@ EQProtocolPacket *p=nullptr;
void EQStream::Process(const unsigned char *buffer, const uint32 length)
{
_eqp
static unsigned char newbuffer[2048];
uint32 newlength=0;
if (EQProtocolPacket::ValidateCRC(buffer,length,Key)) {
@@ -1137,6 +1150,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
long EQStream::GetNextAckToSend()
{
_eqp
MAcks.lock();
long l=NextAckToSend;
MAcks.unlock();
@@ -1146,6 +1160,7 @@ long EQStream::GetNextAckToSend()
long EQStream::GetLastAckSent()
{
_eqp
MAcks.lock();
long l=LastAckSent;
MAcks.unlock();
@@ -1155,16 +1170,17 @@ long EQStream::GetLastAckSent()
void EQStream::AckPackets(uint16 seq)
{
std::deque<EQProtocolPacket *>::iterator itr, tmp;
_eqp
std::deque<EQProtocolPacket *>::iterator itr, tmp;
MOutboundQueue.lock();
//do a bit of sanity checking.
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
//do a bit of sanity checking.
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
SeqOrder ord = CompareSequence(SequencedBase, seq);
if(ord == SeqInOrder) {
@@ -1180,12 +1196,12 @@ if(NextSequencedSend > SequencedQueue.size()) {
//this is a good ack, we get to ack some blocks.
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
while(SequencedBase != seq) {
if(SequencedQueue.empty()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
SequencedBase = NextOutSeq;
NextSequencedSend = 0;
break;
}
if(SequencedQueue.empty()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
SequencedBase = NextOutSeq;
NextSequencedSend = 0;
break;
}
Log.Out(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
//clean out the acked packet
delete SequencedQueue.front();
@@ -1196,12 +1212,12 @@ Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequen
//advance the base sequence number to the seq of the block after the one we just got rid of.
SequencedBase++;
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
}
MOutboundQueue.unlock();
@@ -1209,6 +1225,7 @@ if(NextSequencedSend > SequencedQueue.size()) {
void EQStream::SetNextAckToSend(uint32 seq)
{
_eqp
MAcks.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
NextAckToSend=seq;
@@ -1217,6 +1234,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
void EQStream::SetLastAckSent(uint32 seq)
{
_eqp
MAcks.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
LastAckSent=seq;
@@ -1225,6 +1243,7 @@ void EQStream::SetLastAckSent(uint32 seq)
void EQStream::ProcessQueue()
{
_eqp
if(PacketQueue.empty()) {
return;
}
@@ -1240,8 +1259,9 @@ void EQStream::ProcessQueue()
EQProtocolPacket *EQStream::RemoveQueue(uint16 seq)
{
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
EQProtocolPacket *qp=nullptr;
_eqp
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
EQProtocolPacket *qp=nullptr;
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
qp=itr->second;
PacketQueue.erase(itr);
@@ -1252,6 +1272,7 @@ EQProtocolPacket *qp=nullptr;
void EQStream::SetStreamType(EQStreamType type)
{
_eqp
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
StreamType=type;
switch (StreamType) {
@@ -1282,6 +1303,7 @@ void EQStream::SetStreamType(EQStreamType type)
const char *EQStream::StreamTypeString(EQStreamType t)
{
_eqp
switch (t) {
case LoginStream:
return "Login";
@@ -1311,6 +1333,7 @@ const char *EQStream::StreamTypeString(EQStreamType t)
//returns SeqFuture if `seq` is later than `expected_seq`
EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
{
_eqp
if (expected_seq==seq) {
// Curent
return SeqInOrder;
@@ -1324,6 +1347,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
}
void EQStream::SetState(EQStreamState state) {
_eqp
MState.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
State=state;
@@ -1332,7 +1356,7 @@ void EQStream::SetState(EQStreamState state) {
void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
_eqp
bool outgoing_data = HasOutgoingData(); //up here to avoid recursive locking
EQStreamState orig_state = GetState();
@@ -1371,6 +1395,7 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
void EQStream::Decay()
{
_eqp
MRate.lock();
uint32 rate=DecayRate;
MRate.unlock();
@@ -1383,6 +1408,7 @@ void EQStream::Decay()
void EQStream::AdjustRates(uint32 average_delta)
{
_eqp
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
if (average_delta && (average_delta <= AVERAGE_DELTA_MAX)) {
MRate.lock();
@@ -1408,6 +1434,7 @@ void EQStream::AdjustRates(uint32 average_delta)
}
void EQStream::Close() {
_eqp
if(HasOutgoingData()) {
//there is pending data, wait for it to go out.
Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
@@ -1424,6 +1451,7 @@ void EQStream::Close() {
//this could be expanded to check more than the fitst opcode if
//we needed more complex matching
EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
_eqp
EQRawApplicationPacket *p = nullptr;
MatchState res = MatchNotReady;
+1 -19
View File
@@ -71,7 +71,7 @@ struct SessionResponse {
};
//Deltas are in ms, representing round trip times
struct ClientSessionStats {
struct SessionStats {
/*000*/ uint16 RequestID;
/*002*/ uint32 last_local_delta;
/*006*/ uint32 average_delta;
@@ -83,16 +83,6 @@ struct ClientSessionStats {
/*038*/
};
struct ServerSessionStats {
/*000*/ uint16 RequestID;
/*002*/ uint32 ServerTime;
/*006*/ uint64 packets_sent_echo;
/*014*/ uint64 packets_received_echo;
/*022*/ uint64 packets_sent;
/*030*/ uint64 packets_received;
/*038*/
};
#pragma pack()
class OpcodeManager;
@@ -168,9 +158,6 @@ class EQStream : public EQStreamInterface {
int32 BytesWritten;
uint64 sent_packet_count;
uint64 received_packet_count;
Mutex MRate;
int32 RateThreshold;
int32 DecayRate;
@@ -278,13 +265,11 @@ class EQStream : public EQStreamInterface {
void AddBytesSent(uint32 bytes)
{
bytes_sent += bytes;
++sent_packet_count;
}
void AddBytesRecv(uint32 bytes)
{
bytes_recv += bytes;
++received_packet_count;
}
virtual const uint32 GetBytesSent() const { return bytes_sent; }
@@ -303,9 +288,6 @@ class EQStream : public EQStreamInterface {
return bytes_recv / (Timer::GetTimeSeconds() - create_time);
}
const uint64 GetPacketsSent() { return sent_packet_count; }
const uint64 GetPacketsReceived() { return received_packet_count; }
//used for dynamic stream identification
class Signature {
public:
+13 -3
View File
@@ -23,7 +23,8 @@
ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
_eqp
EQStreamFactory *fs = (EQStreamFactory*)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self());
@@ -40,7 +41,8 @@ EQStreamFactory *fs=(EQStreamFactory *)eqfs;
ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
_eqp
EQStreamFactory *fs = (EQStreamFactory*)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
@@ -58,6 +60,7 @@ ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
EQStreamFactory::EQStreamFactory(EQStreamType type, int port, uint32 timeout)
: Timeoutable(5000), stream_timeout(timeout)
{
_eqp
StreamType=type;
Port=port;
sock=-1;
@@ -65,6 +68,7 @@ EQStreamFactory::EQStreamFactory(EQStreamType type, int port, uint32 timeout)
void EQStreamFactory::Close()
{
_eqp
Stop();
#ifdef _WINDOWS
@@ -77,7 +81,8 @@ void EQStreamFactory::Close()
bool EQStreamFactory::Open()
{
struct sockaddr_in address;
_eqp
struct sockaddr_in address;
#ifndef WIN32
pthread_t t1,t2;
#endif
@@ -118,6 +123,7 @@ struct sockaddr_in address;
std::shared_ptr<EQStream> EQStreamFactory::Pop()
{
_eqp
std::shared_ptr<EQStream> s = nullptr;
MNewStreams.lock();
if (NewStreams.size()) {
@@ -132,6 +138,7 @@ std::shared_ptr<EQStream> EQStreamFactory::Pop()
void EQStreamFactory::Push(std::shared_ptr<EQStream> s)
{
_eqp
MNewStreams.lock();
NewStreams.push(s);
MNewStreams.unlock();
@@ -139,6 +146,7 @@ void EQStreamFactory::Push(std::shared_ptr<EQStream> s)
void EQStreamFactory::ReaderLoop()
{
_eqp
fd_set readset;
std::map<std::pair<uint32, uint16>, std::shared_ptr<EQStream>>::iterator stream_itr;
int num;
@@ -216,6 +224,7 @@ void EQStreamFactory::ReaderLoop()
void EQStreamFactory::CheckTimeout()
{
_eqp
//lock streams the entire time were checking timeouts, it should be fast.
MStreams.lock();
@@ -250,6 +259,7 @@ void EQStreamFactory::CheckTimeout()
void EQStreamFactory::WriterLoop()
{
_eqp
std::map<std::pair<uint32, uint16>, std::shared_ptr<EQStream>>::iterator stream_itr;
bool havework=true;
std::vector<std::shared_ptr<EQStream>> wants_write;
+11
View File
@@ -28,6 +28,7 @@ EQEmuConfig *EQEmuConfig::_config = nullptr;
void EQEmuConfig::do_world(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement * sub_ele;;
text = ParseTextBlock(ele, "shortname");
@@ -145,6 +146,7 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
void EQEmuConfig::do_chatserver(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -158,6 +160,7 @@ void EQEmuConfig::do_chatserver(TiXmlElement *ele)
void EQEmuConfig::do_mailserver(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -171,6 +174,7 @@ void EQEmuConfig::do_mailserver(TiXmlElement *ele)
void EQEmuConfig::do_database(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -197,6 +201,7 @@ void EQEmuConfig::do_database(TiXmlElement *ele)
void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -222,6 +227,7 @@ void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
void EQEmuConfig::do_zones(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement *sub_ele;
// TiXmlNode *node,*sub_node;
@@ -245,6 +251,7 @@ void EQEmuConfig::do_zones(TiXmlElement *ele)
void EQEmuConfig::do_files(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "spells", true);
if (text) {
@@ -262,6 +269,7 @@ void EQEmuConfig::do_files(TiXmlElement *ele)
void EQEmuConfig::do_directories(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "maps", true);
if (text) {
@@ -279,6 +287,7 @@ void EQEmuConfig::do_directories(TiXmlElement *ele)
void EQEmuConfig::do_launcher(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement *sub_ele;
text = ParseTextBlock(ele, "logprefix", true);
@@ -318,6 +327,7 @@ void EQEmuConfig::do_launcher(TiXmlElement *ele)
std::string EQEmuConfig::GetByName(const std::string &var_name) const
{
_eqp
if (var_name == "ShortName") {
return (ShortName);
}
@@ -445,6 +455,7 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
void EQEmuConfig::Dump() const
{
_eqp
std::cout << "ShortName = " << ShortName << std::endl;
std::cout << "LongName = " << LongName << std::endl;
std::cout << "WorldAddress = " << WorldAddress << std::endl;
+5 -2
View File
@@ -96,6 +96,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID);
/* Set Defaults */
log_settings[Logs::LoginServer].log_to_console = Logs::General;
log_settings[Logs::World_Server].log_to_console = Logs::General;
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
log_settings[Logs::QS_Server].log_to_console = Logs::General;
@@ -116,7 +117,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
platform_file_name = "ucs";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
platform_file_name = "login";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
platform_file_name = "launcher";
}
@@ -272,12 +273,14 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
_eqp
const bool log_to_console = log_settings[log_category].log_to_console > 0;
const bool log_to_file = log_settings[log_category].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0;
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log) return;
if (nothing_to_log)
return;
va_list args;
va_start(args, message);
+6 -2
View File
@@ -48,12 +48,14 @@ namespace Logs {
Combat,
Commands,
Crash,
Database,
Debug,
Doors,
Error,
Guilds,
Inventory,
Launcher,
LoginServer,
Netcode,
Normal,
Object,
@@ -96,12 +98,14 @@ namespace Logs {
"Combat",
"Commands",
"Crash",
"Database",
"Debug",
"Doors",
"Error",
"Guilds",
"Inventory",
"Launcher",
"LoginServer",
"Netcode",
"Normal",
"Object",
@@ -122,8 +126,8 @@ namespace Logs {
"WebInterface Server",
"World Server",
"Zone Server",
"MySQL Error",
"MySQL Query",
"MySQLError",
"MySQLQuery",
"Mercenaries",
"Quest Debug",
"Packet :: Server -> Client",
+42 -41
View File
@@ -43,19 +43,19 @@ EQTime::EQTime(TimeOfDay_Struct start_eq, time_t start_real)
EQTime::EQTime()
{
timezone = 0;
timezone=0;
memset(&eqTime, 0, sizeof(eqTime));
//Defaults for time
TimeOfDay_Struct start;
start.day = 1;
start.hour = 9;
start.minute = 0;
start.month = 1;
start.year = 3100;
start.day=1;
start.hour=9;
start.minute=0;
start.month=1;
start.year=3100;
//Set default time zone
timezone = 0;
timezone=0;
//Start EQTimer
SetCurrentEQTimeOfDay(start, time(0));
setEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
@@ -67,10 +67,10 @@ EQTime::~EQTime()
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
//Output: 0=Error, 1=Sucess
int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay)
int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay )
{
/* check to see if we have a reference time to go by. */
if (eqTime.start_realtime == 0)
if( eqTime.start_realtime == 0 )
return 0;
unsigned long diff = timeConvert - eqTime.start_realtime;
@@ -83,7 +83,7 @@ int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *e
int32 ntz = timezone;
/* The minutes range from 0 - 59 */
diff += eqTime.start_eqtime.minute + (ntz % 60);
diff += eqTime.start_eqtime.minute + (ntz%60);
eqTimeOfDay->minute = diff % 60;
diff /= 60;
ntz /= 60;
@@ -97,24 +97,24 @@ int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *e
//
// Modify it so that it works from
// 0-23 for our calculations
diff += (eqTime.start_eqtime.hour - 1) + (ntz % 24);
eqTimeOfDay->hour = (diff % 24) + 1;
diff += ( eqTime.start_eqtime.hour - 1) + (ntz%24);
eqTimeOfDay->hour = (diff%24) + 1;
diff /= 24;
ntz /= 24;
// The days range from 1-28
// Modify it so that it works from
// 0-27 for our calculations
diff += (eqTime.start_eqtime.day - 1) + (ntz % 28);
eqTimeOfDay->day = (diff % 28) + 1;
diff += ( eqTime.start_eqtime.day - 1 ) + (ntz%28);
eqTimeOfDay->day = (diff%28) + 1;
diff /= 28;
ntz /= 28;
// The months range from 1-12
// Modify it so that it works from
// 0-11 for our calculations
diff += (eqTime.start_eqtime.month - 1) + (ntz % 12);
eqTimeOfDay->month = (diff % 12) + 1;
diff += ( eqTime.start_eqtime.month - 1 ) + (ntz%12);
eqTimeOfDay->month = (diff%12) + 1;
diff /= 12;
ntz /= 12;
@@ -124,12 +124,12 @@ int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *e
}
//setEQTimeOfDay
int EQTime::SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
int EQTime::setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
{
if (start_real == 0)
if(start_real==0)
return 0;
eqTime.start_eqtime = start_eq;
eqTime.start_realtime = start_real;
eqTime.start_eqtime=start_eq;
eqTime.start_realtime=start_real;
return 1;
}
@@ -139,7 +139,7 @@ bool EQTime::saveFile(const char *filename)
{
std::ofstream of;
of.open(filename);
if (!of)
if(!of)
{
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
return false;
@@ -200,24 +200,24 @@ bool EQTime::loadFile(const char *filename)
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
if (base->year > test->year)
if(base->year > test->year)
return(true);
if (base->year < test->year)
if(base->year < test->year)
return(false);
//same years
if (base->month > test->month)
if(base->month > test->month)
return(true);
if (base->month < test->month)
if(base->month < test->month)
return(false);
//same month
if (base->day > test->day)
if(base->day > test->day)
return(true);
if (base->day < test->day)
if(base->day < test->day)
return(false);
//same day
if (base->hour > test->hour)
if(base->hour > test->hour)
return(true);
if (base->hour < test->hour)
if(base->hour < test->hour)
return(false);
//same hour...
return(base->minute > test->minute);
@@ -230,7 +230,7 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
//minutes start at 0, everything else starts at 1
cur = to->minute;
cur += minutes;
if (cur < 60) {
if(cur < 60) {
to->minute = cur;
return;
}
@@ -238,29 +238,29 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
//carry hours
cur /= 60;
cur += to->hour;
if (cur <= 24) {
if(cur <= 24) {
to->hour = cur;
return;
}
to->hour = ((cur - 1) % 24) + 1;
to->hour = ((cur-1) % 24) + 1;
//carry days
cur = (cur - 1) / 24;
cur = (cur-1) / 24;
cur += to->day;
if (cur <= 28) {
if(cur <= 28) {
to->day = cur;
return;
}
to->day = ((cur - 1) % 28) + 1;
to->day = ((cur-1) % 28) + 1;
//carry months
cur = (cur - 1) / 28;
cur = (cur-1) / 28;
cur += to->month;
if (cur <= 12) {
if(cur <= 12) {
to->month = cur;
return;
}
to->month = ((cur - 1) % 12) + 1;
to->month = ((cur-1) % 12) + 1;
//carry years
to->year += (cur - 1) / 12;
to->year += (cur-1) / 12;
}
void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
@@ -269,4 +269,5 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
}
+3 -3
View File
@@ -21,8 +21,8 @@ public:
~EQTime();
//Get functions
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
int GetCurrentEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
int getEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(getEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
int getEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
TimeOfDay_Struct getStartEQTime() { return eqTime.start_eqtime; }
time_t getStartRealTime() { return eqTime.start_realtime; }
uint32 getEQTimeZone() { return timezone; }
@@ -30,7 +30,7 @@ public:
uint32 getEQTimeZoneMin() { return timezone%60; }
//Set functions
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
int setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
void setEQTimeZone(int32 in_timezone) { timezone=in_timezone; }
//Time math/logic functions
+1
View File
@@ -26,6 +26,7 @@ void InitExtendedProfile(ExtendedProfile_Struct *p) {
}
bool SetExtendedProfile(ExtendedProfile_Struct *to, char *old, unsigned int len) {
_eqp
if(len == 0 || old == nullptr) {
//handle old chars without an extended profile...
InitExtendedProfile(to);
+4
View File
@@ -21,6 +21,7 @@
const char *FactionValueToString(FACTION_VALUE fv)
{
_eqp
switch (fv) {
case FACTION_ALLY:
return ("Ally");
@@ -55,6 +56,7 @@ const char *FactionValueToString(FACTION_VALUE fv)
//o--------------------------------------------------------------
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
{
_eqp
int32 character_value = tmpCharacter_value;
if (fm) {
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
@@ -92,6 +94,7 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
// this function should check if some races have more than one race define
bool IsOfEqualRace(int r1, int r2)
{
_eqp
if (r1 == r2) {
return true;
}
@@ -113,6 +116,7 @@ bool IsOfEqualRace(int r1, int r2)
// trolls endure ogres, dark elves, ...
bool IsOfIndiffRace(int r1, int r2)
{
_eqp
if (r1 == r2) {
return true;
}
+57 -3
View File
@@ -39,10 +39,8 @@ BaseGuildManager::~BaseGuildManager() {
ClearGuilds();
}
bool BaseGuildManager::LoadGuilds() {
_eqp
ClearGuilds();
if(m_db == nullptr) {
@@ -104,6 +102,7 @@ bool BaseGuildManager::LoadGuilds() {
}
bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to refresh guild %d when we have no database object.", guild_id);
return(false);
@@ -169,6 +168,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, const char *guild_name, uint32 leader_char_id, uint8 minstatus, const char *guild_motd, const char *motd_setter, const char *Channel, const char *URL)
{
_eqp
std::map<uint32, GuildInfo *>::iterator res;
//remove any old entry.
@@ -213,6 +213,7 @@ BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, con
}
bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to store guild %d when we have no database object.", guild_id);
return(false);
@@ -295,6 +296,7 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
}
uint32 BaseGuildManager::_GetFreeGuildID() {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested find a free guild ID when we have no database object.");
return(GUILD_NONE);
@@ -342,6 +344,7 @@ uint32 BaseGuildManager::_GetFreeGuildID() {
uint32 BaseGuildManager::CreateGuild(const char* name, uint32 leader_char_id) {
_eqp
uint32 gid = DBCreateGuild(name, leader_char_id);
if(gid == GUILD_NONE)
return(GUILD_NONE);
@@ -353,6 +356,7 @@ uint32 BaseGuildManager::CreateGuild(const char* name, uint32 leader_char_id) {
}
bool BaseGuildManager::DeleteGuild(uint32 guild_id) {
_eqp
if(!DBDeleteGuild(guild_id))
return(false);
@@ -362,6 +366,7 @@ bool BaseGuildManager::DeleteGuild(uint32 guild_id) {
}
bool BaseGuildManager::RenameGuild(uint32 guild_id, const char* name) {
_eqp
if(!DBRenameGuild(guild_id, name))
return(false);
@@ -371,6 +376,7 @@ bool BaseGuildManager::RenameGuild(uint32 guild_id, const char* name) {
}
bool BaseGuildManager::SetGuildLeader(uint32 guild_id, uint32 leader_char_id) {
_eqp
//get old leader first.
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
@@ -390,6 +396,7 @@ bool BaseGuildManager::SetGuildLeader(uint32 guild_id, uint32 leader_char_id) {
}
bool BaseGuildManager::SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
_eqp
if(!DBSetGuildMOTD(guild_id, motd, setter))
return(false);
@@ -400,6 +407,7 @@ bool BaseGuildManager::SetGuildMOTD(uint32 guild_id, const char* motd, const cha
bool BaseGuildManager::SetGuildURL(uint32 GuildID, const char* URL)
{
_eqp
if(!DBSetGuildURL(GuildID, URL))
return(false);
@@ -410,6 +418,7 @@ bool BaseGuildManager::SetGuildURL(uint32 GuildID, const char* URL)
bool BaseGuildManager::SetGuildChannel(uint32 GuildID, const char* Channel)
{
_eqp
if(!DBSetGuildChannel(GuildID, Channel))
return(false);
@@ -419,6 +428,7 @@ bool BaseGuildManager::SetGuildChannel(uint32 GuildID, const char* Channel)
}
bool BaseGuildManager::SetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
_eqp
if(rank > GUILD_MAX_RANK && guild_id != GUILD_NONE)
return(false);
@@ -439,6 +449,7 @@ bool BaseGuildManager::SetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
//changes rank, but not guild.
bool BaseGuildManager::SetGuildRank(uint32 charid, uint8 rank) {
_eqp
if(rank > GUILD_MAX_RANK)
return(false);
@@ -452,6 +463,7 @@ bool BaseGuildManager::SetGuildRank(uint32 charid, uint8 rank) {
bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
_eqp
if(!DBSetBankerFlag(charid, is_banker))
return(false);
@@ -461,12 +473,14 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
}
bool BaseGuildManager::ForceRankUpdate(uint32 charid) {
_eqp
SendRankUpdate(charid);
return(true);
}
bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
{
_eqp
if(!DBSetAltFlag(charid, is_alt))
return(false);
@@ -476,6 +490,7 @@ bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
}
bool BaseGuildManager::SetTributeFlag(uint32 charid, bool enabled) {
_eqp
if(!DBSetTributeFlag(charid, enabled))
return(false);
@@ -485,6 +500,7 @@ bool BaseGuildManager::SetTributeFlag(uint32 charid, bool enabled) {
}
bool BaseGuildManager::SetPublicNote(uint32 charid, const char *note) {
_eqp
if(!DBSetPublicNote(charid, note))
return(false);
@@ -494,6 +510,7 @@ bool BaseGuildManager::SetPublicNote(uint32 charid, const char *note) {
}
uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
_eqp
//first try to find a free ID.
uint32 new_id = _GetFreeGuildID();
if(new_id == GUILD_NONE)
@@ -515,6 +532,7 @@ uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
}
bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
_eqp
//remove the local entry
std::map<uint32, GuildInfo *>::iterator res;
@@ -551,6 +569,7 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
}
bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to rename guild %d when we have no database object.", guild_id);
return false;
@@ -587,6 +606,7 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
}
bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set the leader for guild %d when we have no database object.", guild_id);
return false;
@@ -622,6 +642,7 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
}
bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set the MOTD for guild %d when we have no database object.", guild_id);
return(false);
@@ -664,6 +685,7 @@ bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const c
bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
{
_eqp
if(m_db == nullptr)
return false;
@@ -697,6 +719,7 @@ bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
{
_eqp
if(m_db == nullptr)
return(false);
@@ -730,6 +753,7 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
}
bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set char to guild %d when we have no database object.", guild_id);
return(false);
@@ -758,11 +782,13 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
}
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET rank=%d WHERE char_id=%d", rank, charid);
return(QueryWithLogging(query, "setting a guild member's rank"));
}
bool BaseGuildManager::DBSetBankerFlag(uint32 charid, bool is_banker) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET banker=%d WHERE char_id=%d",
is_banker? 1: 0, charid);
return(QueryWithLogging(query, "setting a guild member's banker flag"));
@@ -770,6 +796,7 @@ bool BaseGuildManager::DBSetBankerFlag(uint32 charid, bool is_banker) {
bool BaseGuildManager::GetBankerFlag(uint32 CharID)
{
_eqp
if(!m_db)
return false;
@@ -792,6 +819,7 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
{
_eqp
std::string query = StringFormat("UPDATE guild_members SET alt=%d WHERE char_id=%d",
is_alt ? 1: 0, charid);
@@ -800,6 +828,7 @@ bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
bool BaseGuildManager::GetAltFlag(uint32 CharID)
{
_eqp
if(!m_db)
return false;
@@ -821,12 +850,14 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
}
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET tribute_enable=%d WHERE char_id=%d",
enabled ? 1: 0, charid);
return(QueryWithLogging(query, "setting a guild member's tribute flag"));
}
bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
_eqp
if(m_db == nullptr)
return(false);
@@ -851,6 +882,7 @@ bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
}
bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
_eqp
if(m_db == nullptr)
return(false);
@@ -879,6 +911,7 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
" FROM `character_data` AS c LEFT JOIN guild_members AS g ON c.id=g.char_id "
#endif
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
_eqp
//fields from `characer_`
into.char_id = atoi(row[0]);
into.char_name = row[1];
@@ -906,6 +939,7 @@ static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo *> &members) {
_eqp
members.clear();
if(m_db == nullptr)
@@ -930,6 +964,7 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
}
bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested char info on %s when we have no database object.", char_name);
return(false);
@@ -961,6 +996,7 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
}
bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested char info on %d when we have no database object.", char_id);
return false;
@@ -991,6 +1027,7 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
//returns ownership of the buffer.
uint8 *BaseGuildManager::MakeGuildList(const char *head_name, uint32 &length) const {
_eqp
//dynamic structs will make this a lot less painful.
length = sizeof(GuildsList_Struct);
@@ -1018,6 +1055,7 @@ uint8 *BaseGuildManager::MakeGuildList(const char *head_name, uint32 &length) co
}
const char *BaseGuildManager::GetRankName(uint32 guild_id, uint8 rank) const {
_eqp
if(rank > GUILD_MAX_RANK)
return("Invalid Rank");
std::map<uint32, GuildInfo *>::const_iterator res;
@@ -1028,6 +1066,7 @@ const char *BaseGuildManager::GetRankName(uint32 guild_id, uint8 rank) const {
}
const char *BaseGuildManager::GetGuildName(uint32 guild_id) const {
_eqp
if(guild_id == GUILD_NONE)
return("");
std::map<uint32, GuildInfo *>::const_iterator res;
@@ -1038,6 +1077,7 @@ const char *BaseGuildManager::GetGuildName(uint32 guild_id) const {
}
bool BaseGuildManager::GetGuildNameByID(uint32 guild_id, std::string &into) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1048,6 +1088,7 @@ bool BaseGuildManager::GetGuildNameByID(uint32 guild_id, std::string &into) cons
uint32 BaseGuildManager::GetGuildIDByName(const char *GuildName)
{
_eqp
std::map<uint32, GuildInfo *>::iterator Iterator;
for(Iterator = m_guilds.begin(); Iterator != m_guilds.end(); ++Iterator)
@@ -1060,6 +1101,7 @@ uint32 BaseGuildManager::GetGuildIDByName(const char *GuildName)
}
bool BaseGuildManager::GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *setter_buffer) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1071,6 +1113,7 @@ bool BaseGuildManager::GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *se
bool BaseGuildManager::GetGuildURL(uint32 GuildID, char *URLBuffer) const
{
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(GuildID);
if(res == m_guilds.end())
@@ -1082,6 +1125,7 @@ bool BaseGuildManager::GetGuildURL(uint32 GuildID, char *URLBuffer) const
bool BaseGuildManager::GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const
{
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(GuildID);
if(res == m_guilds.end())
@@ -1091,12 +1135,14 @@ bool BaseGuildManager::GetGuildChannel(uint32 GuildID, char *ChannelBuffer) cons
}
bool BaseGuildManager::GuildExists(uint32 guild_id) const {
_eqp
if(guild_id == GUILD_NONE)
return(false);
return(m_guilds.find(guild_id) != m_guilds.end());
}
bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
_eqp
if(guild_id == GUILD_NONE) {
Log.Out(Logs::Detail, Logs::Guilds, "Check leader for char %d: not a guild.", char_id);
return(false);
@@ -1112,6 +1158,7 @@ bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
}
uint32 BaseGuildManager::FindGuildByLeader(uint32 leader) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator cur, end;
cur = m_guilds.begin();
end = m_guilds.end();
@@ -1124,6 +1171,7 @@ uint32 BaseGuildManager::FindGuildByLeader(uint32 leader) const {
//returns the rank to be sent to the client for display purposes, given their eqemu rank.
uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1136,6 +1184,7 @@ uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 cha
}
bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
_eqp
if(status >= 250) {
Log.Out(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d > 250, granted.", guild_id, status);
return(true); //250+ as allowed anything
@@ -1157,6 +1206,7 @@ bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
}
bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const {
_eqp
if(rank > GUILD_MAX_RANK) {
Log.Out(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid rank, denied.",
guild_id, rank, GuildActionNames[act], act);
@@ -1182,6 +1232,7 @@ bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction
}
bool BaseGuildManager::LocalDeleteGuild(uint32 guild_id) {
_eqp
std::map<uint32, GuildInfo *>::iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1201,18 +1252,21 @@ void BaseGuildManager::ClearGuilds() {
}
BaseGuildManager::RankInfo::RankInfo() {
_eqp
uint8 r;
for(r = 0; r < _MaxGuildAction; r++)
permissions[r] = false;
}
BaseGuildManager::GuildInfo::GuildInfo() {
_eqp
leader_char_id = 0;
minstatus = 0;
}
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
{
_eqp
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id IN "
"(SELECT id FROM `character_data` WHERE account_id = %i) AND rank = 2",
AccountID);
-782
View File
@@ -1,782 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 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 "inventory.h"
#include "inventory_null_data_model.h"
#include "item_container_personal_serialization.h"
#include "data_verification.h"
#include "string_util.h"
#include <map>
bool EQEmu::InventorySlot::IsValid() const {
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) {
return true;
}
if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) {
return true;
}
if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) {
return true;
}
if(type_ == InvTypeTribute && EQEmu::ValueWithin(slot_, 0, 4)) {
return true;
}
if(type_ == InvTypeTrade && EQEmu::ValueWithin(slot_, 0, 7)) {
return true;
}
if(type_ == InvTypeWorld && EQEmu::ValueWithin(slot_, 0, 255)) {
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsDelete() const {
return type_ == -1 && slot_ == -1 && bag_index_ == -1 && aug_index_ == -1;
}
bool EQEmu::InventorySlot::IsBank() const {
if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) {
return true;
}
if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) {
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsCursor() const {
if(type_ == InvTypePersonal && slot_ == PersonalSlotCursor) {
return true;
}
if(type_ == InvTypeCursorBuffer) {
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsEquipment() const {
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotAmmo)) {
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsGeneral() const {
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotGeneral1, PersonalSlotGeneral10)) {
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsWeapon() const {
if(type_ == InvTypePersonal &&
(EQEmu::ValueWithin(slot_, PersonalSlotPrimary, PersonalSlotSecondary) || slot_ == PersonalSlotRange))
{
return true;
}
return false;
}
bool EQEmu::InventorySlot::IsTrade() const {
if(type_ == InvTypeTrade) {
return true;
}
return false;
}
const std::string EQEmu::InventorySlot::ToString() const {
return StringFormat("(%i, %i, %i, %i)", type_, slot_, bag_index_, aug_index_);
}
struct EQEmu::Inventory::impl
{
std::map<int, ItemContainer> containers_;
int race_;
int class_;
int deity_;
std::unique_ptr<InventoryDataModel> data_model_;
};
EQEmu::Inventory::Inventory(int race, int class_, int deity) {
impl_ = new impl;
impl_->race_ = race;
impl_->class_ = class_;
impl_->deity_ = deity;
impl_->data_model_ = std::unique_ptr<InventoryDataModel>(new InventoryNullDataModel());
}
EQEmu::Inventory::~Inventory() {
delete impl_;
}
void EQEmu::Inventory::SetRace(int race) {
impl_->race_ = race;
}
void EQEmu::Inventory::SetClass(int class_) {
impl_->class_ = class_;
}
void EQEmu::Inventory::SetDeity(int deity) {
impl_->deity_ = deity;
}
void EQEmu::Inventory::SetDataModel(InventoryDataModel *dm) {
impl_->data_model_ = std::unique_ptr<InventoryDataModel>(dm);
}
EQEmu::ItemInstance::pointer EQEmu::Inventory::Get(const InventorySlot &slot) {
auto iter = impl_->containers_.find(slot.Type());
if(iter != impl_->containers_.end()) {
auto item = iter->second.Get(slot.Slot());
if(item) {
if(slot.BagIndex() > -1) {
auto sub_item = item->Get(slot.BagIndex());
if(sub_item) {
if(slot.AugIndex() > -1) {
return sub_item->Get(slot.AugIndex());
} else {
return sub_item;
}
}
} else {
return item;
}
}
}
return ItemInstance::pointer(nullptr);
}
bool EQEmu::Inventory::Put(const InventorySlot &slot, ItemInstance::pointer &inst) {
if(impl_->containers_.count(slot.Type()) == 0) {
if(slot.Type() == 0) {
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer(new ItemContainerPersonalSerialization())));
} else {
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer()));
}
}
//Verify item can be put into the slot requested
auto &container = impl_->containers_[slot.Type()];
if(slot.BagIndex() > -1) {
auto item = container.Get(slot.Slot());
if(!item)
return false;
if(slot.AugIndex() > -1) {
auto bag_item = item->Get(slot.BagIndex());
if(!bag_item) {
return false;
}
return bag_item->Put(slot.AugIndex(), inst);
} else {
return item->Put(slot.BagIndex(), inst);
}
} else {
if(slot.AugIndex() > -1) {
auto item = container.Get(slot.Slot());
if(!item)
return false;
return item->Put(slot.AugIndex(), inst);
}
return container.Put(slot.Slot(), inst);
}
return false;
}
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, int charges) {
if(src == dest) {
return true;
}
if(!src.IsValid()) {
return false;
}
if(src.Type() == InvTypeCursorBuffer || dest.Type() == InvTypeCursorBuffer) {
return true;
}
if(dest.IsDelete()) {
impl_->data_model_->Begin();
bool v = _destroy(src);
if(v) {
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
if(!dest.IsValid()) {
return false;
}
auto i_src = Get(src);
auto i_dest = Get(dest);
if(!i_src) {
return false;
}
if(i_src->GetBaseItem()->ItemClass == ItemClassContainer && dest.BagIndex() > -1) {
if(i_src->GetContainer()->Size() > 0) {
return false;
}
}
if(dest.IsEquipment() && !CanEquip(i_src, dest)) {
return false;
}
//Check this -> trade no drop
if(dest.IsTrade() && i_src->IsNoDrop()) {
return false;
}
impl_->data_model_->Begin();
if(i_src->IsStackable()) {
//move # charges from src to dest
//0 means *all* the charges
if(charges == 0) {
charges = i_src->GetCharges();
}
//src needs to have that many charges
if(i_src->GetCharges() < charges) {
impl_->data_model_->Rollback();
return false;
}
//if dest exists it needs to not only be the same item id but also be able to hold enough charges to combine
//we can also swap if src id != dest id
if(i_dest) {
uint32 src_id = i_src->GetBaseItem()->ID;
uint32 dest_id = i_dest->GetBaseItem()->ID;
if(src_id != dest_id) {
bool v = _swap(src, dest);
if(v) {
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
int charges_avail = i_dest->GetBaseItem()->StackSize - i_dest->GetCharges();
if(charges_avail < charges) {
impl_->data_model_->Rollback();
return false;
}
if(i_src->GetCharges() == charges) {
if(!_destroy(src)) {
impl_->data_model_->Rollback();
return false;
}
} else {
i_src->SetCharges(i_src->GetCharges() - charges);
impl_->data_model_->Insert(src, i_src);
}
i_dest->SetCharges(i_dest->GetCharges() + charges);
impl_->data_model_->Delete(dest);
impl_->data_model_->Insert(dest, i_dest);
impl_->data_model_->Commit();
return true;
} else {
//if dest does not exist and src charges > # charges then we need to create a new item with # charges in dest
//if dest does not exist and src charges == # charges then we need to swap src to dest
if(i_src->GetCharges() > charges) {
auto split = i_src->Split(charges);
if(!split) {
impl_->data_model_->Rollback();
return false;
}
Put(dest, split);
impl_->data_model_->Delete(src);
impl_->data_model_->Delete(dest);
impl_->data_model_->Insert(src, i_src);
impl_->data_model_->Insert(dest, split);
impl_->data_model_->Commit();
return true;
} else {
bool v = _swap(src, dest);
if(v) {
impl_->data_model_->Commit();
} else {
impl_->data_model_->Rollback();
}
return v;
}
}
} else {
bool v = _swap(src, dest);
if(v) {
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
impl_->data_model_->Commit();
return true;
}
bool EQEmu::Inventory::Summon(const InventorySlot &slot, ItemInstance::pointer &inst) {
if(!inst)
return false;
if(CheckLoreConflict(inst->GetBaseItem())) {
return false;
}
auto cur = Get(slot);
if(cur) {
if(slot.IsCursor()) {
PushToCursorBuffer(inst);
}
return false;
}
impl_->data_model_->Begin();
bool v = Put(slot, inst);
if(v) {
impl_->data_model_->Insert(slot, inst);
impl_->data_model_->Commit();
} else {
impl_->data_model_->Rollback();
}
return v;
}
bool EQEmu::Inventory::PushToCursorBuffer(ItemInstance::pointer &inst) {
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
impl_->containers_.insert(std::pair<int, ItemContainer>(InvTypeCursorBuffer, ItemContainer()));
}
int32 top = 0;
auto &container = impl_->containers_[InvTypeCursorBuffer];
auto iter = container.Begin();
while(iter != container.End()) {
top = iter->first;
++iter;
}
InventorySlot slot(InvTypeCursorBuffer, top + 1);
impl_->data_model_->Begin();
bool v = Put(slot, inst);
if(v) {
impl_->data_model_->Insert(slot, inst);
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
bool EQEmu::Inventory::PopFromCursorBuffer() {
InventorySlot cursor(InvTypePersonal, PersonalSlotCursor);
auto inst = Get(cursor);
if(inst) {
return false;
}
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
return false;
}
int32 top = 0;
auto &container = impl_->containers_[InvTypeCursorBuffer];
auto iter = container.Begin();
while(iter != container.End()) {
top = iter->first;
++iter;
}
InventorySlot slot(InvTypeCursorBuffer, top);
inst = Get(slot);
if(inst) {
impl_->data_model_->Begin();
bool v = _destroy(slot);
impl_->data_model_->Delete(slot);
if(!v) {
impl_->data_model_->Rollback();
return false;
}
v = Put(cursor, inst);
impl_->data_model_->Insert(cursor, inst);
if(!v) {
impl_->data_model_->Rollback();
return false;
}
impl_->data_model_->Commit();
return true;
}
return false;
}
EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) {
bool for_bag = inst->GetItem()->ItemClass == ItemClassContainer;
int min_size = inst->GetItem()->Size;
bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow;
//check upper level inventory
for(int i = slot_id_start; i <= slot_id_end; ++i) {
EQEmu::InventorySlot slot(container_id, i);
if(!Get(slot)) {
return slot;
}
}
//if not for a bag then check inside bags
if (!for_bag) {
for(int i = slot_id_start; i <= slot_id_end; ++i) {
EQEmu::InventorySlot slot(container_id, i);
auto inst = Get(slot);
if(inst && inst->GetBaseItem()->ItemClass == ItemClassContainer && inst->GetBaseItem()->BagSize >= min_size)
{
if(inst->GetBaseItem()->BagType == BagTypeQuiver && !is_arrow)
{
continue;
}
int slots = inst->GetBaseItem()->BagSlots;
for(int b_i = 0; b_i < slots; ++b_i) {
EQEmu::InventorySlot bag_slot(container_id, i, b_i);
if(!Get(bag_slot)) {
return bag_slot;
}
}
}
}
}
return EQEmu::InventorySlot();
}
int EQEmu::Inventory::FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) {
if(!inst->IsStackable()) {
return 0;
}
bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow;
int item_id = inst->GetItem()->ID;
int charges_to_check = inst->GetCharges();
int charges = 0;
auto iter = impl_->containers_.find(container_id);
if(iter == impl_->containers_.end()) {
return 0;
}
auto &container = iter->second;
for(int i = slot_id_start; i <= slot_id_end; ++i) {
auto current = container.Get(i);
if(!current) {
continue;
}
if(current->GetItem()->ID == item_id) {
int free_charges = current->GetItem()->StackSize - current->GetCharges();
if(free_charges)
charges += free_charges;
if(charges >= charges_to_check) {
return charges_to_check;
}
} else if(current->GetItem()->ItemClass == ItemClassContainer) {
int sz = current->GetItem()->BagSlots;
for(int i = 0; i < sz; ++i) {
auto sub_item = current->Get(i);
if(!sub_item) {
continue;
}
if(sub_item->GetItem()->ID == item_id) {
int free_charges = sub_item->GetItem()->StackSize - sub_item->GetCharges();
if(free_charges)
charges += free_charges;
if(charges >= charges_to_check) {
return charges_to_check;
}
}
}
}
}
if(charges >= charges_to_check) {
return charges_to_check;
}
return charges;
}
void EQEmu::Inventory::UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst) {
impl_->data_model_->Begin();
impl_->data_model_->Delete(slot);
if(inst) {
impl_->data_model_->Insert(slot, inst);
}
impl_->data_model_->Commit();
}
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
if(slot.Type() != 0)
return _MaterialInvalid;
switch(slot.Slot()) {
case PersonalSlotHead:
return MaterialHead;
case PersonalSlotChest:
return MaterialChest;
case PersonalSlotArms:
return MaterialArms;
case PersonalSlotWrist1:
return MaterialWrist;
case PersonalSlotHands:
return MaterialHands;
case PersonalSlotLegs:
return MaterialLegs;
case PersonalSlotFeet:
return MaterialFeet;
case PersonalSlotPrimary:
return MaterialPrimary;
case PersonalSlotSecondary:
return MaterialSecondary;
default:
return _MaterialInvalid;
}
}
EQEmu::InventorySlot EQEmu::Inventory::CalcSlotFromMaterial(int material) {
switch(material)
{
case MaterialHead:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotHead);
case MaterialChest:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotChest);
case MaterialArms:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotArms);
case MaterialWrist:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotWrist1);
case MaterialHands:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotHands);
case MaterialLegs:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotLegs);
case MaterialFeet:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotFeet);
case MaterialPrimary:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotPrimary);
case MaterialSecondary:
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotSecondary);
default:
return EQEmu::InventorySlot(-1, -1);
}
}
bool EQEmu::Inventory::CanEquip(EQEmu::ItemInstance::pointer &inst, const EQEmu::InventorySlot &slot) {
if(!inst) {
return false;
}
if(slot.Type() != 0) {
return false;
}
if(!EQEmu::ValueWithin(slot.Slot(), EQEmu::PersonalSlotCharm, EQEmu::PersonalSlotAmmo)) {
return false;
}
auto item = inst->GetItem();
//check slot
int use_slot = -1;
if(slot.Slot() == EQEmu::PersonalSlotPowerSource) {
use_slot = EQEmu::PersonalSlotAmmo;
}
else if(slot.Slot() == EQEmu::PersonalSlotAmmo) {
use_slot = EQEmu::PersonalSlotPowerSource;
}
else {
use_slot = slot.Slot();
}
if(!(item->Slots & (1 << use_slot))) {
return false;
}
//todo: check deity
if(!item->IsEquipable(impl_->race_, impl_->class_)) {
return false;
}
//Checking augments
auto iter = inst->GetContainer()->Begin();
auto end = inst->GetContainer()->End();
while(iter != end) {
EQEmu::ItemInstance::pointer itm = iter->second;
if(!CanEquip(itm, InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first))) {
return false;
}
++iter;
}
return true;
}
bool EQEmu::Inventory::CheckLoreConflict(const ItemData *item) {
if(!item)
return false;
if(!item->LoreFlag)
return false;
if(item->LoreGroup == 0)
return false;
if(item->LoreGroup == 0xFFFFFFFF) {
//look everywhere except shared bank
for(auto &container : impl_->containers_) {
if(container.first != InvTypeSharedBank && container.second.HasItem(item->ID)) {
return true;
}
}
}
else {
//look everywhere except shared bank
for(auto &container : impl_->containers_) {
if(container.first != InvTypeSharedBank && container.second.HasItemByLoreGroup(item->LoreGroup)) {
return true;
}
}
}
return false;
}
bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
buf.SetWritePosition(0);
buf.SetReadPosition(0);
buf.Resize(0);
buf.Write<int32>(105);
bool value = false;
for(auto &iter : impl_->containers_) {
bool v = iter.second.Serialize(buf, iter.first);
if(v && !value) {
value = true;
}
}
return value;
}
void EQEmu::Inventory::Interrogate() {
printf("Inventory:\n");
printf("Class: %u, Race: %u, Deity: %u\n", impl_->class_, impl_->race_, impl_->deity_);
for(auto &iter : impl_->containers_) {
printf("Container: %u\n", iter.first);
iter.second.Interrogate(1);
}
printf("\n");
}
bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest) {
auto src_i = Get(src);
auto dest_i = Get(dest);
if(src_i) {
if(!_destroy(src)) {
return false;
}
}
if(dest_i) {
if(!_destroy(dest)) {
return false;
}
impl_->data_model_->Insert(src, dest_i);
if(!Put(src, dest_i)) {
return false;
}
}
if(src_i) {
impl_->data_model_->Insert(dest, src_i);
if(!Put(dest, src_i)) {
return false;
}
}
return true;
}
bool EQEmu::Inventory::_destroy(const InventorySlot &slot) {
bool v = Put(slot, EQEmu::ItemInstance::pointer(nullptr));
impl_->data_model_->Delete(slot);
return v;
}
-165
View File
@@ -1,165 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_INVENTORY_H
#define COMMON_INVENTORY_H
#include "item_container.h"
#include <string>
namespace EQEmu
{
enum InventoryType : int
{
InvTypePersonal = 0,
InvTypeBank,
InvTypeSharedBank,
InvTypeTrade,
InvTypeWorld,
InvTypeCursorBuffer,
InvTypeTribute,
InvTypeTrophyTribute,
InvTypeGuildTribute,
InvTypeMerchant
};
enum PersonaInventorySlot : int
{
PersonalSlotCharm = 0,
PersonalSlotEar1,
PersonalSlotHead,
PersonalSlotFace,
PersonalSlotEar2,
PersonalSlotNeck,
PersonalSlotShoulders,
PersonalSlotArms,
PersonalSlotBack,
PersonalSlotWrist1,
PersonalSlotWrist2,
PersonalSlotRange,
PersonalSlotHands,
PersonalSlotPrimary,
PersonalSlotSecondary,
PersonalSlotFinger1,
PersonalSlotFinger2,
PersonalSlotChest,
PersonalSlotLegs,
PersonalSlotFeet,
PersonalSlotWaist,
PersonalSlotPowerSource,
PersonalSlotAmmo,
PersonalSlotGeneral1,
PersonalSlotGeneral2,
PersonalSlotGeneral3,
PersonalSlotGeneral4,
PersonalSlotGeneral5,
PersonalSlotGeneral6,
PersonalSlotGeneral7,
PersonalSlotGeneral8,
PersonalSlotGeneral9,
PersonalSlotGeneral10,
PersonalSlotCursor
};
class InventorySlot
{
public:
InventorySlot() : type_(-1), slot_(-1), bag_index_(-1), aug_index_(-1) { }
InventorySlot(int type, int slot)
: type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { }
InventorySlot(int type, int slot, int bag_index)
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { }
InventorySlot(int type, int slot, int bag_index, int aug_index)
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { }
bool IsValid() const;
bool IsDelete() const;
bool IsBank() const;
bool IsCursor() const;
bool IsEquipment() const;
bool IsGeneral() const;
bool IsWeapon() const;
bool IsTrade() const;
const std::string ToString() const;
inline int Type() { return type_; }
inline int Type() const { return type_; }
inline int Slot() { return slot_; }
inline int Slot() const { return slot_; }
inline int BagIndex() { return bag_index_; }
inline int BagIndex() const { return bag_index_; }
inline int AugIndex() { return aug_index_; }
inline int AugIndex() const { return aug_index_; }
private:
int type_;
int slot_;
int bag_index_;
int aug_index_;
};
inline bool operator==(const InventorySlot &lhs, const InventorySlot &rhs) {
return lhs.Type() == rhs.Type() &&
lhs.Slot() == rhs.Slot() &&
lhs.BagIndex() == rhs.BagIndex() &&
lhs.AugIndex() == rhs.AugIndex(); }
inline bool operator!=(const InventorySlot &lhs, const InventorySlot &rhs) { return !(lhs == rhs); }
class InventoryDataModel;
class Inventory
{
public:
Inventory(int race, int class_, int deity);
~Inventory();
void SetRace(int race);
void SetClass(int class_);
void SetDeity(int deity);
void SetDataModel(InventoryDataModel *dm);
ItemInstance::pointer Get(const InventorySlot &slot);
bool Put(const InventorySlot &slot, ItemInstance::pointer &inst);
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
bool Summon(const InventorySlot &slot, ItemInstance::pointer &inst);
bool PushToCursorBuffer(ItemInstance::pointer &inst);
bool PopFromCursorBuffer();
InventorySlot FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end);
int FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end);
void UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst);
//utility
static int CalcMaterialFromSlot(const InventorySlot &slot);
static InventorySlot CalcSlotFromMaterial(int material);
bool CanEquip(EQEmu::ItemInstance::pointer &inst, const EQEmu::InventorySlot &slot);
bool CheckLoreConflict(const ItemData *item);
bool Serialize(MemoryBuffer &buf);
//testing
void Interrogate();
private:
bool _swap(const InventorySlot &src, const InventorySlot &dest);
bool _destroy(const InventorySlot &slot);
struct impl;
impl *impl_;
};
} // EQEmu
#endif
-212
View File
@@ -1,212 +0,0 @@
#include "inventory_db_data_model.h"
#include "shareddb.h"
#include "string_util.h"
#include <list>
#include <string>
enum DataEventTypes
{
DB_Insert,
DB_Delete
};
struct DataEvent
{
DataEventTypes evt;
EQEmu::InventorySlot slot;
EQEmu::ItemInstance::pointer inst;
};
struct EQEmu::InventoryDatabaseDataModel::impl {
SharedDatabase *db_;
std::list<DataEvent> events_;
uint32 char_id_;
};
EQEmu::InventoryDatabaseDataModel::InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id) {
impl_ = new impl;
impl_->db_ = db;
impl_->char_id_ = char_id;
}
EQEmu::InventoryDatabaseDataModel::~InventoryDatabaseDataModel() {
delete impl_;
}
void EQEmu::InventoryDatabaseDataModel::Begin() {
impl_->db_->TransactionBegin();
impl_->events_.clear();
}
bool EQEmu::InventoryDatabaseDataModel::Commit() {
std::string base_insert = "INSERT INTO character_inventory(id, type, slot, bag_index, aug_index, "
"item_id, charges, color, attuned, custom_data, ornament_icon, ornament_idfile, ornament_hero_model"
", tracking_id) VALUES";
std::string current_insert = base_insert;
bool insert = false;
for(auto iter : impl_->events_) {
if(iter.evt == DB_Delete) {
if(insert) {
insert = false;
//commit the current_insert
auto res = impl_->db_->QueryDatabase(current_insert);
if(!res.Success()) {
Rollback();
return false;
}
current_insert = base_insert;
}
std::string current_delete;
if(iter.slot.BagIndex() > -1) {
if(iter.slot.AugIndex() > -1) {
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u AND aug_index=%u",
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex(), iter.slot.AugIndex());
}
else {
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u",
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex());
}
}
else if(iter.slot.AugIndex() > -1) {
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND aug_index=%u",
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.AugIndex());
}
else {
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u",
impl_->char_id_, iter.slot.Type(), iter.slot.Slot());
}
auto res = impl_->db_->QueryDatabase(current_delete);
if(!res.Success()) {
Rollback();
return false;
}
} else {
//insert
if(!insert) {
insert = true;
} else {
current_insert += ",";
}
current_insert += StringFormat("(%u, %i, %i, %i, %i, %u, %i, %u, %u, '%s', %u, %u, %u, %llu)",
impl_->char_id_,
iter.slot.Type(),
iter.slot.Slot(),
iter.slot.BagIndex(),
iter.slot.AugIndex(),
iter.inst->GetBaseItem()->ID,
iter.inst->GetCharges(),
iter.inst->GetColor(),
iter.inst->GetAttuned(),
EscapeString(iter.inst->GetCustomData()).c_str(),
iter.inst->GetOrnamentIcon(),
iter.inst->GetOrnamentIDFile(),
iter.inst->GetOrnamentHeroModel(),
iter.inst->GetTrackingID());
}
}
if(insert) {
insert = false;
//commit the current_insert
auto res = impl_->db_->QueryDatabase(current_insert);
if(!res.Success()) {
Rollback();
return false;
}
current_insert = base_insert;
}
impl_->db_->TransactionCommit();
impl_->events_.clear();
return true;
}
void EQEmu::InventoryDatabaseDataModel::Rollback() {
impl_->db_->TransactionRollback();
impl_->events_.clear();
}
void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, ItemInstance::pointer &inst) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = inst;
evt.slot = slot;
impl_->events_.push_back(evt);
//insert current item
if(slot.BagIndex() < 0 && slot.AugIndex() < 0) {
//if bag put all bag contents in
//if common put all augment contents in
if(inst->GetBaseItem()->ItemClass == ItemClassContainer) {
auto container = inst->GetContainer();
auto iter = container->Begin();
while(iter != container->End()) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, -1);
impl_->events_.push_back(evt);
//do augments here
if(evt.inst->GetBaseItem()->ItemClass == ItemClassCommon) {
auto inst_container = evt.inst->GetContainer();
auto inst_iter = inst_container->Begin();
while(inst_iter != inst_container->End()) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = inst_iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, inst_iter->first);
impl_->events_.push_back(evt);
++inst_iter;
}
}
++iter;
}
}
else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
auto container = inst->GetContainer();
auto iter = container->Begin();
while(iter != container->End()) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
impl_->events_.push_back(evt);
++iter;
}
}
}
else if(slot.AugIndex() < 0 && inst->GetBaseItem()->ItemClass == ItemClassCommon) {
//bag item that can have augs
//if common put all augment contents in
auto container = inst->GetContainer();
auto iter = container->Begin();
while(iter != container->End()) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first);
impl_->events_.push_back(evt);
++iter;
}
}
}
void EQEmu::InventoryDatabaseDataModel::Delete(const InventorySlot &slot) {
DataEvent evt;
evt.evt = DB_Delete;
evt.slot = slot;
impl_->events_.push_back(evt);
}
-45
View File
@@ -1,45 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_INVENTORY_DB_DATA_MODEL_H
#define COMMON_INVENTORY_DB_DATA_MODEL_H
#include "inventory_data_model.h"
class SharedDatabase;
namespace EQEmu
{
class InventoryDatabaseDataModel : public InventoryDataModel
{
public:
InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id);
virtual ~InventoryDatabaseDataModel();
virtual void Begin();
virtual bool Commit();
virtual void Rollback();
virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst);
virtual void Delete(const InventorySlot &slot);
private:
struct impl;
impl *impl_;
};
} // EQEmu
#endif
+107 -179
View File
@@ -105,9 +105,9 @@ ItemInst* ItemInstQueue::peek_front() const
//
// class InventoryOld
// class Inventory
//
InventoryOld::~InventoryOld()
Inventory::~Inventory()
{
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
safe_delete(iter->second);
@@ -135,7 +135,7 @@ InventoryOld::~InventoryOld()
m_trade.clear();
}
void InventoryOld::CleanDirty() {
void Inventory::CleanDirty() {
auto iter = dirty_inst.begin();
while (iter != dirty_inst.end()) {
delete (*iter);
@@ -144,14 +144,14 @@ void InventoryOld::CleanDirty() {
dirty_inst.clear();
}
void InventoryOld::MarkDirty(ItemInst *inst) {
void Inventory::MarkDirty(ItemInst *inst) {
if (inst) {
dirty_inst.push_back(inst);
}
}
// Retrieve item at specified slot; returns false if item not found
ItemInst* InventoryOld::GetItem(int16 slot_id) const
ItemInst* Inventory::GetItem(int16 slot_id) const
{
ItemInst* result = nullptr;
@@ -186,37 +186,37 @@ ItemInst* InventoryOld::GetItem(int16 slot_id) const
// Inner bag slots
else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) {
// Trade bag slots
ItemInst* inst = _GetItem(m_trade, InventoryOld::CalcSlotId(slot_id));
ItemInst* inst = _GetItem(m_trade, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
// Shared Bank bag slots
ItemInst* inst = _GetItem(m_shbank, InventoryOld::CalcSlotId(slot_id));
ItemInst* inst = _GetItem(m_shbank, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) {
// Bank bag slots
ItemInst* inst = _GetItem(m_bank, InventoryOld::CalcSlotId(slot_id));
ItemInst* inst = _GetItem(m_bank, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) {
// Cursor bag slots
ItemInst* inst = m_cursor.peek_front();
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) {
// Personal inventory bag slots
ItemInst* inst = _GetItem(m_inv, InventoryOld::CalcSlotId(slot_id));
ItemInst* inst = _GetItem(m_inv, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
@@ -224,13 +224,13 @@ ItemInst* InventoryOld::GetItem(int16 slot_id) const
}
// Retrieve item at specified position within bag
ItemInst* InventoryOld::GetItem(int16 slot_id, uint8 bagidx) const
ItemInst* Inventory::GetItem(int16 slot_id, uint8 bagidx) const
{
return GetItem(InventoryOld::CalcSlotId(slot_id, bagidx));
return GetItem(Inventory::CalcSlotId(slot_id, bagidx));
}
// Put an item snto specified slot
int16 InventoryOld::PutItem(int16 slot_id, const ItemInst& inst)
int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst)
{
// Clean up item already in slot (if exists)
DeleteItem(slot_id);
@@ -245,19 +245,19 @@ int16 InventoryOld::PutItem(int16 slot_id, const ItemInst& inst)
return _PutItem(slot_id, inst.Clone());
}
int16 InventoryOld::PushCursor(const ItemInst& inst)
int16 Inventory::PushCursor(const ItemInst& inst)
{
m_cursor.push(inst.Clone());
return MainCursor;
}
ItemInst* InventoryOld::GetCursorItem()
ItemInst* Inventory::GetCursorItem()
{
return m_cursor.peek_front();
}
// Swap items in inventory
bool InventoryOld::SwapItem(int16 slot_a, int16 slot_b)
bool Inventory::SwapItem(int16 slot_a, int16 slot_b)
{
// Temp holding areas for a and b
ItemInst* inst_a = GetItem(slot_a);
@@ -273,7 +273,7 @@ bool InventoryOld::SwapItem(int16 slot_a, int16 slot_b)
}
// Remove item from inventory (with memory delete)
bool InventoryOld::DeleteItem(int16 slot_id, uint8 quantity)
bool Inventory::DeleteItem(int16 slot_id, uint8 quantity)
{
// Pop item out of inventory map (or queue)
ItemInst* item_to_delete = PopItem(slot_id);
@@ -293,7 +293,7 @@ bool InventoryOld::DeleteItem(int16 slot_id, uint8 quantity)
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
) {
// Item can now be destroyed
InventoryOld::MarkDirty(item_to_delete);
Inventory::MarkDirty(item_to_delete);
return true;
}
}
@@ -303,19 +303,19 @@ bool InventoryOld::DeleteItem(int16 slot_id, uint8 quantity)
return false;
}
InventoryOld::MarkDirty(item_to_delete);
Inventory::MarkDirty(item_to_delete);
return true;
}
// Checks All items in a bag for No Drop
bool InventoryOld::CheckNoDrop(int16 slot_id) {
bool Inventory::CheckNoDrop(int16 slot_id) {
ItemInst* inst = GetItem(slot_id);
if (!inst) return false;
if (!inst->GetItem()->NoDrop) return true;
if (inst->GetItem()->ItemClass == 1) {
for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
ItemInst* bagitem = GetItem(InventoryOld::CalcSlotId(slot_id, i));
ItemInst* bagitem = GetItem(Inventory::CalcSlotId(slot_id, i));
if (bagitem && !bagitem->GetItem()->NoDrop)
return true;
}
@@ -325,7 +325,7 @@ bool InventoryOld::CheckNoDrop(int16 slot_id) {
// Remove item from bucket without memory delete
// Returns item pointer if full delete was successful
ItemInst* InventoryOld::PopItem(int16 slot_id)
ItemInst* Inventory::PopItem(int16 slot_id)
{
ItemInst* p = nullptr;
@@ -358,9 +358,9 @@ ItemInst* InventoryOld::PopItem(int16 slot_id)
}
else {
// Is slot inside bag?
ItemInst* baginst = GetItem(InventoryOld::CalcSlotId(slot_id));
ItemInst* baginst = GetItem(Inventory::CalcSlotId(slot_id));
if (baginst != nullptr && baginst->IsType(ItemClassContainer)) {
p = baginst->PopItem(InventoryOld::CalcBagIdx(slot_id));
p = baginst->PopItem(Inventory::CalcBagIdx(slot_id));
}
}
@@ -368,7 +368,7 @@ ItemInst* InventoryOld::PopItem(int16 slot_id)
return p;
}
bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) {
bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
if (ItemToTry->Stackable) {
@@ -388,7 +388,7 @@ bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) {
}
if (InvItem && InvItem->IsType(ItemClassContainer)) {
int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN);
int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN);
uint8 BagSize = InvItem->GetItem()->BagSlots;
for (uint8 BagSlot = SUB_BEGIN; BagSlot < BagSize; BagSlot++) {
@@ -432,7 +432,7 @@ bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) {
}
else if (InvItem->IsType(ItemClassContainer) && CanItemFitInContainer(ItemToTry, InvItem->GetItem())) {
int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN);
int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN);
uint8 BagSize = InvItem->GetItem()->BagSlots;
@@ -468,7 +468,7 @@ bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) {
//This function has a flaw in that it only returns the last stack that it looked at
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
int16 InventoryOld::HasItem(uint32 item_id, uint8 quantity, uint8 where)
int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
{
int16 slot_id = INVALID_INDEX;
@@ -518,7 +518,7 @@ int16 InventoryOld::HasItem(uint32 item_id, uint8 quantity, uint8 where)
}
//this function has the same quantity flaw mentioned above in HasItem()
int16 InventoryOld::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
{
int16 slot_id = INVALID_INDEX;
@@ -564,7 +564,7 @@ int16 InventoryOld::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
return slot_id;
}
int16 InventoryOld::HasItemByLoreGroup(uint32 loregroup, uint8 where)
int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
{
int16 slot_id = INVALID_INDEX;
@@ -612,7 +612,7 @@ int16 InventoryOld::HasItemByLoreGroup(uint32 loregroup, uint8 where)
// Locate an available inventory slot
// Returns slot_id when there's one available, else SLOT_INVALID
int16 InventoryOld::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
{
// Check basic inventory
for (int16 i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) {
@@ -631,7 +631,7 @@ int16 InventoryOld::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size,
continue;
}
int16 base_slot_id = InventoryOld::CalcSlotId(i, SUB_BEGIN);
int16 base_slot_id = Inventory::CalcSlotId(i, SUB_BEGIN);
uint8 slots = inst->GetItem()->BagSlots;
uint8 j;
@@ -656,11 +656,11 @@ int16 InventoryOld::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size,
}
// This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function...
int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
// If you have a need, use it..but, understand it is not a compatible replacement for InventoryOld::FindFreeSlot().
// If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot().
//
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U
if (!inst || !inst->GetID())
return INVALID_INDEX;
@@ -701,7 +701,7 @@ int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
continue;
if ((sub_inst->GetID() == inst->GetID()) && (sub_inst->GetCharges() < sub_inst->GetItem()->StackSize))
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
return Inventory::CalcSlotId(free_slot, free_bag_slot);
}
}
}
@@ -717,7 +717,7 @@ int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
if (!main_inst->GetItem(free_bag_slot))
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
return Inventory::CalcSlotId(free_slot, free_bag_slot);
}
}
}
@@ -732,7 +732,7 @@ int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
if (!main_inst->GetItem(free_bag_slot))
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
return Inventory::CalcSlotId(free_slot, free_bag_slot);
}
}
}
@@ -754,7 +754,7 @@ int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
if (!main_inst->GetItem(free_bag_slot))
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
return Inventory::CalcSlotId(free_slot, free_bag_slot);
}
}
}
@@ -764,7 +764,7 @@ int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
}
// Opposite of below: Get parent bag slot_id from a slot inside of bag
int16 InventoryOld::CalcSlotId(int16 slot_id) {
int16 Inventory::CalcSlotId(int16 slot_id) {
int16 parent_slot_id = INVALID_INDEX;
// this is not a bag range... using this risks over-writing existing items
@@ -792,8 +792,8 @@ int16 InventoryOld::CalcSlotId(int16 slot_id) {
}
// Calculate slot_id for an item within a bag
int16 InventoryOld::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
if (!InventoryOld::SupportsContainers(bagslot_id))
int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
if (!Inventory::SupportsContainers(bagslot_id))
return INVALID_INDEX;
int16 slot_id = INVALID_INDEX;
@@ -817,7 +817,7 @@ int16 InventoryOld::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
return slot_id;
}
uint8 InventoryOld::CalcBagIdx(int16 slot_id) {
uint8 Inventory::CalcBagIdx(int16 slot_id) {
uint8 index = 0;
// this is not a bag range... using this risks over-writing existing items
@@ -846,7 +846,7 @@ uint8 InventoryOld::CalcBagIdx(int16 slot_id) {
return index;
}
int16 InventoryOld::CalcSlotFromMaterial(uint8 material)
int16 Inventory::CalcSlotFromMaterial(uint8 material)
{
switch (material)
{
@@ -873,7 +873,7 @@ int16 InventoryOld::CalcSlotFromMaterial(uint8 material)
}
}
uint8 InventoryOld::CalcMaterialFromSlot(int16 equipslot)
uint8 Inventory::CalcMaterialFromSlot(int16 equipslot)
{
switch (equipslot)
{
@@ -901,7 +901,7 @@ uint8 InventoryOld::CalcMaterialFromSlot(int16 equipslot)
}
}
bool InventoryOld::CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container) {
bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) {
if (!ItemToTry || !Container)
return false;
@@ -918,7 +918,7 @@ bool InventoryOld::CanItemFitInContainer(const ItemData *ItemToTry, const ItemDa
return true;
}
bool InventoryOld::SupportsClickCasting(int16 slot_id)
bool Inventory::SupportsClickCasting(int16 slot_id)
{
// there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource)
@@ -934,7 +934,7 @@ bool InventoryOld::SupportsClickCasting(int16 slot_id)
return false;
}
bool InventoryOld::SupportsPotionBeltCasting(int16 slot_id)
bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
{
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END))
return true;
@@ -943,7 +943,7 @@ bool InventoryOld::SupportsPotionBeltCasting(int16 slot_id)
}
// Test whether a given slot can support a container item
bool InventoryOld::SupportsContainers(int16 slot_id)
bool Inventory::SupportsContainers(int16 slot_id)
{
if ((slot_id == MainCursor) ||
(slot_id >= EmuConstants::GENERAL_BEGIN && slot_id <= EmuConstants::GENERAL_END) ||
@@ -957,7 +957,7 @@ bool InventoryOld::SupportsContainers(int16 slot_id)
return false;
}
int InventoryOld::GetSlotByItemInst(ItemInst *inst) {
int Inventory::GetSlotByItemInst(ItemInst *inst) {
if (!inst)
return INVALID_INDEX;
@@ -993,46 +993,37 @@ int InventoryOld::GetSlotByItemInst(ItemInst *inst) {
return INVALID_INDEX;
}
uint8 InventoryOld::FindBrightestLightType()
uint8 Inventory::FindHighestLightValue()
{
uint8 brightest_light_type = 0;
uint8 light_value = NOT_USED;
// NOTE: The client does not recognize augment light sources, applied or otherwise, and should not be parsed
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
if ((iter->first < EmuConstants::EQUIPMENT_BEGIN || iter->first > EmuConstants::EQUIPMENT_END) && iter->first != MainPowerSource) { continue; }
if (iter->first == MainAmmo) { continue; }
auto inst = iter->second;
if (inst == nullptr) { continue; }
auto item = inst->GetItem();
if (item == nullptr) { continue; }
if (LightProfile_Struct::IsLevelGreater(item->Light, brightest_light_type))
brightest_light_type = item->Light;
if (item->Light & 0xF0) { continue; }
if (item->Light > light_value) { light_value = item->Light; }
}
uint8 general_light_type = 0;
for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) {
if (iter->first < EmuConstants::GENERAL_BEGIN || iter->first > EmuConstants::GENERAL_END) { continue; }
auto inst = iter->second;
if (inst == nullptr) { continue; }
auto item = inst->GetItem();
if (item == nullptr) { continue; }
if (item->ItemClass != ItemClassCommon) { continue; }
if (item->Light < 9 || item->Light > 13) { continue; }
if (LightProfile_Struct::TypeToLevel(item->Light))
general_light_type = item->Light;
// 'Gloomingdeep lantern' is ItemTypeArmor in the database..there may be others instances and/or types that need to be handled
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight && item->ItemType != ItemTypeArmor) { continue; }
if (item->Light & 0xF0) { continue; }
if (item->Light > light_value) { light_value = item->Light; }
}
if (LightProfile_Struct::IsLevelGreater(general_light_type, brightest_light_type))
brightest_light_type = general_light_type;
return brightest_light_type;
return light_value;
}
void InventoryOld::dumpEntireInventory() {
void Inventory::dumpEntireInventory() {
dumpWornItems();
dumpInventory();
@@ -1042,29 +1033,29 @@ void InventoryOld::dumpEntireInventory() {
std::cout << std::endl;
}
void InventoryOld::dumpWornItems() {
void Inventory::dumpWornItems() {
std::cout << "Worn items:" << std::endl;
dumpItemCollection(m_worn);
}
void InventoryOld::dumpInventory() {
void Inventory::dumpInventory() {
std::cout << "Inventory items:" << std::endl;
dumpItemCollection(m_inv);
}
void InventoryOld::dumpBankItems() {
void Inventory::dumpBankItems() {
std::cout << "Bank items:" << std::endl;
dumpItemCollection(m_bank);
}
void InventoryOld::dumpSharedBankItems() {
void Inventory::dumpSharedBankItems() {
std::cout << "Shared Bank items:" << std::endl;
dumpItemCollection(m_shbank);
}
int InventoryOld::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst) {
int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst) {
for (auto iter = collection.begin(); iter != collection.end(); ++iter) {
ItemInst *t_inst = iter->second;
if (t_inst == inst) {
@@ -1074,7 +1065,7 @@ int InventoryOld::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &
if (t_inst && !t_inst->IsType(ItemClassContainer)) {
for (auto b_iter = t_inst->_cbegin(); b_iter != t_inst->_cend(); ++b_iter) {
if (b_iter->second == inst) {
return InventoryOld::CalcSlotId(iter->first, b_iter->first);
return Inventory::CalcSlotId(iter->first, b_iter->first);
}
}
}
@@ -1083,7 +1074,7 @@ int InventoryOld::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &
return -1;
}
void InventoryOld::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
{
for (auto it = collection.cbegin(); it != collection.cend(); ++it) {
auto inst = it->second;
@@ -1097,7 +1088,7 @@ void InventoryOld::dumpItemCollection(const std::map<int16, ItemInst*> &collecti
}
}
void InventoryOld::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it)
void Inventory::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it)
{
if (!inst || !inst->IsType(ItemClassContainer))
return;
@@ -1108,7 +1099,7 @@ void InventoryOld::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::c
if (!baginst || !baginst->GetItem())
continue;
std::string subSlot = StringFormat(" Slot %d: %s (%d)", InventoryOld::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;
}
@@ -1116,7 +1107,7 @@ void InventoryOld::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::c
}
// Internal Method: Retrieves item within an inventory bucket
ItemInst* InventoryOld::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const
ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const
{
auto it = bucket.find(slot_id);
if (it != bucket.end()) {
@@ -1129,7 +1120,7 @@ ItemInst* InventoryOld::_GetItem(const std::map<int16, ItemInst*>& bucket, int16
// Internal Method: "put" item into bucket, without regard for what is currently in bucket
// Assumes item has already been allocated
int16 InventoryOld::_PutItem(int16 slot_id, ItemInst* inst)
int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
{
// What happens here when we _PutItem(MainCursor)? Bad things..really bad things...
//
@@ -1175,25 +1166,25 @@ int16 InventoryOld::_PutItem(int16 slot_id, ItemInst* inst)
}
else {
// Slot must be within a bag
parentSlot = InventoryOld::CalcSlotId(slot_id);
parentSlot = Inventory::CalcSlotId(slot_id);
ItemInst* baginst = GetItem(parentSlot); // Get parent bag
if (baginst && baginst->IsType(ItemClassContainer))
{
baginst->_PutItem(InventoryOld::CalcBagIdx(slot_id), inst);
baginst->_PutItem(Inventory::CalcBagIdx(slot_id), inst);
result = slot_id;
}
}
if (result == INVALID_INDEX) {
Log.Out(Logs::General, Logs::Error, "InventoryOld::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
InventoryOld::MarkDirty(inst); // Slot not found, clean up
Log.Out(Logs::General, Logs::Error, "Inventory::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
Inventory::MarkDirty(inst); // Slot not found, clean up
}
return result;
}
// Internal Method: Checks an inventory bucket for a particular item
int16 InventoryOld::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity)
int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity)
{
uint8 quantity_found = 0;
@@ -1221,7 +1212,7 @@ int16 InventoryOld::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id,
if (bag_inst->GetID() == item_id) {
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
if (quantity_found >= quantity)
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
return Inventory::CalcSlotId(iter->first, bag_iter->first);
}
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
@@ -1235,13 +1226,13 @@ int16 InventoryOld::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id,
}
// Internal Method: Checks an inventory queue type bucket for a particular item
int16 InventoryOld::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
{
// The downfall of this (these) queue procedure is that callers presume that when an item is
// found, it is presented as being available on the cursor. In cases of a parity check, this
// is sufficient. However, in cases where referential criteria is considered, this can lead
// to unintended results. Funtionality should be observed when referencing the return value
// of this query
// of this query -U
uint8 quantity_found = 0;
@@ -1269,7 +1260,7 @@ int16 InventoryOld::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quanti
if (bag_inst->GetID() == item_id) {
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
if (quantity_found >= quantity)
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
}
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
@@ -1286,7 +1277,7 @@ int16 InventoryOld::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quanti
}
// Internal Method: Checks an inventory bucket for a particular item
int16 InventoryOld::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity)
int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity)
{
uint8 quantity_found = 0;
@@ -1309,7 +1300,7 @@ int16 InventoryOld::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use,
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) {
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
if (quantity_found >= quantity)
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
return Inventory::CalcSlotId(iter->first, bag_iter->first);
}
}
}
@@ -1318,7 +1309,7 @@ int16 InventoryOld::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use,
}
// Internal Method: Checks an inventory queue type bucket for a particular item
int16 InventoryOld::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
{
uint8 quantity_found = 0;
@@ -1341,7 +1332,7 @@ int16 InventoryOld::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quanti
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) {
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
if (quantity_found >= quantity)
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
}
}
@@ -1352,7 +1343,7 @@ int16 InventoryOld::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quanti
return INVALID_INDEX;
}
int16 InventoryOld::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup)
int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup)
{
for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) {
auto inst = iter->second;
@@ -1376,7 +1367,7 @@ int16 InventoryOld::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint
if (bag_inst == nullptr) { continue; }
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup)
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
return Inventory::CalcSlotId(iter->first, bag_iter->first);
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
auto aug_inst = bag_inst->GetAugment(index);
@@ -1392,7 +1383,7 @@ int16 InventoryOld::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint
}
// Internal Method: Checks an inventory queue type bucket for a particular item
int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
{
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
auto inst = *iter;
@@ -1416,7 +1407,7 @@ int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
if (bag_inst == nullptr) { continue; }
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup)
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
auto aug_inst = bag_inst->GetAugment(index);
@@ -1438,7 +1429,7 @@ int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
//
// class ItemInst
//
ItemInst::ItemInst(const ItemData* item, int16 charges) {
ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
m_use_type = ItemInstNormal;
m_item = item;
m_charges = charges;
@@ -1548,7 +1539,7 @@ ItemInst::ItemInst(const ItemInst& copy)
m_evolveLvl = copy.m_evolveLvl;
m_activated = copy.m_activated;
if (copy.m_scaledItem)
m_scaledItem = new ItemData(*copy.m_scaledItem);
m_scaledItem = new Item_Struct(*copy.m_scaledItem);
else
m_scaledItem = nullptr;
@@ -1767,7 +1758,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
continue;
}
const ItemData* item = inst->GetItem();
const Item_Struct* item = inst->GetItem();
if (item == nullptr) {
cur = m_contents.erase(cur);
continue;
@@ -1908,7 +1899,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const ItemData* ornamentItem;
const Item_Struct* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
@@ -1935,7 +1926,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
return ornamentSet;
}
bool ItemInst::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll) {
if (!ItemToTry || !Container) return false;
if (ItemToTry->ItemType == ItemTypeArrow || strnlen(Container->CharmFile, 30) == 0)
@@ -2003,7 +1994,7 @@ void ItemInst::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id)
if (item_id == NO_ITEM) { return; }
if (db == nullptr) { return; /* TODO: add log message for nullptr */ }
const ItemInst* aug = db->CreateItemOld(item_id);
const ItemInst* aug = db->CreateItem(item_id);
if (aug) {
PutAugment(slot, *aug);
safe_delete(aug);
@@ -2069,7 +2060,7 @@ bool ItemInst::IsAmmo() const
}
const ItemData* ItemInst::GetItem() const
const Item_Struct* ItemInst::GetItem() const
{
if (!m_item)
return nullptr;
@@ -2080,7 +2071,7 @@ const ItemData* ItemInst::GetItem() const
return m_item;
}
const ItemData* ItemInst::GetUnscaledItem() const
const Item_Struct* ItemInst::GetUnscaledItem() const
{
// No operator calls and defaults to nullptr
return m_item;
@@ -2157,9 +2148,9 @@ ItemInst* ItemInst::Clone() const
}
bool ItemInst::IsSlotAllowed(int16 slot_id) const {
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid -U
if (!m_item) { return false; }
else if (InventoryOld::SupportsContainers(slot_id)) { return true; }
else if (Inventory::SupportsContainers(slot_id)) { return true; }
else if (m_item->Slots & (1 << slot_id)) { return true; }
else if (slot_id == MainPowerSource && (m_item->Slots & (1 << 22))) { return true; } // got lazy... <watch>
else if (slot_id != MainPowerSource && slot_id > EmuConstants::EQUIPMENT_END) { return true; }
@@ -2188,10 +2179,10 @@ void ItemInst::ScaleItem() {
return;
if (m_scaledItem) {
memcpy(m_scaledItem, m_item, sizeof(ItemData));
memcpy(m_scaledItem, m_item, sizeof(Item_Struct));
}
else {
m_scaledItem = new ItemData(*m_item);
m_scaledItem = new Item_Struct(*m_item);
}
float Mult = (float)(GetExp()) / 10000; // scaling is determined by exp, with 10,000 being full stats
@@ -2335,9 +2326,9 @@ EvolveInfo::~EvolveInfo() {
//
// struct ItemData
// struct Item_Struct
//
bool ItemData::IsEquipable(uint16 Race, uint16 Class_) const
bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const
{
bool IsRace = false;
bool IsClass = false;
@@ -2370,66 +2361,3 @@ bool ItemData::IsEquipable(uint16 Race, uint16 Class_) const
return (IsRace && IsClass);
}
//
// struct LightProfile_Struct
//
uint8 LightProfile_Struct::TypeToLevel(uint8 lightType)
{
switch (lightType) {
case lightTypeGlobeOfStars:
return lightLevelBrilliant; // 10
case lightTypeFlamelessLantern:
case lightTypeGreaterLightstone:
return lightLevelLargeMagic; // 9
case lightTypeLargeLantern:
return lightLevelLargeLantern; // 8
case lightTypeSteinOfMoggok:
case lightTypeLightstone:
return lightLevelMagicLantern; // 7
case lightTypeSmallLantern:
return lightLevelSmallLantern; // 6
case lightTypeColdlight:
case lightTypeUnknown2:
return lightLevelBlueLight; // 5
case lightTypeFireBeetleEye:
case lightTypeUnknown1:
return lightLevelRedLight; // 4
case lightTypeTinyGlowingSkull:
case lightTypeLightGlobe:
return lightLevelSmallMagic; // 3
case lightTypeTorch:
return lightLevelTorch; // 2
case lightLevelCandle:
return lightLevelCandle; // 1
default:
return lightLevelUnlit; // 0
}
}
bool LightProfile_Struct::IsLevelGreater(uint8 leftType, uint8 rightType)
{
static const uint8 light_levels[LIGHT_TYPES_COUNT] = {
lightLevelUnlit, /* lightTypeNone */
lightLevelCandle, /* lightTypeCandle */
lightLevelTorch, /* lightTypeTorch */
lightLevelSmallMagic, /* lightTypeTinyGlowingSkull */
lightLevelSmallLantern, /* lightTypeSmallLantern */
lightLevelMagicLantern, /* lightTypeSteinOfMoggok */
lightLevelLargeLantern, /* lightTypeLargeLantern */
lightLevelLargeMagic, /* lightTypeFlamelessLantern */
lightLevelBrilliant, /* lightTypeGlobeOfStars */
lightLevelSmallMagic, /* lightTypeLightGlobe */
lightLevelMagicLantern, /* lightTypeLightstone */
lightLevelLargeMagic, /* lightTypeGreaterLightstone */
lightLevelRedLight, /* lightTypeFireBeetleEye */
lightLevelBlueLight, /* lightTypeColdlight */
lightLevelRedLight, /* lightTypeUnknown1 */
lightLevelBlueLight /* lightTypeUnknown2 */
};
if (leftType >= LIGHT_TYPES_COUNT) { leftType = lightTypeNone; }
if (rightType >= LIGHT_TYPES_COUNT) { rightType = lightTypeNone; }
return (light_levels[leftType] > light_levels[rightType]);
}
+16 -55
View File
@@ -27,7 +27,7 @@ class ItemParse; // Parses item packets
class EvolveInfo; // Stores information about an evolving item family
#include "../common/eq_constants.h"
#include "../common/item_data.h"
#include "../common/item_struct.h"
#include "../common/timer.h"
#include <list>
@@ -104,9 +104,9 @@ protected:
};
// ########################################
// Class: InventoryOld
// Class: Inventory
// Character inventory
class InventoryOld
class Inventory
{
friend class ItemInst;
public:
@@ -114,8 +114,8 @@ public:
// Public Methods
///////////////////////////////
InventoryOld() { m_version = ClientVersion::Unknown; m_versionset = false; }
~InventoryOld();
Inventory() { m_version = ClientVersion::Unknown; m_versionset = false; }
~Inventory();
// Inventory v2 creep
bool SetInventoryVersion(ClientVersion version) {
@@ -168,7 +168,7 @@ public:
ItemInst* PopItem(int16 slot_id);
// Check whether there is space for the specified number of the specified item.
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
bool HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
@@ -193,7 +193,7 @@ public:
static int16 CalcSlotFromMaterial(uint8 material);
static uint8 CalcMaterialFromSlot(int16 equipslot);
static bool CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container);
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
// Test for valid inventory casting slot
bool SupportsClickCasting(int16 slot_id);
@@ -204,7 +204,7 @@ public:
int GetSlotByItemInst(ItemInst *inst);
uint8 FindBrightestLightType();
uint8 FindHighestLightValue();
void dumpEntireInventory();
void dumpWornItems();
@@ -270,7 +270,7 @@ public:
/////////////////////////
// Constructors/Destructor
ItemInst(const ItemData* item = nullptr, int16 charges = 0);
ItemInst(const Item_Struct* item = nullptr, int16 charges = 0);
ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0);
@@ -331,7 +331,7 @@ public:
bool IsAugmented();
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
static bool CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll = false);
// Has attack/delay?
bool IsWeapon() const;
@@ -340,8 +340,8 @@ public:
// Accessors
const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); }
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); }
const ItemData* GetItem() const;
const ItemData* GetUnscaledItem() const;
const Item_Struct* GetItem() const;
const Item_Struct* GetUnscaledItem() const;
int16 GetCharges() const { return m_charges; }
void SetCharges(int16 charges) { m_charges = charges; }
@@ -376,7 +376,7 @@ public:
// Allows treatment of this object as though it were a pointer to m_item
operator bool() const { return (m_item != nullptr); }
// Compare inner ItemData of two ItemInst objects
// Compare inner Item_Struct of two ItemInst objects
bool operator==(const ItemInst& right) const { return (this->m_item == right.m_item); }
bool operator!=(const ItemInst& right) const { return (this->m_item != right.m_item); }
@@ -425,13 +425,13 @@ protected:
std::map<uint8, ItemInst*>::const_iterator _cbegin() { return m_contents.cbegin(); }
std::map<uint8, ItemInst*>::const_iterator _cend() { return m_contents.cend(); }
friend class InventoryOld;
friend class Inventory;
void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
const Item_Struct* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
@@ -443,7 +443,7 @@ protected:
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
ItemData* m_scaledItem;
Item_Struct* m_scaledItem;
EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
@@ -472,43 +472,4 @@ public:
~EvolveInfo();
};
struct LightProfile_Struct
{
/*
Current criteria (light types):
Equipment: { 0 .. 15 }
General: { 9 .. 13 }
Notes:
- Initial character load and item movement updates use different light source update behaviors
-- Server procedure matches the item movement behavior since most updates occur post-character load
- MainAmmo is not considered when determining light sources
- No 'Sub' or 'Aug' items are recognized as light sources
- Light types '< 9' and '> 13' are not considered for general (carried) light sources
- If values > 0x0F are valid, then assignment limiters will need to be removed
- MainCursor 'appears' to be a valid light source update slot..but, have not experienced updates during debug sessions
- All clients have a bug regarding stackable items (light and sound updates are not processed when picking up an item)
-- The timer-based update cancels out the invalid light source
*/
static uint8 TypeToLevel(uint8 lightType);
static bool IsLevelGreater(uint8 leftType, uint8 rightType);
// Light types (classifications)
struct {
uint8 Innate; // Defined by db field `npc_types`.`light` - where appropriate
uint8 Equipment; // Item_Struct::light value of worn/carried equipment
uint8 Spell; // Set value of any light-producing spell (can be modded to mimic equip_light behavior)
uint8 Active; // Highest value of all light sources
} Type;
// Light levels (intensities) - used to determine which light source should be active
struct {
uint8 Innate;
uint8 Equipment;
uint8 Spell;
uint8 Active;
} Level;
};
#endif // #define __ITEM_H
-135
View File
@@ -1,135 +0,0 @@
#include "item_container.h"
#include "item_container_default_serialization.h"
#include <utility>
struct EQEmu::ItemContainer::impl
{
std::map<int, ItemInstance::pointer> items_;
ItemContainerSerializationStrategy *serialize_strat_;
};
EQEmu::ItemContainer::ItemContainer()
{
impl_ = new impl();
impl_->serialize_strat_ = new ItemContainerDefaultSerialization();
}
EQEmu::ItemContainer::ItemContainer(ItemContainerSerializationStrategy *strategy) {
impl_ = new impl();
impl_->serialize_strat_ = strategy;
}
EQEmu::ItemContainer::~ItemContainer()
{
if(impl_) {
delete impl_->serialize_strat_;
delete impl_;
}
}
EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) {
impl_ = other.impl_;
other.impl_ = nullptr;
}
EQEmu::ItemContainer& EQEmu::ItemContainer::operator=(ItemContainer &&other) {
if(this == &other)
return *this;
impl_ = other.impl_;
other.impl_ = nullptr;
return *this;
}
EQEmu::ItemInstance::pointer EQEmu::ItemContainer::Get(const int slot_id) {
auto iter = impl_->items_.find(slot_id);
if(iter != impl_->items_.end()) {
return iter->second;
}
return EQEmu::ItemInstance::pointer(nullptr);
}
bool EQEmu::ItemContainer::Put(const int slot_id, ItemInstance::pointer &inst) {
if(!inst) {
impl_->items_.erase(slot_id);
return true;
} else {
auto iter = impl_->items_.find(slot_id);
if(iter == impl_->items_.end()) {
impl_->items_[slot_id] = inst;
return true;
}
}
return false;
}
bool EQEmu::ItemContainer::HasItem(uint32 item_id) {
for(auto &item : impl_->items_) {
if(item.second->GetBaseItem()->ID == item_id) {
return true;
}
}
return false;
}
bool EQEmu::ItemContainer::HasItemByLoreGroup(uint32 loregroup) {
if(loregroup == 0xFFFFFFFF)
return false;
for(auto &item : impl_->items_) {
if(item.second->GetBaseItem()->LoreGroup == loregroup) {
return true;
}
}
return false;
}
uint32 EQEmu::ItemContainer::Size() {
return (uint32)impl_->items_.size();
}
uint32 EQEmu::ItemContainer::Size() const {
return (uint32)impl_->items_.size();
}
bool EQEmu::ItemContainer::Delete(const int slot_id) {
auto iter = impl_->items_.find(slot_id);
if(iter == impl_->items_.end()) {
return false;
} else {
impl_->items_.erase(iter);
return true;
}
}
bool EQEmu::ItemContainer::Serialize(MemoryBuffer &buf, int container_number) {
if(impl_->serialize_strat_) {
return impl_->serialize_strat_->Serialize(buf, container_number, impl_->items_);
}
return false;
}
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() {
return impl_->items_.begin();
}
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() {
return impl_->items_.end();
}
void EQEmu::ItemContainer::Interrogate(int level) {
char buffer[16] = { 0 };
for(int i = 0; i < level; ++i) {
buffer[i] = '\t';
}
for(auto &iter : impl_->items_) {
printf("%s%u: (%u)%s (%u)\n", buffer, iter.first, iter.second->GetBaseItem()->ID, iter.second->GetBaseItem()->Name, iter.second->GetCharges());
iter.second->Interrogate(level + 1);
}
}
-70
View File
@@ -1,70 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_H
#define COMMON_ITEM_CONTAINER_H
#include "item_instance.h"
#include "item_container_serialization_strategy.h"
#include "memory_buffer.h"
#include <memory>
#include <map>
namespace EQEmu
{
class ItemContainerSerializationStrategy;
class ItemContainer
{
public:
typedef std::map<int, ItemInstance::pointer>::const_iterator ItemContainerIter;
ItemContainer();
ItemContainer(ItemContainerSerializationStrategy *strategy);
~ItemContainer();
ItemContainer(ItemContainer &&other);
ItemContainer& operator=(ItemContainer &&other);
ItemInstance::pointer Get(const int slot_id);
bool Put(const int slot_id, ItemInstance::pointer &inst);
bool Delete(const int slot_id);
//Utility
bool HasItem(uint32 item_id);
bool HasItemByLoreGroup(uint32 loregroup);
uint32 Size();
uint32 Size() const;
//Low level interface for encode/decode
bool Serialize(MemoryBuffer &buf, int container_number);
ItemContainerIter Begin();
ItemContainerIter End();
//testing
void Interrogate(int level);
protected:
struct impl;
impl *impl_;
private:
ItemContainer(const ItemContainer &other);
ItemContainer& operator=(const ItemContainer &other);
};
} // EQEmu
#endif
@@ -1,19 +0,0 @@
#include "item_container_default_serialization.h"
bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) {
if(items.size() == 0) {
return false;
}
bool ret = false;
for(auto &iter : items) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<int32>(-1);
buf.Write<int32>(-1);
buf.Write<void*>(iter.second.get());
ret = true;
}
return ret;
}
@@ -1,35 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
#define COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
#include "item_container_serialization_strategy.h"
namespace EQEmu
{
class ItemContainerDefaultSerialization : public ItemContainerSerializationStrategy
{
public:
ItemContainerDefaultSerialization() { }
virtual ~ItemContainerDefaultSerialization() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items);
};
} // EQEmu
#endif
@@ -1,21 +0,0 @@
#include "item_container_personal_serialization.h"
bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) {
if(items.size() == 0) {
return false;
}
bool ret = false;
for(auto &iter : items) {
if(iter.first < 33) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<int32>(-1);
buf.Write<int32>(-1);
buf.Write<void*>(iter.second.get());
ret = true;
}
}
return ret;
}
@@ -1,35 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
#define COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
#include "item_container_serialization_strategy.h"
namespace EQEmu
{
class ItemContainerPersonalSerialization : public ItemContainerSerializationStrategy
{
public:
ItemContainerPersonalSerialization() { }
virtual ~ItemContainerPersonalSerialization() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items);
};
} // EQEmu
#endif
@@ -1,37 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
#define COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
#include "item_container.h"
#include "memory_buffer.h"
#include <map>
namespace EQEmu
{
class ItemContainerSerializationStrategy
{
public:
ItemContainerSerializationStrategy() { }
virtual ~ItemContainerSerializationStrategy() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) = 0;
};
} // EQEmu
#endif
-389
View File
@@ -1,389 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 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 "item_instance.h"
#include "data_verification.h"
#include "item_container.h"
uint32 ItemInstanceSerial = 1;
uint32 EQEmu::GetNextItemInstanceSerial() {
ItemInstanceSerial++;
return ItemInstanceSerial;
}
struct EQEmu::ItemInstance::impl {
const ItemData *base_item_;
ItemData *modified_item_;
int16 charges_;
uint32 color_;
bool attuned_;
std::string custom_data_;
uint32 ornament_idfile_;
uint32 ornament_icon_;
uint32 ornament_hero_model_;
char tracking_id_[17];
uint32 serial_id_;
uint32 recast_timestamp_;
uint32 merchant_slot_;
uint32 merchant_count_;
uint32 price_;
ItemContainer contents_;
};
EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
impl_ = new impl;
impl_->base_item_ = idata;
impl_->modified_item_ = nullptr;
impl_->charges_ = -1;
impl_->color_ = 0;
impl_->attuned_ = false;
impl_->ornament_idfile_ = 0;
impl_->ornament_icon_ = 0;
impl_->ornament_hero_model_ = 0;
impl_->serial_id_ = 0;
impl_->recast_timestamp_ = 0;
impl_->merchant_slot_ = 0;
impl_->merchant_count_ = 0;
impl_->price_ = 0;
memset(impl_->tracking_id_, 0, 17);
}
EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) {
impl_ = new impl;
impl_->base_item_ = idata;
impl_->modified_item_ = nullptr;
impl_->charges_ = charges;
impl_->color_ = 0;
impl_->attuned_ = false;
impl_->ornament_idfile_ = 0;
impl_->ornament_icon_ = 0;
impl_->ornament_hero_model_ = 0;
impl_->recast_timestamp_ = 0;
impl_->serial_id_ = 0;
impl_->merchant_slot_ = 0;
impl_->merchant_count_ = 0;
impl_->price_ = 0;
memset(impl_->tracking_id_, 0, 17);
}
EQEmu::ItemInstance::~ItemInstance() {
delete impl_;
}
EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Split(int charges) {
if(!IsStackable()) {
//Can't split non stackable items!
return pointer(nullptr);
}
if(charges >= GetCharges()) {
return pointer(nullptr);
}
if(impl_->contents_.Size() > 0) {
return pointer(nullptr);
}
pointer split = pointer(new EQEmu::ItemInstance(impl_->base_item_, charges));
split->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
//Set Tracking here
split->impl_->attuned_ = impl_->attuned_;
split->impl_->custom_data_ = impl_->custom_data_;
split->impl_->recast_timestamp_ = impl_->recast_timestamp_;
split->impl_->price_ = impl_->price_;
split->impl_->color_ = impl_->color_;
split->impl_->merchant_count_ = impl_->merchant_count_;
split->impl_->merchant_slot_ = impl_->merchant_slot_;
split->impl_->ornament_hero_model_ = impl_->ornament_hero_model_;
split->impl_->ornament_icon_ = impl_->ornament_icon_;
split->impl_->ornament_idfile_ = impl_->ornament_idfile_;
SetCharges(GetCharges() - charges);
return split;
}
const ItemData *EQEmu::ItemInstance::GetItem() {
return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_;
}
const ItemData *EQEmu::ItemInstance::GetBaseItem() {
return impl_->base_item_;
}
const ItemData *EQEmu::ItemInstance::GetBaseItem() const {
return impl_->base_item_;
}
EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Get(const int index) {
if(EQEmu::ValueWithin(index, 0, 255)) {
return impl_->contents_.Get(index);
}
return pointer(nullptr);
}
bool EQEmu::ItemInstance::Put(const int index, pointer &inst) {
if(!impl_->base_item_) {
return false;
}
auto item = impl_->base_item_;
if(item->ItemClass == ItemClassContainer) { // Bag
if(!EQEmu::ValueWithin(index, 0, item->BagSlots)) {
return false;
}
return impl_->contents_.Put(index, inst);
}
else if(item->ItemClass == ItemClassCommon) { // Augment
if(!EQEmu::ValueWithin(index, 0, EmuConstants::ITEM_COMMON_SIZE)) {
return false;
}
if(!item->AugSlotVisible[index]) {
return false;
}
if(inst) {
auto *aug_item = inst->GetItem();
int aug_type = aug_item->AugType;
if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) {
return impl_->contents_.Put(index, inst);
}
} else {
return impl_->contents_.Put(index, inst);
}
return false;
}
return false;
}
int16 EQEmu::ItemInstance::GetCharges() {
return impl_->charges_;
}
int16 EQEmu::ItemInstance::GetCharges() const {
return impl_->charges_;
}
void EQEmu::ItemInstance::SetCharges(const int16 charges) {
impl_->charges_ = charges;
}
uint32 EQEmu::ItemInstance::GetColor() {
return impl_->color_;
}
uint32 EQEmu::ItemInstance::GetColor() const {
return impl_->color_;
}
void EQEmu::ItemInstance::SetColor(const uint32 color) {
impl_->color_ = color;
}
bool EQEmu::ItemInstance::GetAttuned() {
return impl_->attuned_;
}
bool EQEmu::ItemInstance::GetAttuned() const {
return impl_->attuned_;
}
void EQEmu::ItemInstance::SetAttuned(const bool attuned) {
impl_->attuned_ = attuned;
}
std::string EQEmu::ItemInstance::GetCustomData() {
return impl_->custom_data_;
}
std::string EQEmu::ItemInstance::GetCustomData() const {
return impl_->custom_data_;
}
void EQEmu::ItemInstance::SetCustomData(const std::string &custom_data) {
//We need to actually set the custom data stuff based on this string
impl_->custom_data_ = custom_data;
}
uint32 EQEmu::ItemInstance::GetOrnamentIDFile() {
return impl_->ornament_idfile_;
}
uint32 EQEmu::ItemInstance::GetOrnamentIDFile() const {
return impl_->ornament_idfile_;
}
void EQEmu::ItemInstance::SetOrnamentIDFile(const uint32 ornament_idfile) {
impl_->ornament_idfile_ = ornament_idfile;
}
uint32 EQEmu::ItemInstance::GetOrnamentIcon() {
return impl_->ornament_icon_;
}
uint32 EQEmu::ItemInstance::GetOrnamentIcon() const {
return impl_->ornament_icon_;
}
void EQEmu::ItemInstance::SetOrnamentIcon(const uint32 ornament_icon) {
impl_->ornament_icon_ = ornament_icon;
}
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() {
return impl_->ornament_hero_model_;
}
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() const {
return impl_->ornament_hero_model_;
}
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) {
uint32 hero_model = 0;
if(impl_->ornament_hero_model_ > 0)
{
hero_model = impl_->ornament_hero_model_;
if(material_slot >= 0)
{
hero_model = (impl_->ornament_hero_model_ * 100) + material_slot;
}
}
return hero_model;
}
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) const {
uint32 hero_model = 0;
if(impl_->ornament_hero_model_ > 0)
{
hero_model = impl_->ornament_hero_model_;
if(material_slot >= 0)
{
hero_model = (impl_->ornament_hero_model_ * 100) + material_slot;
}
}
return hero_model;
}
void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model) {
impl_->ornament_hero_model_ = ornament_hero_model;
}
const char* EQEmu::ItemInstance::GetTrackingID() {
return impl_->tracking_id_;
}
const char* EQEmu::ItemInstance::GetTrackingID() const {
return impl_->tracking_id_;
}
void EQEmu::ItemInstance::SetTrackingID(const char *tracking_id) {
size_t len = strlen(tracking_id);
if(len > 16) {
return;
}
strncpy(impl_->tracking_id_, tracking_id, 16);
}
uint32 EQEmu::ItemInstance::GetRecastTimestamp() {
return impl_->recast_timestamp_;
}
uint32 EQEmu::ItemInstance::GetRecastTimestamp() const {
return impl_->recast_timestamp_;
}
void EQEmu::ItemInstance::SetRecastTimestamp(const uint32 recast_timestamp) {
impl_->recast_timestamp_ = recast_timestamp;
}
uint32 EQEmu::ItemInstance::GetMerchantSlot() {
return impl_->merchant_slot_;
}
uint32 EQEmu::ItemInstance::GetMerchantSlot() const {
return impl_->merchant_slot_;
}
void EQEmu::ItemInstance::SetMerchantSlot(uint32 slot) {
impl_->merchant_slot_ = slot;
}
uint32 EQEmu::ItemInstance::GetMerchantCount() {
return impl_->merchant_count_;
}
uint32 EQEmu::ItemInstance::GetMerchantCount() const {
return impl_->merchant_count_;
}
void EQEmu::ItemInstance::SetMerchantCount(const uint32 cnt) {
impl_->merchant_count_ = cnt;
}
uint32 EQEmu::ItemInstance::GetPrice() {
return impl_->price_;
}
uint32 EQEmu::ItemInstance::GetPrice() const {
return impl_->price_;
}
void EQEmu::ItemInstance::SetPrice(const uint32 p) {
impl_->price_ = p;
}
uint32 EQEmu::ItemInstance::GetSerialNumber() {
return impl_->serial_id_;
}
uint32 EQEmu::ItemInstance::GetSerialNumber() const {
return impl_->serial_id_;
}
void EQEmu::ItemInstance::SetSerialNumber(const uint32 sn) {
impl_->serial_id_ = sn;
}
bool EQEmu::ItemInstance::IsStackable() {
return impl_->base_item_->Stackable;
}
bool EQEmu::ItemInstance::IsStackable() const {
return impl_->base_item_->Stackable;
}
bool EQEmu::ItemInstance::IsNoDrop() {
return GetAttuned() || GetBaseItem()->NoDrop == 0;
}
bool EQEmu::ItemInstance::IsNoDrop() const {
return GetAttuned() || GetBaseItem()->NoDrop == 0;
}
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
return &(impl_->contents_);
}
void EQEmu::ItemInstance::Interrogate(int level) {
impl_->contents_.Interrogate(level);
}
-126
View File
@@ -1,126 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_INSTANCE_H
#define COMMON_ITEM_INSTANCE_H
#include "item_data.h"
#include <memory>
namespace EQEmu
{
uint32 GetNextItemInstanceSerial();
class ItemContainer;
class ItemInstance
{
public:
typedef std::shared_ptr<ItemInstance> pointer;
ItemInstance(const ItemData* idata);
ItemInstance(const ItemData* idata, const int16 charges);
~ItemInstance();
const ItemData *GetItem();
const ItemData *GetBaseItem();
const ItemData *GetBaseItem() const;
pointer Split(int charges);
//Container
pointer Get(const int index);
bool Put(const int index, pointer &inst);
//Persistent State
int16 GetCharges();
int16 GetCharges() const;
void SetCharges(const int16 charges);
uint32 GetColor();
uint32 GetColor() const;
void SetColor(const uint32 color);
bool GetAttuned();
bool GetAttuned() const;
void SetAttuned(const bool attuned);
std::string GetCustomData();
std::string GetCustomData() const;
void SetCustomData(const std::string &custom_data);
uint32 GetOrnamentIDFile();
uint32 GetOrnamentIDFile() const;
void SetOrnamentIDFile(const uint32 ornament_idfile);
uint32 GetOrnamentIcon();
uint32 GetOrnamentIcon() const;
void SetOrnamentIcon(const uint32 ornament_icon);
uint32 GetOrnamentHeroModel();
uint32 GetOrnamentHeroModel() const;
uint32 GetOrnamentHeroModel(int material_slot);
uint32 GetOrnamentHeroModel(int material_slot) const;
void SetOrnamentHeroModel(const uint32 ornament_hero_model);
const char* GetTrackingID();
const char* GetTrackingID() const;
void SetTrackingID(const char *tracking_id);
uint32 GetRecastTimestamp();
uint32 GetRecastTimestamp() const;
void SetRecastTimestamp(const uint32 recast_timestamp);
//Merchant
uint32 GetMerchantSlot();
uint32 GetMerchantSlot() const;
void SetMerchantSlot(const uint32 slot);
uint32 GetMerchantCount();
uint32 GetMerchantCount() const;
void SetMerchantCount(const uint32 cnt);
uint32 GetPrice();
uint32 GetPrice() const;
void SetPrice(const uint32 p);
//Serial Number
uint32 GetSerialNumber();
uint32 GetSerialNumber() const;
void SetSerialNumber(uint32 sn);
//Basic Stats
bool IsStackable();
bool IsStackable() const;
bool IsNoDrop();
bool IsNoDrop() const;
void CheckStackRemaining(pointer &insert, int &charges);
//Internal state
//Used for low level operations such as encode/decode
ItemContainer *GetContainer();
void Interrogate(int level);
private:
struct impl;
impl *impl_;
};
} // EQEmu
#endif
+23 -20
View File
@@ -16,8 +16,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
*/
#ifndef COMMON_ITEM_DATA_H
#define COMMON_ITEM_DATA_H
#ifndef ITEM_STRUCT_H
#define ITEM_STRUCT_H
/*
* Note: (Doodman)
@@ -35,7 +35,7 @@
*
* Note #3: (Doodman)
* Please take care when adding new found data fields to add them
* to the appropriate structure. ItemData has elements that are
* to the appropriate structure. Item_Struct has elements that are
* global to all types of items only.
*
* Note #4: (Doodman)
@@ -46,7 +46,7 @@
#include "eq_dictionary.h"
/*
** Child struct of ItemData:
** Child struct of Item_Struct:
** Effect data: Click, Proc, Focus, Worn, Scroll
**
*/
@@ -69,18 +69,10 @@ struct InternalSerializedItem_Struct {
const void * inst;
};
struct SerializedItemInstance_Struct {
int32 container_id;
int32 slot_id;
int32 bag_id;
int32 aug_id;
void *inst;
};
// use EmuConstants::ITEM_COMMON_SIZE
//#define MAX_AUGMENT_SLOTS 5
struct ItemData {
struct Item_Struct {
bool IsEquipable(uint16 Race, uint16 Class) const;
// Non packet based fields
uint8 MinStatus;
@@ -107,10 +99,17 @@ struct ItemData {
uint32 Favor; // Individual favor
uint32 GuildFavor; // Guild favor
uint32 PointType;
//uint32 Unk117;
//uint32 Unk118;
//uint32 Unk121;
//uint32 Unk124;
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots; // Number of slots
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR; // 0->100
bool BenefitFlag;
bool Tradeskills; // Is this a tradeskill item?
int8 CR; // Save vs Cold
@@ -129,6 +128,7 @@ struct ItemData {
int32 Mana; // Mana
int32 AC; // AC
uint32 Deity; // Bitmask of Deities that can equip this item
//uint32 Unk033
int32 SkillModValue; // % Mod to skill specified in SkillModType
uint32 SkillModType; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace; // Bane Damage Race
@@ -150,11 +150,13 @@ struct ItemData {
uint32 Color; // RR GG BB 00 <-- as it appears in pc
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
uint32 Races; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054;
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType; // Item Type/Skill (itemClass* from above)
uint8 Material; // Item material type
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
float SellRate; // Sell rate
//uint32 Unk059;
union {
uint32 Fulfilment; // Food fulfilment (How long it lasts)
int16 CastTime; // Cast Time for clicky effects, in milliseconds
@@ -183,7 +185,7 @@ struct ItemData {
uint32 AugType;
uint8 AugSlotType[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
@@ -209,6 +211,7 @@ struct ItemData {
int16 StackSize;
uint8 PotionBeltSlots;
ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
uint8 Book; // 0=Not book, 1=Book
uint32 BookType;
char Filename[33]; // Filename for book data
@@ -237,11 +240,11 @@ struct ItemData {
uint32 ScriptFileID;
uint16 ExpendableArrow;
uint32 Clairvoyance;
char ClickName[65];
char ProcName[65];
char WornName[65];
char FocusName[65];
char ScrollName[65];
char ClickName[65];
char ProcName[65];
char WornName[65];
char FocusName[65];
char ScrollName[65];
};
-212
View File
@@ -1,212 +0,0 @@
#include "memory_buffer.h"
EQEmu::MemoryBuffer::MemoryBuffer() {
buffer_ = nullptr;
size_ = 0;
capacity_ = 0;
read_pos_ = 0;
write_pos_ = 0;
}
EQEmu::MemoryBuffer::MemoryBuffer(size_t sz) {
buffer_ = nullptr;
size_ = 0;
capacity_ = 0;
read_pos_ = 0;
write_pos_ = 0;
Resize(sz);
}
EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other) {
if(other.capacity_) {
buffer_ = new uchar[other.capacity_];
memcpy(buffer_, other.buffer_, other.capacity_);
} else {
buffer_ = nullptr;
}
size_ = other.size_;
capacity_ = other.capacity_;
write_pos_ = other.write_pos_;
read_pos_ = other.read_pos_;
}
EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) {
uchar *tbuf = other.buffer_;
size_t tsz = other.size_;
size_t tcapacity = other.capacity_;
size_t twrite_pos = other.write_pos_;
size_t tread_pos = other.read_pos_;
other.buffer_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
other.read_pos_ = 0;
other.write_pos_ = 0;
buffer_ = tbuf;
size_ = tsz;
capacity_ = tcapacity;
write_pos_ = twrite_pos;
read_pos_ = tread_pos;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) {
if(this == &other) {
return *this;
}
if(buffer_) {
delete[] buffer_;
}
if(other.capacity_) {
buffer_ = new uchar[other.capacity_];
memcpy(buffer_, other.buffer_, other.capacity_);
}
else {
buffer_ = nullptr;
}
size_ = other.size_;
capacity_ = other.capacity_;
write_pos_ = other.write_pos_;
read_pos_ = other.read_pos_;
return *this;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) {
uchar *tbuf = other.buffer_;
size_t tsz = other.size_;
size_t tcapacity = other.capacity_;
size_t twrite_pos = other.write_pos_;
size_t tread_pos = other.read_pos_;
other.buffer_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
other.read_pos_ = 0;
other.write_pos_ = 0;
buffer_ = tbuf;
size_ = tsz;
capacity_ = tcapacity;
write_pos_ = twrite_pos;
read_pos_ = tread_pos;
return *this;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator+=(const MemoryBuffer &rhs) {
if(!rhs.buffer_) {
return *this;
}
if(buffer_) {
size_t old_size = size_;
Resize(size_ + rhs.size_);
memcpy(&buffer_[old_size], rhs.buffer_, rhs.size_);
} else {
buffer_ = new uchar[rhs.capacity_];
memcpy(buffer_, rhs.buffer_, rhs.capacity_);
size_ = rhs.size_;
capacity_ = rhs.capacity_;
}
return *this;
}
EQEmu::MemoryBuffer::~MemoryBuffer() { Clear(); }
uchar& EQEmu::MemoryBuffer::operator[](size_t pos) {
return buffer_[pos];
}
const uchar& EQEmu::MemoryBuffer::operator[](size_t pos) const {
return buffer_[pos];
}
bool EQEmu::MemoryBuffer::Empty() {
return size_ == 0;
}
bool EQEmu::MemoryBuffer::Empty() const {
return size_ == 0;
}
size_t EQEmu::MemoryBuffer::Size() {
return size_;
}
size_t EQEmu::MemoryBuffer::Size() const {
return size_;
}
size_t EQEmu::MemoryBuffer::Capacity() {
return capacity_;
}
size_t EQEmu::MemoryBuffer::Capacity() const {
return capacity_;
}
void EQEmu::MemoryBuffer::Resize(size_t sz) {
if(!buffer_) {
size_t new_size = sz + 64;
buffer_ = new uchar[new_size];
capacity_ = new_size;
size_ = sz;
memset(buffer_, 0, capacity_);
return;
}
if(sz > capacity_) {
size_t new_size = sz + 32;
uchar *temp = new uchar[new_size];
memcpy(temp, buffer_, capacity_);
delete[] buffer_;
buffer_ = temp;
capacity_ = new_size;
size_ = sz;
}
else {
size_ = sz;
}
}
void EQEmu::MemoryBuffer::Clear() {
if(buffer_) {
delete[] buffer_;
buffer_ = nullptr;
}
size_ = 0;
capacity_ = 0;
write_pos_ = 0;
read_pos_ = 0;
}
void EQEmu::MemoryBuffer::Zero() {
if(buffer_) {
memset(buffer_, 0, capacity_);
}
}
void EQEmu::MemoryBuffer::Write(const char *val, size_t len) {
size_t size_needed = write_pos_ + len;
Resize(size_needed);
memcpy(&buffer_[write_pos_], val, len);
write_pos_ += len;
}
void EQEmu::MemoryBuffer::Read(uchar *buf, size_t len) {
memcpy(buf, &buffer_[read_pos_], len);
read_pos_ += len;
}
void EQEmu::MemoryBuffer::Read(char *str) {
size_t len = strlen((const char*)&buffer_[read_pos_]);
memcpy(str, &buffer_[read_pos_], len);
read_pos_ += len;
}
-124
View File
@@ -1,124 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_MEMORY_BUFFER_H
#define COMMON_MEMORY_BUFFER_H
#include "types.h"
#include <type_traits>
#include <string.h>
#include <string>
namespace EQEmu
{
class MemoryBuffer
{
public:
MemoryBuffer();
MemoryBuffer(size_t sz);
MemoryBuffer(const MemoryBuffer &other);
MemoryBuffer(MemoryBuffer &&other);
MemoryBuffer& operator=(const MemoryBuffer &other);
MemoryBuffer& operator=(MemoryBuffer &&other);
MemoryBuffer& operator+=(const MemoryBuffer &rhs);
friend MemoryBuffer operator+(MemoryBuffer lhs, const MemoryBuffer& rhs) { return lhs += rhs; }
~MemoryBuffer();
uchar& operator[](size_t pos);
const uchar& operator[](size_t pos) const;
template<typename T>
operator T*() {
return reinterpret_cast<T*>(buffer_);
}
template<typename T>
operator T*() const {
return reinterpret_cast<T*>(buffer_);
}
operator bool() { return buffer_ != nullptr; }
operator bool() const { return buffer_ != nullptr; }
bool Empty();
bool Empty() const;
size_t Size();
size_t Size() const;
size_t Capacity();
size_t Capacity() const;
void Resize(size_t sz);
void Clear();
void Zero();
template<typename T>
void Write(T val) {
static_assert(std::is_pod<T>::value, "MemoryBuffer::Write<T>(T val) only works on pod and string types.");
Write((const char*)&val, sizeof(T));
}
template<typename T>
T Read() {
static_assert(std::is_pod<T>::value, "MemoryBuffer::Read<T>() only works on pod and string types.");
T temp;
Read((uchar*)&temp, sizeof(T));
return temp;
}
void Write(const std::string &val) {
Write(val.c_str(), val.length());
Write((uint8)0);
}
void Write(const char *val) {
size_t len = strlen(val);
Write(val, len);
Write((uint8)0);
}
std::string ReadString() {
std::string ret;
size_t len = strlen((const char*)&buffer_[read_pos_]);
ret.resize(len);
memcpy(&ret[0], &buffer_[read_pos_], len);
read_pos_ += len + 1;
return ret;
}
void Write(const char *val, size_t len);
void Read(uchar *buf, size_t len);
void Read(char *str);
inline size_t GetWritePosition() { return write_pos_; }
inline void SetWritePosition(size_t wp) { write_pos_ = wp; }
inline void WriteSkipBytes(size_t skip) { write_pos_ += skip; }
inline size_t GetReadPosition() { return read_pos_; }
inline void SetReadPosition(size_t wp) { read_pos_ = wp; }
inline void ReadSkipBytes(size_t skip) { read_pos_ += skip; }
private:
uchar *buffer_;
size_t size_;
size_t capacity_;
size_t write_pos_;
size_t read_pos_;
};
} // EQEmu
#endif
+34 -64
View File
@@ -24,36 +24,6 @@
std::map<int,std::string> DBFieldNames;
#ifndef WIN32
#if defined(FREEBSD) || defined(__CYGWIN__)
int print_stacktrace()
{
printf("Insert stack trace here...\n");
return(0);
}
#else //!WIN32 && !FREEBSD == linux
#include <execinfo.h>
int print_stacktrace()
{
void *ba[20];
int n = backtrace (ba, 20);
if (n != 0)
{
char **names = backtrace_symbols (ba, n);
if (names != nullptr)
{
int i;
std::cerr << "called from " << (char*)names[0] << std::endl;
for (i = 1; i < n; ++i)
std::cerr << " " << (char*)names[i] << std::endl;
free (names);
}
}
return(0);
}
#endif //!FREEBSD
#endif //!WIN32
void Unprotect(std::string &s, char what)
{
if (s.length()) {
@@ -78,12 +48,12 @@ void Protect(std::string &s, char what)
*/
bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::string> > &items, int id_pos, int name_pos, int max_field, int level)
{
int i;
char *end,*ptr;
std::map<int,std::string> field;
static char *buffer=nullptr;
static int buffsize=0;
static char *temp=nullptr;
int i;
char *end,*ptr;
std::map<int,std::string> field;
static char *buffer=nullptr;
static int buffsize=0;
static char *temp=nullptr;
if (!buffsize || buffsize<(length+1)) {
buffer=(char *)realloc(buffer,length+1);
temp=(char *)realloc(temp,length+1);
@@ -186,10 +156,10 @@ static char *temp=nullptr;
int Tokenize(std::string s,std::map<int,std::string> & tokens, char delim)
{
int i,len;
std::string::size_type end;
//char temp[1024];
std::string x;
int i,len;
std::string::size_type end;
//char temp[1024];
std::string x;
tokens.clear();
i=0;
while(s.length()) {
@@ -335,14 +305,14 @@ void LoadItemDBFieldNames() {
void encode_length(unsigned long length, char *out)
{
char buf[4];
char buf[4];
memcpy(buf,&length,sizeof(unsigned long));
encode_chunk(buf,3,out);
}
unsigned long encode(char *in, unsigned long length, char *out)
{
unsigned long used=0,len=0;
unsigned long used=0,len=0;
while(used<length) {
encode_chunk(in+used,length-used,out+len);
used+=3;
@@ -355,8 +325,8 @@ unsigned long used=0,len=0;
unsigned long decode_length(char *in)
{
int length;
char buf[4];
int length;
char buf[4];
decode_chunk(in,&buf[0]);
buf[3]=0;
memcpy(&length,buf,sizeof(unsigned long));
@@ -366,8 +336,8 @@ char buf[4];
void decode(char *in, char *out)
{
char *ptr=in;
char *outptr=out;
char *ptr=in;
char *outptr=out;
while(*ptr) {
decode_chunk(ptr,outptr);
ptr+=4;
@@ -393,8 +363,8 @@ void decode_chunk(char *in, char *out)
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
{
unsigned long i,j;
unsigned long rows,offset=0;
unsigned long i,j;
unsigned long rows,offset=0;
rows=(length/16)+1;
for(i=0;i<rows;i++) {
fprintf(to, "%s%05ld: ",leader.c_str(),i*16);
@@ -419,8 +389,8 @@ unsigned long rows,offset=0;
std::string long2ip(unsigned long ip)
{
char temp[16];
union { unsigned long ip; struct { unsigned char a,b,c,d; } octet;} ipoctet;
char temp[16];
union { unsigned long ip; struct { unsigned char a,b,c,d; } octet;} ipoctet;
ipoctet.ip=ip;
sprintf(temp,"%d.%d.%d.%d",ipoctet.octet.a,ipoctet.octet.b,ipoctet.octet.c,ipoctet.octet.d);
@@ -430,8 +400,8 @@ union { unsigned long ip; struct { unsigned char a,b,c,d; } octet;} ipoctet;
std::string string_from_time(std::string pattern, time_t now)
{
struct tm *now_tm;
char time_string[51];
struct tm *now_tm;
char time_string[51];
if (!now)
time(&now);
@@ -450,9 +420,9 @@ std::string timestamp(time_t now)
std::string pop_arg(std::string &s, std::string seps, bool obey_quotes)
{
std::string ret;
unsigned long i;
bool in_quote=false;
std::string ret;
unsigned long i;
bool in_quote=false;
unsigned long length=s.length();
for(i=0;i<length;i++) {
@@ -481,8 +451,8 @@ bool in_quote=false;
int EQsprintf(char *buffer, const char *pattern, const char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *arg5, const char *arg6, const char *arg7, const char *arg8, const char *arg9)
{
const char *args[9],*ptr;
char *bptr;
const char *args[9],*ptr;
char *bptr;
args[0]=arg1;
args[1]=arg2;
args[2]=arg3;
@@ -524,11 +494,11 @@ char *bptr;
std::string generate_key(int length)
{
std::string key;
//TODO: write this for win32...
std::string key;
//TODO: write this for win32...
#ifndef WIN32
int i;
timeval now;
int i;
timeval now;
static const char *chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for(i=0;i<length;i++) {
gettimeofday(&now,nullptr);
@@ -550,9 +520,9 @@ void print_hex(const char *data, unsigned long length) {
void build_hex_line(const char *buffer, unsigned long length, unsigned long offset, char *out_buffer, unsigned char padding)
{
char *ptr=out_buffer;
int i;
char printable[17];
char *ptr=out_buffer;
int i;
char printable[17];
ptr+=sprintf(ptr,"%0*lu:",padding,offset);
for(i=0;i<16; i++) {
if (i==8) {
-4
View File
@@ -24,10 +24,6 @@ void decode(char *in, char *out);
void encode_chunk(char *in, int len, char *out);
void decode_chunk(char *in, char *out);
#ifndef WIN32
int print_stacktrace();
#endif
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader="", FILE *to = stdout);
std::string string_from_time(std::string pattern, time_t now=0);
std::string timestamp(time_t now=0);
-1
View File
@@ -32,7 +32,6 @@ MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, u
void MySQLRequestResult::FreeInternals()
{
safe_delete_array(m_ErrorBuffer);
if (m_Result != nullptr)
+3 -3
View File
@@ -180,7 +180,7 @@ IN(OP_GMLastName, GMLastName_Struct);
IN(OP_GMToggle, GMToggle_Struct);
IN(OP_LFGCommand, LFG_Struct);
IN(OP_GMGoto, GMSummon_Struct);
INv(OP_TraderShop, TraderClick_Struct);
IN(OP_TraderShop, TraderClick_Struct);
IN(OP_ShopRequest, Merchant_Click_Struct);
IN(OP_Bazaar, BazaarSearch_Struct);
//alt:IN(OP_Bazaar, BazaarWelcome_Struct); //alternate structure for OP_Bazaar
@@ -399,7 +399,7 @@ OUT(OP_Weather, Weather_Struct);
OUT(OP_ZoneChange, ZoneChange_Struct);
OUT(OP_ZoneInUnknown, ZoneInUnknown_Struct);
//this is the set of opcodes which are already listed
//this is the set of opcodes which are allready listed
//in the IN section above, but are also sent OUT
#ifdef DISJOINT_DIRECTIONS
OUTz(OP_ClientReady); //follows OP_SetServerFilter
@@ -449,7 +449,7 @@ OUT(OP_Trader, TraderBuy_Struct); //3 possible lengths
//alt:OUT(OP_Trader, Trader_ShowItems_Struct);
//alt:OUT(OP_Trader, Trader_Struct);
OUT(OP_TraderBuy, TraderBuy_Struct);
OUTv(OP_TraderShop, TraderClick_Struct);
OUT(OP_TraderShop, TraderClick_Struct);
OUT(OP_WearChange, WearChange_Struct);
OUT(OP_ZoneEntry, ServerZoneEntry_Struct);
#endif
-307
View File
@@ -1,307 +0,0 @@
#include "global_define.h"
#include <map>
#include <string>
std::map<unsigned long, std::string> opcode_map;
std::string get_opcode_name(unsigned long opcode)
{
std::map<unsigned long, std::string>::iterator itr;;
return (itr = opcode_map.find(opcode)) != opcode_map.end() ? itr->second : "OP_Unknown";
}
void load_opcode_names()
{
opcode_map[0x0176] = "LiveOP_Heartbeat";
opcode_map[0x02d7] = "LiveOP_ReloadUI";
opcode_map[0x01eb] = "LiveOP_IncreaseStats";
opcode_map[0x0134] = "LiveOP_ApproveZone";
opcode_map[0x01d5] = "LiveOP_Dye";
opcode_map[0x0168] = "LiveOP_Stamina";
opcode_map[0x014d] = "LiveOP_ControlBoat";
opcode_map[0x003e] = "LiveOP_MobUpdate";
opcode_map[0x0027] = "LiveOP_ClientUpdate";
opcode_map[0x0024] = "LiveOP_ChannelMessage";
opcode_map[0x01d7] = "LiveOP_SimpleMessage";
opcode_map[0x01d8] = "LiveOP_FormattedMessage";
opcode_map[0x01c6] = "LiveOP_TGB";
opcode_map[0x0285] = "LiveOP_TestBuff";
opcode_map[0x012d] = "LiveOP_Bind_Wound";
opcode_map[0x01ab] = "LiveOP_Charm";
opcode_map[0x014c] = "LiveOP_Begging";
opcode_map[0x0152] = "LiveOP_MoveCoin";
opcode_map[0x0292] = "LiveOP_SpawnDoor";
opcode_map[0x009d] = "LiveOP_Sneak";
opcode_map[0x0079] = "LiveOP_ExpUpdate";
opcode_map[0x027d] = "LiveOP_DumpName";
opcode_map[0x01ea] = "LiveOP_RespondAA";
opcode_map[0x01c9] = "LiveOP_SendAAStats";
opcode_map[0x0366] = "LiveOP_SendAATable";
opcode_map[0x01e9] = "LiveOP_AAAction";
opcode_map[0x00bb] = "LiveOP_BoardBoat";
opcode_map[0x00bc] = "LiveOP_LeaveBoat";
opcode_map[0x02b8] = "LiveOP_AdventureInfoRequest";
opcode_map[0x02b9] = "LiveOP_AdventureInfo";
opcode_map[0x02a6] = "LiveOP_AdventureRequest";
opcode_map[0x02a8] = "LiveOP_AdventureDetails";
opcode_map[0x02a9] = "LiveOP_LDoNButton";
opcode_map[0x02ba] = "LiveOP_AdventureData";
opcode_map[0x02c9] = "LiveOP_AdventureFinish";
opcode_map[0x02c6] = "LiveOP_LeaveAdventure";
opcode_map[0x02ce] = "LiveOP_AdventureUpdate";
opcode_map[0x002b] = "LiveOP_SendExpZonein";
opcode_map[0x01e4] = "LiveOP_ZoneInSendName";
opcode_map[0x01bf] = "LiveOP_GuildLeader";
opcode_map[0x009a] = "LiveOP_GuildPeace";
opcode_map[0x0132] = "LiveOP_GuildRemove";
opcode_map[0x0059] = "LiveOP_GuildMemberList";
opcode_map[0x026e] = "LiveOP_GuildMemberUpdate";
opcode_map[0x0130] = "LiveOP_GuildInvite";
opcode_map[0x01c0] = "LiveOP_GuildMOTD";
opcode_map[0x003c] = "LiveOP_GuildPublicNote";
opcode_map[0x027e] = "LiveOP_GetGuildMOTD";
opcode_map[0x0277] = "LiveOP_GuildDemote";
opcode_map[0x0131] = "LiveOP_GuildInviteAccept";
opcode_map[0x00a4] = "LiveOP_GuildWar";
opcode_map[0x0133] = "LiveOP_GuildDelete";
opcode_map[0x0233] = "LiveOP_GuildManageRemove";
opcode_map[0x022d] = "LiveOP_GuildManageAdd";
opcode_map[0x0039] = "LiveOP_GuildManageStatus";
opcode_map[0x01e8] = "LiveOP_Trader";
opcode_map[0x01e7] = "LiveOP_Bazaar";
opcode_map[0x01c4] = "LiveOP_BecomeTrader";
opcode_map[0x01f4] = "LiveOP_BazaarInspect";
opcode_map[0x006e] = "LiveOP_TraderItemUpdate";
opcode_map[0x017c] = "LiveOP_TraderDelItem";
opcode_map[0x01eb] = "LiveOP_TraderShop";
opcode_map[0x01ca] = "LiveOP_TraderBuy";
opcode_map[0x01ac] = "LiveOP_PetCommands";
opcode_map[0x0042] = "LiveOP_TradeSkillCombine";
opcode_map[0x02e5] = "LiveOP_AugmentItem";
opcode_map[0x0367] = "LiveOP_ItemName";
opcode_map[0x02cd] = "LiveOP_ShopItem";
opcode_map[0x0065] = "LiveOP_ShopPlayerBuy";
opcode_map[0x006a] = "LiveOP_ShopPlayerSell";
opcode_map[0x006d] = "LiveOP_ShopDelItem";
opcode_map[0x0f6d] = "LiveOP_ShopEndConfirm";
opcode_map[0x00f7] = "LiveOP_ShopRequest";
opcode_map[0x006c] = "LiveOP_ShopEnd";
opcode_map[0x02d1] = "LiveOP_AdventureMerchantRequest";
opcode_map[0x02d2] = "LiveOP_AdventureMerchantResponse";
opcode_map[0x02d3] = "LiveOP_AdventureMerchantPurchase";
opcode_map[0x02e3] = "LiveOP_AdventurePointsUpdate";
opcode_map[0x0270] = "LiveOP_LFGCommand";
opcode_map[0x01d0] = "LiveOP_LFGAppearance";
opcode_map[0x01b5] = "LiveOP_MoneyUpdate";
opcode_map[0x0721] = "LiveOP_GroupDelete";
opcode_map[0x0272] = "LiveOP_GroupAcknowledge";
opcode_map[0x024a] = "LiveOP_GroupUpdate";
opcode_map[0x025f] = "LiveOP_GroupInvite";
opcode_map[0x00ff] = "LiveOP_GroupDisband";
opcode_map[0x00d5] = "LiveOP_GroupInvite2";
opcode_map[0x025e] = "LiveOP_GroupFollow";
opcode_map[0x00d7] = "LiveOP_GroupFollow2";
opcode_map[0x00d6] = "LiveOP_GroupCancelInvite";
opcode_map[0x0156] = "LiveOP_Split";
opcode_map[0x00d8] = "LiveOP_Jump";
opcode_map[0x01d6] = "LiveOP_ConsiderCorpse";
opcode_map[0x0064] = "LiveOP_SkillUpdate";
opcode_map[0x0178] = "LiveOP_GMEndTrainingResponse";
opcode_map[0x013c] = "LiveOP_GMEndTraining";
opcode_map[0x0175] = "LiveOP_GMTrainSkill";
opcode_map[0x013b] = "LiveOP_GMTraining";
opcode_map[0x017b] = "LiveOP_ConsumeAmmo";
opcode_map[0x0171] = "LiveOP_CombatAbility";
opcode_map[0x009c] = "LiveOP_TrackUnknown";
opcode_map[0x0234] = "LiveOP_TrackTarget";
opcode_map[0x0286] = "LiveOP_Track";
opcode_map[0x0297] = "LiveOP_ReadBook";
opcode_map[0x001f] = "LiveOP_ItemLinkClick";
opcode_map[0x01f4] = "LiveOP_ItemLinkResponse";
opcode_map[0x01d9] = "LiveOP_ItemLinkText";
opcode_map[0x0a41] = "LiveOP_RezzRequest";
opcode_map[0x00e5] = "LiveOP_RezzAnswer";
opcode_map[0x019b] = "LiveOP_RezzComplete";
opcode_map[0x0128] = "LiveOP_MoveDoor";
opcode_map[0x0127] = "LiveOP_ClickDoor";
opcode_map[0x0247] = "LiveOP_SendZonepoints";
opcode_map[0x008c] = "LiveOP_SetRunMode";
opcode_map[0x0248] = "LiveOP_InspectRequest";
opcode_map[0x0249] = "LiveOP_InspectAnswer";
opcode_map[0x0187] = "LiveOP_SenseTraps";
opcode_map[0x018e] = "LiveOP_DisarmTraps";
opcode_map[0x01bc] = "LiveOP_Assist";
opcode_map[0x0240] = "LiveOP_PickPocket";
opcode_map[0x0119] = "LiveOP_LootRequest";
opcode_map[0x011a] = "LiveOP_EndLootRequest";
opcode_map[0x011b] = "LiveOP_MoneyOnCorpse";
opcode_map[0x0179] = "LiveOP_LootComplete";
opcode_map[0x013f] = "LiveOP_LootItem";
opcode_map[0x0151] = "LiveOP_MoveItem";
opcode_map[0x0056] = "LiveOP_WhoAllRequest";
opcode_map[0x0229] = "LiveOP_WhoAllResponse";
opcode_map[0x0167] = "LiveOP_Consume";
opcode_map[0x0172] = "LiveOP_AutoAttack";
opcode_map[0x0186] = "LiveOP_AutoAttack2";
opcode_map[0x0173] = "LiveOP_TargetMouse";
opcode_map[0x01ba] = "LiveOP_TargetCommand";
opcode_map[0x01d8] = "LiveOP_TargetReject";
opcode_map[0x009e] = "LiveOP_Hide";
opcode_map[0x012e] = "LiveOP_Forage";
opcode_map[0x0077] = "LiveOP_Fishing";
opcode_map[0x0246] = "LiveOP_Bug";
opcode_map[0x00f2] = "LiveOP_Emote";
opcode_map[0x0140] = "LiveOP_EmoteAnim";
opcode_map[0x015c] = "LiveOP_Consider";
opcode_map[0x01cb] = "LiveOP_FaceChange";
opcode_map[0x0197] = "LiveOP_RandomReq";
opcode_map[0x0087] = "LiveOP_RandomReply";
opcode_map[0x01c3] = "LiveOP_Camp";
opcode_map[0x0192] = "LiveOP_YellForHelp";
opcode_map[0x00ef] = "LiveOP_SafePoint";
opcode_map[0x0157] = "LiveOP_Buff";
opcode_map[0x00c0] = "LiveOP_ColoredText";
opcode_map[0x0440] = "LiveOP_MultiLineMsg";
opcode_map[0x021c] = "LiveOP_SpecialMesg";
opcode_map[0x0013] = "LiveOP_Consent";
opcode_map[0x029d] = "LiveOP_ConsentResponse";
opcode_map[0x02d4] = "LiveOP_Deny";
opcode_map[0x016c] = "LiveOP_Stun";
opcode_map[0x0021] = "LiveOP_BeginCast";
opcode_map[0x00be] = "LiveOP_CastSpell";
opcode_map[0x01a8] = "LiveOP_InterruptCast";
opcode_map[0x0105] = "LiveOP_Death";
opcode_map[0x023f] = "LiveOP_FeignDeath";
opcode_map[0x012b] = "LiveOP_Illusion";
opcode_map[0x0078] = "LiveOP_LevelUpdate";
opcode_map[0x0371] = "LiveOP_LevelAppearance";
opcode_map[0x00c2] = "LiveOP_MemorizeSpell";
opcode_map[0x0244] = "LiveOP_HPUpdate";
opcode_map[0x022e] = "LiveOP_SendHPTarget";
opcode_map[0x007d] = "LiveOP_Mend";
opcode_map[0x0160] = "LiveOP_Taunt";
opcode_map[0x0199] = "LiveOP_GMDelCorpse";
opcode_map[0x0047] = "LiveOP_GMFind";
opcode_map[0x0020] = "LiveOP_GMServers";
opcode_map[0x010b] = "LiveOP_GMGoto";
opcode_map[0x028c] = "LiveOP_GMSummon";
opcode_map[0x010a] = "LiveOP_GMKick";
opcode_map[0x0109] = "LiveOP_GMKill";
opcode_map[0x0b40] = "LiveOP_GMNameChange";
opcode_map[0x00a3] = "LiveOP_GMLastName";
opcode_map[0x01b3] = "LiveOP_GMToggle";
opcode_map[0x028f] = "LiveOP_GMEmoteZone";
opcode_map[0x0074] = "LiveOP_GMBecomeNPC";
opcode_map[0x00de] = "LiveOP_GMHideMe";
opcode_map[0x0184] = "LiveOP_GMZoneRequest";
opcode_map[0x0239] = "LiveOP_GMZoneRequest2";
opcode_map[0x0068] = "LiveOP_Petition";
opcode_map[0x0085] = "LiveOP_PetitionRefresh";
opcode_map[0x01ee] = "LiveOP_PDeletePetition";
opcode_map[0x0092] = "LiveOP_PetitionBug";
opcode_map[0x0069] = "LiveOP_PetitionUpdate";
opcode_map[0x0076] = "LiveOP_PetitionCheckout";
opcode_map[0x0056] = "LiveOP_PetitionCheckout2";
opcode_map[0x0091] = "LiveOP_PetitionDelete";
opcode_map[0x02b4] = "LiveOP_PetitionResolve";
opcode_map[0x007e] = "LiveOP_PetitionCheckIn";
opcode_map[0x0090] = "LiveOP_PetitionUnCheckout";
opcode_map[0x01ec] = "LiveOP_PetitionQue";
opcode_map[0x01bb] = "LiveOP_SetServerFilter";
opcode_map[0x0218] = "LiveOP_NewSpawn";
opcode_map[0x0140] = "LiveOP_Animation";
opcode_map[0x0142] = "LiveOP_ZoneChange";
opcode_map[0x00f3] = "LiveOP_DeleteSpawn";
opcode_map[0x0265] = "LiveOP_CrashDump";
opcode_map[0x00e8] = "LiveOP_EnvDamage";
opcode_map[0x0101] = "LiveOP_Action";
opcode_map[0x00e2] = "LiveOP_Damage";
opcode_map[0x00bf] = "LiveOP_ManaChange";
opcode_map[0x027c] = "LiveOP_ClientError";
opcode_map[0x00fb] = "LiveOP_Save";
opcode_map[0x0316] = "LiveOP_LocInfo";
opcode_map[0x0188] = "LiveOP_Surname";
opcode_map[0x018f] = "LiveOP_SwapSpell";
opcode_map[0x01db] = "LiveOP_DeleteSpell";
opcode_map[0x029f] = "LiveOP_CloseContainer";
opcode_map[0x029f] = "LiveOP_ClickObjectAck";
opcode_map[0x00fa] = "LiveOP_CreateObject";
opcode_map[0x00f9] = "LiveOP_ClickObject";
opcode_map[0x01c1] = "LiveOP_ClearObject";
opcode_map[0x0265] = "LiveOP_ZoneUnavail";
opcode_map[0x02e0] = "LiveOP_ItemPacket";
opcode_map[0x029a] = "LiveOP_TradeRequest";
opcode_map[0x0037] = "LiveOP_TradeRequestAck";
opcode_map[0x002d] = "LiveOP_TradeAcceptClick";
opcode_map[0x0162] = "LiveOP_TradeMoneyUpdate";
opcode_map[0x0036] = "LiveOP_TradeCoins";
opcode_map[0x002e] = "LiveOP_CancelTrade";
opcode_map[0x002f] = "LiveOP_FinishTrade";
opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq";
opcode_map[0x0185] = "LiveOP_Logout";
opcode_map[0x0298] = "LiveOP_RequestDuel";
opcode_map[0x0a5d] = "LiveOP_DuelResponse";
opcode_map[0x016e] = "LiveOP_DuelResponse2";
opcode_map[0x007c] = "LiveOP_InstillDoubt";
opcode_map[0x00ac] = "LiveOP_SafeFallSuccess";
opcode_map[0x02fb] = "LiveOP_DisciplineUpdate";
opcode_map[0x02f2] = "LiveOP_TributeUpdate";
opcode_map[0x02f3] = "LiveOP_TributeItem";
opcode_map[0x02f4] = "LiveOP_TributePointUpdate";
opcode_map[0x02f5] = "LiveOP_SendTributes";
opcode_map[0x02f6] = "LiveOP_TributeInfo";
opcode_map[0x02f7] = "LiveOP_SelectTribute";
opcode_map[0x02f8] = "LiveOP_TributeTimer";
opcode_map[0x02f9] = "LiveOP_StartTribute";
opcode_map[0x02fa] = "LiveOP_TributeNPC";
opcode_map[0x02fe] = "LiveOP_TributeMoney";
opcode_map[0x0364] = "LiveOP_TributeToggle";
opcode_map[0x0322] = "LiveOP_RecipesFavorite";
opcode_map[0x01f9] = "LiveOP_RecipesSearch";
opcode_map[0x01fa] = "LiveOP_RecipeReply";
opcode_map[0x01fb] = "LiveOP_RecipeDetails";
opcode_map[0x01fc] = "LiveOP_RecipeAutoCombine";
opcode_map[0x02db] = "LiveOP_FindPersonRequest";
opcode_map[0x02dc] = "LiveOP_FindPersonReply";
opcode_map[0x01dd] = "LiveOP_Shielding";
opcode_map[0x0198] = "LiveOP_SetDataRate";
opcode_map[0x023b] = "LiveOP_ZoneEntry";
opcode_map[0x006b] = "LiveOP_PlayerProfile";
opcode_map[0x0291] = "LiveOP_CharInventory";
opcode_map[0x0170] = "LiveOP_ZoneSpawns";
opcode_map[0x0026] = "LiveOP_TimeOfDay";
opcode_map[0x015b] = "LiveOP_Weather";
opcode_map[0x00ec] = "LiveOP_ReqNewZone";
opcode_map[0x00eb] = "LiveOP_NewZone";
opcode_map[0x00fd] = "LiveOP_ReqClientSpawn";
opcode_map[0x012F] = "LiveOP_SpawnAppearance";
opcode_map[0x0086] = "LiveOP_ClientReady";
opcode_map[0x0086] = "LiveOP_ZoneComplete";
opcode_map[0x02db] = "LiveOP_LoginComplete";
opcode_map[0x0195] = "LiveOP_ApproveWorld";
opcode_map[0x035f] = "LiveOP_LogServer";
opcode_map[0x01b2] = "LiveOP_MOTD";
opcode_map[0x0251] = "LiveOP_SendLoginInfo";
opcode_map[0x00ea] = "LiveOP_DeleteCharacter";
opcode_map[0x0102] = "LiveOP_SendCharInfo";
opcode_map[0x00e1] = "LiveOP_ExpansionInfo";
opcode_map[0x0104] = "LiveOP_CharacterCreate";
opcode_map[0x02ab] = "LiveOP_RandomNameGenerator";
opcode_map[0x005d] = "LiveOP_GuildsList";
opcode_map[0x0125] = "LiveOP_ApproveName";
opcode_map[0x0261] = "LiveOP_EnterWorld";
opcode_map[0x015a] = "LiveOP_World_Client_CRC1";
opcode_map[0x015e] = "LiveOP_World_Client_CRC2";
opcode_map[0x0269] = "LiveOP_SetChatServer";
opcode_map[0x0264] = "LiveOP_ZoneServerInfo";
opcode_map[0x0017] = "LiveOP_AckPacket";
opcode_map[0x012c] = "LiveOP_WearChange";
opcode_map[0x1FA1] = "LiveOP_WorldObjectsSent";
opcode_map[0x39C4] = "LiveOP_BlockedBuffs";
opcode_map[0x4656] = "LiveOP_SpawnPositionUpdate";
opcode_map[0x4b61] = "LiveOP_ManaUpdate";
opcode_map[0x02d6] = "LiveOP_EnduranceUpdate";
opcode_map[0x2ac1] = "LiveOP_MobManaUpdate";
opcode_map[0x6c5f] = "LiveOP_MobEnduranceUpdate";
opcode_map[0x73a8] = "LiveOP_SendMaxCharacters";
}
-438
View File
@@ -1,438 +0,0 @@
#ifndef WIN32
#include <unistd.h>
#else
#include <winsock2.h>
#endif
#include <errno.h>
#include <string.h>
#include <time.h>
#include "packetfile.h"
#include "../common/eq_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "../common/misc.h"
#include <map>
PacketFileWriter::PacketFileWriter(bool _force_flush) {
out = NULL;
force_flush = _force_flush;
}
PacketFileWriter::~PacketFileWriter() {
CloseFile();
}
bool PacketFileWriter::SetPacketStamp(const char *name, uint32 stamp) {
FILE *in;
in = fopen(name, "r+b");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
unsigned long magic = 0;
if(fread(&magic, sizeof(magic), 1, in) != 1) {
fprintf(stderr, "Error reading header from packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
PacketFileReader *ret = NULL;
if(magic == OLD_PACKET_FILE_MAGIC) {
OldPacketFileHeader *pos = 0;
uint32 stamp_pos = (uint32) &pos->packet_file_stamp;
fseek(in, stamp_pos, SEEK_SET);
OldPacketFileHeader hdr;
hdr.packet_file_stamp = stamp;
if(fwrite(&hdr.packet_file_stamp, sizeof(hdr.packet_file_stamp), 1, in) != 1) {
fprintf(stderr, "Error writting to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
} else if(magic == PACKET_FILE_MAGIC) {
PacketFileHeader *pos = 0;
uint32 stamp_pos = (uint32) &pos->packet_file_stamp;
fseek(in, stamp_pos, SEEK_SET);
PacketFileHeader hdr;
hdr.packet_file_stamp = stamp;
if(fwrite(&hdr.packet_file_stamp, sizeof(hdr.packet_file_stamp), 1, in) != 1) {
fprintf(stderr, "Error writting to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
} else {
fprintf(stderr, "Unknown packet file type 0x%.8x\n", magic);
fclose(in);
return(false);
}
fclose(in);
return(true);
}
bool PacketFileWriter::OpenFile(const char *name) {
CloseFile();
printf("Opening packet file: %s\n", name);
out = fopen(name, "wb");
if(out == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
PacketFileHeader head;
head.packet_file_magic = PACKET_FILE_MAGIC;
head.packet_file_version = PACKET_FILE_CURRENT_VERSION;
head.packet_file_stamp = time(NULL);
if(fwrite(&head, sizeof(head), 1, out) != 1) {
fprintf(stderr, "Error writting header to packet file: %s\n", strerror(errno));
fclose(out);
return(false);
}
return(true);
}
void PacketFileWriter::CloseFile() {
if(out != NULL) {
fclose(out);
out = NULL;
printf("Closed packet file.\n");
}
}
void PacketFileWriter::WritePacket(uint16 eq_op, uint32 packlen, const unsigned char *packet, bool to_server, const struct timeval &tv) {
if(out == NULL)
return;
_WriteBlock(eq_op, packet, packlen, to_server, tv);
/*
Could log only the packets we care about, but this is most of the stream,
so just log them all...
switch(eq_op) {
case OP_NewZone:
case OP_ZoneSpawns:
case OP_NewSpawn:
case OP_MobUpdate:
case OP_ClientUpdate:
case OP_Death:
case OP_DeleteSpawn:
case OP_CastSpell:
case OP_ShopRequest:
case OP_ShopEndConfirm:
case OP_ItemPacket:
_WriteBlock(eq_op, packet, packlen);
default:
return;
}
*/
}
bool PacketFileWriter::_WriteBlock(uint16 eq_op, const void *d, uint16 len, bool to_server, const struct timeval &tv) {
if(out == NULL)
return(false);
PacketFileSection s;
s.opcode = eq_op;
s.len = len;
s.tv_sec = tv.tv_sec;
s.tv_msec = tv.tv_usec/1000;
if(to_server)
SetToServer(s);
else
SetToClient(s);
if(fwrite(&s, sizeof(s), 1, out) != 1) {
fprintf(stderr, "Error writting block header: %s\n", strerror(errno));
return(false);
}
if(fwrite(d, 1, len, out) != len) {
fprintf(stderr, "Error writting block body: %s\n", strerror(errno));
return(false);
}
if(force_flush)
fflush(out);
return(true);
}
PacketFileReader *PacketFileReader::OpenPacketFile(const char *name) {
FILE *in;
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(NULL);
}
unsigned long magic = 0;
if(fread(&magic, sizeof(magic), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(NULL);
}
PacketFileReader *ret = NULL;
if(magic == OLD_PACKET_FILE_MAGIC) {
ret = new OldPacketFileReader();
} else if(magic == PACKET_FILE_MAGIC) {
ret = new NewPacketFileReader();
} else {
fprintf(stderr, "Unknown packet file type 0x%.8x\n", magic);
fclose(in);
return(NULL);
}
if(!ret->OpenFile(name)) {
safe_delete(ret);
return(NULL);
}
return(ret);
}
PacketFileReader::PacketFileReader() {
packet_file_stamp = 0;
}
OldPacketFileReader::OldPacketFileReader()
: PacketFileReader()
{
in = NULL;
}
OldPacketFileReader::~OldPacketFileReader() {
CloseFile();
}
bool OldPacketFileReader::OpenFile(const char *name) {
CloseFile();
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
OldPacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
if(head.packet_file_magic != OLD_PACKET_FILE_MAGIC) {
fclose(in);
if(head.packet_file_magic > (OLD_PACKET_FILE_MAGIC)) {
fprintf(stderr, "Error: this is a build file, not a packet file, its allready processed!\n");
} else {
fprintf(stderr, "Error: this is not a packet file!\n");
}
return(false);
}
uint32 now = time(NULL);
if(head.packet_file_stamp > now) {
fprintf(stderr, "Error: invalid timestamp in file. Your clock or the collector's is wrong (%d sec ahead).\n", head.packet_file_stamp-now);
fclose(in);
return(false);
}
packet_file_stamp = head.packet_file_stamp;
return(true);
}
void OldPacketFileReader::CloseFile() {
if(in != NULL) {
fclose(in);
in = NULL;
}
}
bool OldPacketFileReader::ResetFile() {
if(in == NULL)
return(false);
rewind(in);
//gotta read past the header again
OldPacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
return(false);
}
return(true);
}
bool OldPacketFileReader::ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) {
if(in == NULL)
return(false);
if(feof(in))
return(false);
OldPacketFileSection s;
if(fread(&s, sizeof(s), 1, in) != 1) {
if(!feof(in))
fprintf(stderr, "Error reading section header: %s\n", strerror(errno));
return(false);
}
eq_op = s.opcode;
if(packlen < s.len) {
fprintf(stderr, "Packet buffer is too small! %d < %d, skipping\n", packlen, s.len);
fseek(in, s.len, SEEK_CUR);
return(false);
}
if(fread(packet, 1, s.len, in) != s.len) {
if(feof(in))
fprintf(stderr, "Error: EOF encountered when expecting packet data.\n");
else
fprintf(stderr, "Error reading packet body: %s\n", strerror(errno));
return(false);
}
packlen = s.len;
to_server = false;
tv.tv_sec = 0;
tv.tv_usec = 0;
return(true);
}
NewPacketFileReader::NewPacketFileReader()
: PacketFileReader()
{
in = NULL;
}
NewPacketFileReader::~NewPacketFileReader() {
CloseFile();
}
bool NewPacketFileReader::OpenFile(const char *name) {
CloseFile();
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
PacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
if(head.packet_file_magic != PACKET_FILE_MAGIC) {
fclose(in);
if(head.packet_file_magic == (PACKET_FILE_MAGIC+1)) {
fprintf(stderr, "Error: this is a build file, not a packet file, its allready processed!\n");
} else {
fprintf(stderr, "Error: this is not a packet file!\n");
}
return(false);
}
uint32 now = time(NULL);
if(head.packet_file_stamp > now) {
fprintf(stderr, "Error: invalid timestamp in file. Your clock or the collector's is wrong (%d sec ahead).\n", head.packet_file_stamp-now);
fclose(in);
return(false);
}
packet_file_stamp = head.packet_file_stamp;
return(true);
}
void NewPacketFileReader::CloseFile() {
if(in != NULL) {
fclose(in);
in = NULL;
}
}
bool NewPacketFileReader::ResetFile() {
if(in == NULL)
return(false);
rewind(in);
//gotta read past the header again
PacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
return(false);
}
return(true);
}
bool NewPacketFileReader::ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) {
if(in == NULL)
return(false);
if(feof(in))
return(false);
PacketFileSection s;
if(fread(&s, sizeof(s), 1, in) != 1) {
if(!feof(in))
fprintf(stderr, "Error reading section header: %s\n", strerror(errno));
return(false);
}
eq_op = s.opcode;
if(packlen < s.len) {
fprintf(stderr, "Packet buffer is too small! %d < %d, skipping\n", packlen, s.len);
fseek(in, s.len, SEEK_CUR);
return(false);
}
if(fread(packet, 1, s.len, in) != s.len) {
if(feof(in))
fprintf(stderr, "Error: EOF encountered when expecting packet data.\n");
else
fprintf(stderr, "Error reading packet body: %s\n", strerror(errno));
return(false);
}
packlen = s.len;
to_server = IsToServer(s);
tv.tv_sec = s.tv_sec;
tv.tv_usec = 1000*s.tv_msec;
return(true);
}
-130
View File
@@ -1,130 +0,0 @@
#ifndef PACKET_FILE_H
#define PACKET_FILE_H
#include "../common/types.h"
#include <stdio.h>
#include <time.h>
//#include <zlib.h>
//constants used in the packet file header
#define PACKET_FILE_MAGIC 0x93a7b6f6
#define OLD_PACKET_FILE_MAGIC 0x93a7b6f7
#define PACKET_FILE_CURRENT_VERSION 1
#pragma pack(1)
//old structs from when I forgot to put the version number in
struct OldPacketFileHeader {
uint32 packet_file_magic;
uint32 packet_file_stamp;
};
struct OldPacketFileSection {
uint16 opcode;
uint32 len;
};
struct PacketFileHeader {
uint32 packet_file_magic;
uint16 packet_file_version;
uint32 packet_file_stamp;
};
struct PacketFileSection {
uint16 opcode;
uint8 flags; //mainly for client->server, but others could be added
uint32 tv_sec;
uint16 tv_msec;
uint32 len;
};
#pragma pack()
#define TO_SERVER_FLAG 0x01
#define SetToClient(pfs) pfs.flags = pfs.flags&~TO_SERVER_FLAG
#define SetToServer(pfs) pfs.flags = pfs.flags|TO_SERVER_FLAG
#define IsToClient(pfs) (pfs.flags&TO_SERVER_FLAG == 0)
#define IsToServer(pfs) (pfs.flags&TO_SERVER_FLAG != 0)
class PacketFileWriter {
public:
PacketFileWriter(bool force_flush);
~PacketFileWriter();
bool OpenFile(const char *name);
void CloseFile();
void WritePacket(uint16 eq_op, uint32 packlen, const unsigned char *packet, bool to_server, const struct timeval &tv);
static bool SetPacketStamp(const char *file, uint32 stamp);
protected:
bool _WriteBlock(uint16 eq_op, const void *d, uint16 len, bool to_server, const struct timeval &tv);
//gzFile out;
FILE *out;
bool force_flush;
};
class PacketFileReader {
public:
PacketFileReader();
virtual bool OpenFile(const char *name) = 0;
virtual void CloseFile() = 0;
virtual bool ResetFile() = 0; //aka rewind
virtual bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) = 0;
time_t GetStamp() { return(time_t(packet_file_stamp)); }
//factory method to open the right packet file.
static PacketFileReader *OpenPacketFile(const char *name);
protected:
uint32 packet_file_stamp;
};
class OldPacketFileReader : public PacketFileReader {
public:
OldPacketFileReader();
virtual ~OldPacketFileReader();
bool OpenFile(const char *name);
void CloseFile();
bool ResetFile(); //aka rewind
bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv);
time_t GetStamp() { return(time_t(packet_file_stamp)); }
protected:
//gzFile in;
FILE *in;
};
class NewPacketFileReader: public PacketFileReader {
public:
NewPacketFileReader();
virtual ~NewPacketFileReader();
bool OpenFile(const char *name);
void CloseFile();
bool ResetFile(); //aka rewind
bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv);
time_t GetStamp() { return(time_t(packet_file_stamp)); }
protected:
//gzFile in;
FILE *in;
};
#endif
+10 -10
View File
@@ -10,19 +10,19 @@
#include "rof2.h"
void RegisterAllPatches(EQStreamIdentifier &into) {
//Titanium::Register(into);
//SoF::Register(into);
//SoD::Register(into);
//UF::Register(into);
//RoF::Register(into);
Titanium::Register(into);
SoF::Register(into);
SoD::Register(into);
UF::Register(into);
RoF::Register(into);
RoF2::Register(into);
}
void ReloadAllPatches() {
//Titanium::Reload();
//SoF::Reload();
//SoD::Reload();
//UF::Reload();
//RoF::Reload();
Titanium::Reload();
SoF::Reload();
SoD::Reload();
UF::Reload();
RoF::Reload();
RoF2::Reload();
}
+280 -348
View File
@@ -15,8 +15,6 @@
#include <iostream>
#include <sstream>
#include <numeric>
#include <cassert>
namespace RoF
{
@@ -227,8 +225,8 @@ namespace RoF
SETUP_DIRECT_ENCODE(Animation_Struct, structs::Animation_Struct);
OUT(spawnid);
OUT(value);
OUT(action);
OUT(speed);
FINISH_ENCODE();
}
@@ -417,7 +415,7 @@ namespace RoF
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
outapp->WriteUInt8(0); // Caster name
outapp->WriteUInt8(0); // Type
outapp->WriteUInt8(0); // Terminating byte
}
FINISH_ENCODE();
@@ -454,7 +452,7 @@ namespace RoF
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
__packet->WriteString("");
}
__packet->WriteUInt8(emu->type); // Unknown
__packet->WriteUInt8(!emu->all_buffs); // Unknown
FINISH_ENCODE();
}
@@ -479,7 +477,7 @@ namespace RoF
eq->slot = 13;
else
OUT(slot);
OUT(spell_id);
eq->inventoryslot = ServerToRoFSlot(emu->inventoryslot);
//OUT(inventoryslot);
@@ -532,72 +530,71 @@ namespace RoF
{
//consume the packet
EQApplicationPacket *in = *p;
delete in;
//*p = nullptr;
//
//if (in->size == 0) {
//
// in->size = 4;
// in->pBuffer = new uchar[in->size];
//
// *((uint32 *)in->pBuffer) = 0;
//
// dest->FastQueuePacket(&in, ack_req);
// return;
//}
//
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
//
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
//
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
// opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
//
// delete in;
//
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
//
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
//
// if (Serialized) {
//
// uchar *OldBuffer = in->pBuffer;
// in->pBuffer = new uchar[in->size + Length];
// memcpy(in->pBuffer, OldBuffer, in->size);
//
// safe_delete_array(OldBuffer);
//
// memcpy(in->pBuffer + in->size, Serialized, Length);
// in->size += Length;
//
// safe_delete_array(Serialized);
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
*p = nullptr;
if (in->size == 0) {
in->size = 4;
in->pBuffer = new uchar[in->size];
*((uint32 *)in->pBuffer) = 0;
dest->FastQueuePacket(&in, ack_req);
return;
}
//store away the emu struct
unsigned char *__emu_buffer = in->pBuffer;
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
in->pBuffer = new uchar[4];
*(uint32 *)in->pBuffer = ItemCount;
in->size = 4;
for (int r = 0; r < ItemCount; r++, eq++) {
uint32 Length = 0;
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
if (Serialized) {
uchar *OldBuffer = in->pBuffer;
in->pBuffer = new uchar[in->size + Length];
memcpy(in->pBuffer, OldBuffer, in->size);
safe_delete_array(OldBuffer);
memcpy(in->pBuffer + in->size, Serialized, Length);
in->size += Length;
safe_delete_array(Serialized);
}
else {
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
}
}
delete[] __emu_buffer;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClickObjectAction)
@@ -659,9 +656,7 @@ namespace RoF
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
eq->sequence = emu->sequence;
FINISH_ENCODE();
}
@@ -705,7 +700,7 @@ namespace RoF
{
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
@@ -976,8 +971,8 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Unknown
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 1); // Need to add emu->size to struct
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
@@ -1252,7 +1247,7 @@ namespace RoF
switch (emu_e->rank) {
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
}
@@ -1709,14 +1704,14 @@ namespace RoF
ENCODE(OP_MoveItem)
{
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//eq->from_slot = ServerToRoFSlot(emu->from_slot);
//eq->to_slot = ServerToRoFSlot(emu->to_slot);
//OUT(number_in_stack);
//
//FINISH_ENCODE();
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
eq->from_slot = ServerToRoFSlot(emu->from_slot);
eq->to_slot = ServerToRoFSlot(emu->to_slot);
OUT(number_in_stack);
FINISH_ENCODE();
}
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
@@ -2048,7 +2043,7 @@ namespace RoF
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint[r].color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2058,7 +2053,7 @@ namespace RoF
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint[r].color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2121,7 +2116,7 @@ namespace RoF
{
outapp->WriteUInt32(emu->aa_array[r].AA);
outapp->WriteUInt32(emu->aa_array[r].value);
outapp->WriteUInt32(emu->aa_array[r].charges);
outapp->WriteUInt32(0);
}
// Fill the other 60 AAs with zeroes
@@ -2291,52 +2286,46 @@ namespace RoF
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt32(consts::BANDOLIERS_SIZE);
outapp->WriteUInt32(structs::MAX_PLAYER_BANDOLIER);
// Copy bandoliers where server and client indexes converge
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
outapp->WriteString(emu->bandoliers[r].Name);
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
outapp->WriteString(emu->bandoliers[r].Items[j].Name);
outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID);
if (emu->bandoliers[r].Items[j].Icon) {
outapp->WriteSInt32(emu->bandoliers[r].Items[j].Icon);
}
else {
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
outapp->WriteSInt32(-1);
}
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_COUNT; r++)
{
outapp->WriteString(emu->bandoliers[r].name);
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
outapp->WriteString(emu->bandoliers[r].items[j].item_name);
outapp->WriteUInt32(emu->bandoliers[r].items[j].item_id);
outapp->WriteUInt32(emu->bandoliers[r].items[j].icon);
}
}
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (uint32 r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
for (uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - EmuConstants::BANDOLIERS_COUNT; r++)
{
outapp->WriteString("");
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
outapp->WriteString("");
outapp->WriteUInt32(0);
outapp->WriteSInt32(-1);
outapp->WriteUInt32(0);
}
}
outapp->WriteUInt32(consts::POTION_BELT_ITEM_COUNT);
outapp->WriteUInt32(structs::MAX_POTIONS_IN_BELT);
// Copy potion belt where server and client indexes converge
for (uint32 r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
outapp->WriteString(emu->potionbelt.Items[r].Name);
outapp->WriteUInt32(emu->potionbelt.Items[r].ID);
if (emu->potionbelt.Items[r].Icon) {
outapp->WriteSInt32(emu->potionbelt.Items[r].Icon);
}
else {
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
outapp->WriteSInt32(-1);
}
for (uint32 r = 0; r < EmuConstants::POTION_BELT_SIZE; r++)
{
outapp->WriteString(emu->potionbelt.items[r].item_name);
outapp->WriteUInt32(emu->potionbelt.items[r].item_id);
outapp->WriteUInt32(emu->potionbelt.items[r].icon);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (uint32 r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
for (uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - EmuConstants::POTION_BELT_SIZE; r++)
{
outapp->WriteString("");
outapp->WriteUInt32(0);
outapp->WriteSInt32(-1);
outapp->WriteUInt32(0);
}
outapp->WriteSInt32(-1); // Unknown;
@@ -2429,7 +2418,7 @@ namespace RoF
outapp->WriteUInt32(emu->silver_bank);
outapp->WriteUInt32(emu->copper_bank);
outapp->WriteUInt32(emu->platinum_shared);
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
@@ -2819,9 +2808,9 @@ namespace RoF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{
eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].charges = emu->aa_list[i].charges;
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
}
FINISH_ENCODE();
@@ -2853,7 +2842,7 @@ namespace RoF
// Check clientver field to verify this AA should be sent for SoF
// clientver 1 is for all clients and 5 is for Live
if (emu->clientver <= 7)
if (emu->clientver <= 5)
{
OUT(id);
eq->unknown004 = 1;
@@ -2869,9 +2858,9 @@ namespace RoF
OUT(cost);
OUT(seq);
OUT(current_level);
eq->prereq_skill_count = 1; // min 1
eq->unknown037 = 1; // Introduced during HoT
OUT(prereq_skill);
eq->prereq_minpoints_count = 1; // min 1
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1
OUT(prereq_minpoints);
eq->type = emu->sof_type;
OUT(spellid);
@@ -2887,7 +2876,6 @@ namespace RoF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -2903,100 +2891,85 @@ namespace RoF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
FINISH_ENCODE();
return;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
}
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
eq->CharCount = character_count;
//eq->TotalChars = emu->TotalChars;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
//if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
// eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
eq->char_count = char_count;
//eq->total_chars = 10;
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Class = emu_cse->Class;
eq_cse->Race = emu_cse->Race;
eq_cse->Level = emu_cse->Level;
eq_cse->ShroudClass = emu_cse->ShroudClass;
eq_cse->ShroudRace = emu_cse->ShroudRace;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Instance = emu_cse->Instance;
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
}
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
eq_cse->Deity = emu_cse->Deity;
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Beard = emu_cse->Beard;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->Unknown1 = emu_cse->Unknown1;
eq_cse->Enabled = emu_cse->Enabled;
eq_cse->LastLogin = emu_cse->LastLogin;
eq_cse->Unknown2 = emu_cse->Unknown2;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->class_ = emu->class_[r];
eq2->race = emu->race[r];
eq2->level = emu->level[r];
eq2->class_2 = emu->class_[r];
eq2->race2 = emu->race[r];
eq2->zone = emu->zone[r];
eq2->instance = 0;
eq2->gender = emu->gender[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].heroforgemodel = emu->equip[r][k].heroforgemodel;
eq2->equip[k].material2 = emu->equip[r][k].material2;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->u15 = 0xff;
eq2->u19 = 0xFF;
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
eq2->deity = emu->deity[r];
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->haircolor = emu->haircolor[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->beard = emu->beard[r];
eq2->char_enabled = 1;
eq2->tutorial = emu->tutorial[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->unknown1 = 0;
eq2->gohome = emu->gohome[r];
eq2->LastLogin = 1212696584;
eq2->unknown2 = 0;
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -3051,7 +3024,7 @@ namespace RoF
switch (emu->Rank) {
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
default: { eq->Rank = emu->Rank; break; }
}
@@ -3066,13 +3039,13 @@ namespace RoF
{
ENCODE_LENGTH_EXACT(Merchant_Sell_Struct);
SETUP_DIRECT_ENCODE(Merchant_Sell_Struct, structs::Merchant_Sell_Struct);
OUT(npcid);
OUT(playerid);
OUT(itemslot);
OUT(quantity);
OUT(price);
FINISH_ENCODE();
}
@@ -3318,7 +3291,7 @@ namespace RoF
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
#if 0 // original code
EQApplicationPacket *in = *p;
*p = nullptr;
@@ -3615,71 +3588,37 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_VetClaimReply)
{
ENCODE_LENGTH_EXACT(VeteranClaim);
SETUP_DIRECT_ENCODE(VeteranClaim, structs::VeteranClaim);
memcpy(eq->name, emu->name, sizeof(emu->name));
OUT(claim_id);
OUT(action);
FINISH_ENCODE();
}
ENCODE(OP_VetRewardsAvaliable)
{
EQApplicationPacket *inapp = *p;
auto __emu_buffer = inapp->pBuffer;
unsigned char * __emu_buffer = inapp->pBuffer;
uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward));
*p = nullptr;
// calculate size of names, note the packet DOES NOT have null termed c-strings
std::vector<uint32> name_lengths;
for (int i = 0; i < count; ++i) {
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count));
uchar *old_data = __emu_buffer;
uchar *data = outapp_create->pBuffer;
for (unsigned int i = 0; i < count; ++i)
{
structs::VeteranReward *vr = (structs::VeteranReward*)data;
InternalVeteranReward *ivr = (InternalVeteranReward*)old_data;
for (int i = 0; i < ivr->claim_count; i++) {
uint32 length = strnlen(ivr->items[i].item_name, 63);
if (length)
name_lengths.push_back(length);
vr->claim_count = ivr->claim_count;
vr->claim_id = ivr->claim_id;
vr->number_available = ivr->number_available;
for (int x = 0; x < 8; ++x)
{
vr->items[x].item_id = ivr->items[x].item_id;
strncpy(vr->items[x].item_name, ivr->items[x].item_name, sizeof(vr->items[x].item_name));
vr->items[x].charges = ivr->items[x].charges;
}
__emu_buffer += sizeof(InternalVeteranReward);
old_data += sizeof(InternalVeteranReward);
data += sizeof(structs::VeteranReward);
}
uint32 packet_size = std::accumulate(name_lengths.begin(), name_lengths.end(), 0) +
sizeof(structs::VeteranReward) + (sizeof(structs::VeteranRewardEntry) * count) +
// size of name_lengths is the same as item count
(sizeof(structs::VeteranRewardItem) * name_lengths.size());
// build packet now!
auto outapp = new EQApplicationPacket(OP_VetRewardsAvaliable, packet_size);
__emu_buffer = inapp->pBuffer;
outapp->WriteUInt32(count);
auto name_itr = name_lengths.begin();
for (int i = 0; i < count; i++) {
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
outapp->WriteUInt32(ivr->claim_id);
outapp->WriteUInt32(ivr->number_available);
outapp->WriteUInt32(ivr->claim_count);
outapp->WriteUInt8(1); // enabled
for (int j = 0; j < ivr->claim_count; j++) {
assert(name_itr != name_lengths.end()); // the way it's written, it should never happen, so just assert
outapp->WriteUInt32(*name_itr);
outapp->WriteData(ivr->items[j].item_name, *name_itr);
outapp->WriteUInt32(ivr->items[j].item_id);
outapp->WriteUInt32(ivr->items[j].charges);
++name_itr;
}
__emu_buffer += sizeof(InternalVeteranReward);
}
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
delete inapp;
}
@@ -3694,7 +3633,7 @@ namespace RoF
OUT(elite_material);
OUT(hero_forge_model);
OUT(unknown18);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -3782,26 +3721,45 @@ namespace RoF
}
ENCODE(OP_ZoneEntry) { ENCODE_FORWARD(OP_ZoneSpawns); }
ENCODE(OP_ZonePlayerToBind)
{
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
FINISH_ENCODE();
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = 0;
zph->bind_instance_id = zps->bind_instance_id;
strncpy(zph->zone_name, zps->zone_name, sizeof(zph->zone_name));
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
}
ENCODE(OP_ZoneServerInfo)
@@ -3849,8 +3807,8 @@ namespace RoF
PacketSize += strlen(emu->name);
PacketSize += strlen(emu->lastName);
emu->title[31] = 0;
emu->suffix[31] = 0;
emu->title[0] = 0;
emu->suffix[0] = 0;
if (strlen(emu->title))
PacketSize += strlen(emu->title) + 1;
@@ -3973,8 +3931,8 @@ namespace RoF
switch (emu->guildrank) {
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
}
}
@@ -3993,7 +3951,7 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -4005,18 +3963,18 @@ namespace RoF
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
}
}
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment[k].Material2;
Equipment[k].material = emu->equipment[k].material;
Equipment[k].unknown1 = emu->equipment[k].unknown1;
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
Equipment[k].heroforgemodel = emu->equipment[k].heroforgemodel;
Equipment[k].material2 = emu->equipment[k].material2;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -4029,13 +3987,13 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
@@ -4123,18 +4081,6 @@ namespace RoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_Animation)
{
DECODE_LENGTH_EXACT(structs::Animation_Struct);
SETUP_DIRECT_DECODE(Animation_Struct, structs::Animation_Struct);
IN(spawnid);
IN(action);
IN(speed);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ApplyPoison)
{
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
@@ -4247,16 +4193,12 @@ namespace RoF
emu->slot = 10;
else
IN(slot);
IN(spell_id);
emu->inventoryslot = RoFToServerSlot(eq->inventoryslot);
//IN(inventoryslot);
IN(target_id);
IN(y_pos);
IN(x_pos);
IN(z_pos);
FINISH_DIRECT_DECODE();
}
@@ -4394,7 +4336,7 @@ namespace RoF
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
emu->sequence = eq->sequence;
FINISH_DIRECT_DECODE();
}
@@ -4704,16 +4646,16 @@ namespace RoF
DECODE(OP_MoveItem)
{
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot);
//Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack);
//emu->from_slot = RoFToServerSlot(eq->from_slot);
//emu->to_slot = RoFToServerSlot(eq->to_slot);
//IN(number_in_stack);
//
//FINISH_DIRECT_DECODE();
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot);
Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack);
emu->from_slot = RoFToServerSlot(eq->from_slot);
emu->to_slot = RoFToServerSlot(eq->to_slot);
IN(number_in_stack);
FINISH_DIRECT_DECODE();
}
DECODE(OP_PetCommands)
@@ -4722,7 +4664,7 @@ namespace RoF
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
IN(command);
IN(target);
emu->unknown = eq->unknown04;
FINISH_DIRECT_DECODE();
}
@@ -4841,13 +4783,13 @@ namespace RoF
{
DECODE_LENGTH_EXACT(structs::Merchant_Sell_Struct);
SETUP_DIRECT_DECODE(Merchant_Sell_Struct, structs::Merchant_Sell_Struct);
IN(npcid);
IN(playerid);
IN(itemslot);
IN(quantity);
IN(price);
FINISH_DIRECT_DECODE();
}
@@ -4946,7 +4888,7 @@ namespace RoF
slot_id = legacy::SLOT_TRADESKILL; // 1000
}
emu->container_slot = slot_id;
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented -U
FINISH_DIRECT_DECODE();
}
@@ -4981,16 +4923,6 @@ namespace RoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_VetClaimRequest)
{
DECODE_LENGTH_EXACT(structs::VeteranClaim);
SETUP_DIRECT_DECODE(VeteranClaim, structs::VeteranClaim);
IN(claim_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ZoneChange)
{
DECODE_LENGTH_EXACT(structs::ZoneChange_Struct);
@@ -5044,14 +4976,14 @@ namespace RoF
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
const ItemData *item = inst->GetUnscaledItem();
const Item_Struct *item = inst->GetUnscaledItem();
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
RoF::structs::ItemSerializationHeader hdr;
//sprintf(hdr.unknown000, "06e0002Y1W00");
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%012d", item->ID);
hdr.stacksize = stackable ? charges : 1;
hdr.unknown004 = 0;
@@ -5103,7 +5035,7 @@ namespace RoF
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = inst->GetOrnamentationIcon();
heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in));
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
}
else
{
@@ -5122,7 +5054,7 @@ namespace RoF
hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0)
{
ss.write(item->Name, strlen(item->Name));
@@ -5546,7 +5478,7 @@ namespace RoF
/*
// TEST CODE: <watch>
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
*/
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
+460 -592
View File
File diff suppressed because it is too large Load Diff
+3 -6
View File
@@ -103,8 +103,6 @@ namespace RoF2 {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -180,10 +178,9 @@ namespace RoF2 {
static const uint16 ITEM_COMMON_SIZE = 6;
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
}
-7
View File
@@ -2,14 +2,10 @@
// Begin RoF2 Encodes
E(OP_SendMembershipDetails)
E(OP_TraderShop)
E(OP_TraderDelItem)
// incoming packets that require a DECODE translation:
// Begin RoF2 Decodes
D(OP_TraderShop)
// End RoF2 Encodes/Decodes
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
@@ -111,7 +107,6 @@ E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeInfo)
E(OP_TributeItem)
E(OP_VetClaimReply)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
@@ -124,7 +119,6 @@ E(OP_ZoneSpawns)
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_Animation)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
@@ -176,7 +170,6 @@ D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_VetClaimRequest)
D(OP_WhoAllRequest)
D(OP_ZoneChange)
D(OP_ZoneEntry)
+180 -249
View File
@@ -97,6 +97,11 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_TRIBUTE_TIERS = 10;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
@@ -109,7 +114,7 @@ static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_AA_ARRAY = 300;
static const uint32 MAX_PP_DISCIPLINES = 300; // was 200
static const uint32 MAX_PP_DISCIPLINES = 200; // was 100
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -142,86 +147,83 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
};
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
/*0000*/ uint8 Class;
/*0000*/ uint32 Race;
/*0000*/ uint8 Level;
/*0000*/ uint8 ShroudClass;
/*0000*/ uint32 ShroudRace;
/*0000*/ uint16 Zone;
/*0000*/ uint16 Instance;
/*0000*/ uint8 Gender;
/*0000*/ uint8 Face;
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint8 Unknown15; // Seen FF
/*0000*/ uint8 Unknown19; // Seen FF
/*0000*/ uint32 DrakkinTattoo;
/*0000*/ uint32 DrakkinDetails;
/*0000*/ uint32 Deity;
/*0000*/ uint32 PrimaryIDFile;
/*0000*/ uint32 SecondaryIDFile;
/*0000*/ uint8 HairColor;
/*0000*/ uint8 BeardColor;
/*0000*/ uint8 EyeColor1;
/*0000*/ uint8 EyeColor2;
/*0000*/ uint8 HairStyle;
/*0000*/ uint8 Beard;
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 DrakkinHeritage;
/*0000*/ uint8 Unknown1; // Seen 0
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
/*0000*/ uint32 LastLogin;
/*0000*/ uint8 Unknown2; // Seen 0
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct
{
/*000*/ uint32 CharCount; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/ uint32 HeroForgeModel;
/*16*/ uint32 Material2; // Same as material?
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/ uint32 heroforgemodel;
/*16*/ uint32 material2; // Same as material?
/*20*/
};
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
uint32 heroforgemodel;
uint32 material2;
Color_Struct color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ char name[1]; // Name null terminated
/*0000*/ uint8 class_;
/*0000*/ uint32 race;
/*0000*/ uint8 level;
/*0000*/ uint8 class_2;
/*0000*/ uint32 race2;
/*0000*/ uint16 zone;
/*0000*/ uint16 instance;
/*0000*/ uint8 gender;
/*0000*/ uint8 face;
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint8 u15; // Seen FF
/*0000*/ uint8 u19; // Seen FF
/*0000*/ uint32 drakkin_tattoo;
/*0000*/ uint32 drakkin_details;
/*0000*/ uint32 deity;
/*0000*/ uint32 primary;
/*0000*/ uint32 secondary;
/*0000*/ uint8 haircolor;
/*0000*/ uint8 beardcolor;
/*0000*/ uint8 eyecolor1;
/*0000*/ uint8 eyecolor2;
/*0000*/ uint8 hairstyle;
/*0000*/ uint8 beard;
/*0000*/ uint8 char_enabled;
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 drakkin_heritage;
/*0000*/ uint8 unknown1; // Seen 0
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
/*0000*/ uint32 LastLogin;
/*0000*/ uint8 unknown2; // Seen 0
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*000*/ uint32 char_count; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct entries[0];
};
struct Membership_Entry_Struct
{
@@ -416,7 +418,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -658,10 +660,7 @@ struct CastSpell_Struct
/*04*/ uint32 spell_id;
/*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast
/*20*/ uint32 target_id;
/*24*/ uint32 cs_unknown[2];
/*32*/ float y_pos;
/*36*/ float x_pos;
/*40*/ float z_pos;
/*24*/ uint32 cs_unknown[5];
/*44*/
};
@@ -687,7 +686,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ int32 duration;
/*014*/ uint32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@@ -703,7 +702,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -720,7 +719,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*016*/ uint32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@@ -736,7 +735,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -877,7 +876,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges; // expendable charges
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
};
struct Disciplines_Struct {
@@ -897,66 +896,38 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct BandolierItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
struct BandolierItem_Struct {
char item_name[1]; // Variable Length
uint32 item_id;
uint32 icon;
};
//len = 72
struct BandolierItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct_Old {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[1]; // Variable Length
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[1]; // Variable Length
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
struct Bandolier_Struct_Old
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
struct Bandolier_Struct_Old {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
struct PotionBeltItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
//len = 72
struct PotionBeltItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
struct PotionBelt_Struct_Old
{
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
};
struct GroupLeadershipAA_Struct {
@@ -1166,7 +1137,7 @@ union
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
/*12953*/ uint16 unknown_rof20; //
/*12955*/ uint32 bandolier_count; // Seen 20
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*13699*/ uint32 potionbelt_count; // Seen 5
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
/*13748*/ int32 unknown_rof21; // Seen -1
@@ -1293,7 +1264,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*00*/ uint32 command;
/*04*/ uint32 target;
/*04*/ uint32 unknown04;
/*08*/ uint32 unknown08;
};
@@ -1418,8 +1389,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 speed;
/*02*/ uint8 value;
/*03*/ uint8 action;
/*04*/
};
@@ -1484,10 +1455,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25[5]; // was [9]
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 30 */
};
@@ -2310,7 +2280,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2473,7 +2443,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {
@@ -2944,12 +2914,10 @@ struct BazaarWindowStart_Struct {
struct BazaarWelcome_Struct {
uint32 Code;
uint32 EntityID;
uint32 Traders;
uint32 Items;
uint32 Traders2;
uint32 Items2;
BazaarWindowStart_Struct Beginning;
uint32 Traders;
uint32 Items;
uint8 Unknown012[8];
};
struct BazaarSearch_Struct {
@@ -3232,13 +3200,6 @@ struct BecomeTrader_Struct {
};
struct Trader_ShowItems_Struct {
/*000*/ uint32 Code;
/*004*/ uint16 TraderID;
/*008*/ uint32 Unknown08;
/*012*/
};
struct Trader_ShowItems_Struct_WIP {
/*000*/ uint32 Code;
/*004*/ char SerialNumber[17];
/*021*/ uint8 Unknown21;
@@ -3256,26 +3217,6 @@ struct TraderStatus_Struct {
};
struct TraderBuy_Struct {
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Unknown012;
/*016*/ uint32 TraderID;
/*020*/ char BuyerName[64];
/*084*/ char SellerName[64];
/*148*/ char Unknown148[32];
/*180*/ char ItemName[64];
/*244*/ char SerialNumber[16];
/*260*/ uint32 Unknown076;
/*264*/ uint32 ItemID;
/*268*/ uint32 Price;
/*272*/ uint32 AlreadySold;
/*276*/ uint32 Unknown276;
/*280*/ uint32 Quantity;
/*284*/
};
struct TraderBuy_Struct_OLD {
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Price;
@@ -3305,19 +3246,25 @@ struct MoneyUpdate_Struct{
int32 copper;
};
//struct MoneyUpdate_Struct
//{
//*0000*/ uint32 spawn_id; // ***Placeholder
//*0004*/ uint32 cointype; // Coin Type
//*0008*/ uint32 amount; // Amount
//*0012*/
//};
struct TraderDelItem_Struct{
/*000*/ uint32 Unknown000;
/*004*/ uint32 TraderID;
/*008*/ char SerialNumber[16];
/*024*/ uint32 Unknown012;
/*028*/
uint32 slotid;
uint32 quantity;
uint32 unknown;
};
struct TraderClick_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Approval;
/*012*/
uint32 traderid;
uint32 unknown4[2];
uint32 approval;
};
struct FormattedMessage_Struct{
@@ -3620,7 +3567,7 @@ struct Split_Struct
*/
struct NewCombine_Struct {
/*00*/ ItemSlotStruct container_slot;
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
/*24*/
};
@@ -4141,35 +4088,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -4190,11 +4132,9 @@ struct Arrow_Struct {
/*068*/ uint8 unknown068;
/*069*/ uint8 unknown069;
/*070*/ uint8 unknown070;
/*071*/ uint8 unknown071;
/*072*/ uint8 unknown072;
/*073*/ uint8 skill;
/*074*/ uint8 item_type;
/*075*/ uint8 unknown075[14];
/*071*/ uint8 item_type;
/*072*/ uint8 skill;
/*073*/ uint8 unknown073[16];
/*089*/ char model_name[27];
/*116*/
};
@@ -4253,9 +4193,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost;
/*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0037*/ uint32 unknown037; // Introduced during HoT
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type;
/*0057*/ uint32 spellid;
@@ -4268,16 +4208,10 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id;
/*0085*/ uint32 next_id;
/*0089*/ uint32 cost2;
/*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0093*/ uint8 unknown80[7];
/*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category;
/*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0108*/ uint32 unknown0096;
/*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0];
};
@@ -4294,6 +4228,12 @@ struct AA_Action {
/*16*/
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@@ -4313,7 +4253,14 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AATable_Struct {
@@ -4323,7 +4270,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4406,7 +4353,7 @@ struct RoF2SlotStruct
struct ItemSerializationHeader
{
/*000*/ char tracking_id[17]; // New for HoT. Looks like a string.
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
/*017*/ uint32 stacksize;
/*021*/ uint32 unknown004;
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
@@ -4551,7 +4498,7 @@ struct ItemSecondaryBodyStruct
uint32 augtype;
// swapped augrestrict and augdistiller positions
// (this swap does show the proper augment restrictions in Item Information window now)
// unsure what the purpose of augdistiller is at this time 3/17/2014
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
int32 augrestrict2; // New to December 10th 2012 client - Hidden Aug Restriction
uint32 augrestrict;
AugSlotStruct augslots[6];
@@ -4726,33 +4673,17 @@ struct AugmentInfo_Struct
struct VeteranRewardItem
{
/*000*/ uint32 name_length;
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
/*???*/ uint32 item_id;
/*???*/ uint32 charges;
};
struct VeteranRewardEntry
{
/*000*/ uint32 claim_id; // guessed
/*004*/ uint32 avaliable_count;
/*008*/ uint32 claim_count;
/*012*/ char enabled;
/*013*/ //VeteranRewardItem items[0];
/*000*/ uint32 item_id;
/*004*/ uint32 charges;
/*008*/ char item_name[64];
};
struct VeteranReward
{
/*000*/ uint32 claim_count;
/*004*/ //VeteranRewardEntry entries[0];
};
struct VeteranClaim
{
/*000*/ char name[68]; //name + other data
/*068*/ uint32 claim_id;
/*072*/ uint32 unknown072;
/*076*/ uint32 action;
/*000*/ uint32 claim_id;
/*004*/ uint32 number_available;
/*008*/ uint32 claim_count;
/*012*/ VeteranRewardItem items[8];
};
struct ExpeditionEntryHeader_Struct
+3 -6
View File
@@ -102,8 +102,6 @@ namespace RoF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -179,10 +177,9 @@ namespace RoF {
static const uint16 ITEM_COMMON_SIZE = 6;
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 55;
}
-3
View File
@@ -96,7 +96,6 @@ E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeInfo)
E(OP_TributeItem)
E(OP_VetClaimReply)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
@@ -109,7 +108,6 @@ E(OP_ZoneSpawns)
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_Animation)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
@@ -161,7 +159,6 @@ D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_VetClaimRequest)
D(OP_WhoAllRequest)
D(OP_ZoneChange)
D(OP_ZoneEntry)
+156 -198
View File
@@ -97,6 +97,11 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_TRIBUTE_TIERS = 10;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
@@ -142,87 +147,71 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
uint32 heroforgemodel;
uint32 material2;
Color_Struct color;
};
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
/*0000*/ uint8 Class;
/*0000*/ uint32 Race;
/*0000*/ uint8 Level;
/*0000*/ uint8 ShroudClass;
/*0000*/ uint32 ShroudRace;
/*0000*/ uint16 Zone;
/*0000*/ uint16 Instance;
/*0000*/ uint8 Gender;
/*0000*/ uint8 Face;
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint8 Unknown15; // Seen FF
/*0000*/ uint8 Unknown19; // Seen FF
/*0000*/ uint32 DrakkinTattoo;
/*0000*/ uint32 DrakkinDetails;
/*0000*/ uint32 Deity;
/*0000*/ uint32 PrimaryIDFile;
/*0000*/ uint32 SecondaryIDFile;
/*0000*/ uint8 HairColor;
/*0000*/ uint8 BeardColor;
/*0000*/ uint8 EyeColor1;
/*0000*/ uint8 EyeColor2;
/*0000*/ uint8 HairStyle;
/*0000*/ uint8 Beard;
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 DrakkinHeritage;
/*0000*/ uint8 Unknown1; // Seen 0
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
struct CharacterSelectEntry_Struct {
/*0000*/ char name[1]; // Name null terminated
/*0000*/ uint8 class_;
/*0000*/ uint32 race;
/*0000*/ uint8 level;
/*0000*/ uint8 class_2;
/*0000*/ uint32 race2;
/*0000*/ uint16 zone;
/*0000*/ uint16 instance;
/*0000*/ uint8 gender;
/*0000*/ uint8 face;
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint8 u15; // Seen FF
/*0000*/ uint8 u19; // Seen FF
/*0000*/ uint32 drakkin_tattoo;
/*0000*/ uint32 drakkin_details;
/*0000*/ uint32 deity;
/*0000*/ uint32 primary;
/*0000*/ uint32 secondary;
/*0000*/ uint8 haircolor;
/*0000*/ uint8 beardcolor;
/*0000*/ uint8 eyecolor1;
/*0000*/ uint8 eyecolor2;
/*0000*/ uint8 hairstyle;
/*0000*/ uint8 beard;
/*0000*/ uint8 char_enabled;
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 drakkin_heritage;
/*0000*/ uint8 unknown1; // Seen 0
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
/*0000*/ uint32 LastLogin;
/*0000*/ uint8 Unknown2; // Seen 0
/*0000*/ uint8 unknown2; // Seen 0
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct
{
/*000*/ uint32 CharCount; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct Entries[0];
struct CharacterSelect_Struct {
/*000*/ uint32 char_count; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct entries[0];
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/ uint32 HeroForgeModel;
/*16*/ uint32 Material2; // Same as material?
/*20*/
};
struct Membership_Entry_Struct
{
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
@@ -263,6 +252,20 @@ struct Membership_Struct
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/ uint32 heroforgemodel;
/*16*/ uint32 material2; // Same as material?
/*20*/
};
/*
** Generic Spawn Struct
** Length: 897 Octets
@@ -410,7 +413,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -647,10 +650,7 @@ struct CastSpell_Struct
/*04*/ uint32 spell_id;
/*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast
/*20*/ uint32 target_id;
/*24*/ uint32 cs_unknown[2];
/*32*/ float y_pos;
/*36*/ float x_pos;
/*40*/ float z_pos;
/*24*/ uint32 cs_unknown[5];
/*44*/
};
@@ -676,7 +676,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ int32 duration;
/*014*/ uint32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@@ -692,7 +692,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -709,7 +709,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*016*/ uint32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@@ -725,7 +725,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -866,7 +866,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges; // expendable charges
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
};
struct Disciplines_Struct {
@@ -880,66 +880,38 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct BandolierItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
struct BandolierItem_Struct {
char item_name[1]; // Variable Length
uint32 item_id;
uint32 icon;
};
//len = 72
struct BandolierItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct_Old {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[1]; // Variable Length
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[1]; // Variable Length
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
struct Bandolier_Struct_Old
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
struct Bandolier_Struct_Old {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
struct PotionBeltItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
//len = 72
struct PotionBeltItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
struct PotionBelt_Struct_Old
{
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
};
struct GroupLeadershipAA_Struct {
@@ -1149,7 +1121,7 @@ union
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
/*12953*/ uint16 unknown_rof20; //
/*12955*/ uint32 bandolier_count; // Seen 20
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*13699*/ uint32 potionbelt_count; // Seen 5
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
/*13748*/ int32 unknown_rof21; // Seen -1
@@ -1323,7 +1295,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*00*/ uint32 command;
/*04*/ uint32 target;
/*04*/ uint32 unknown04;
/*08*/ uint32 unknown08;
};
@@ -1448,8 +1420,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 speed;
/*02*/ uint8 value;
/*03*/ uint8 action;
/*04*/
};
@@ -1514,10 +1486,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25[5]; // was [9]
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 30 */
};
@@ -2338,7 +2309,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2501,7 +2472,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {
@@ -3621,7 +3592,7 @@ struct Split_Struct
*/
struct NewCombine_Struct {
/*00*/ ItemSlotStruct container_slot;
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
/*24*/
};
@@ -4142,35 +4113,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -4252,9 +4218,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost;
/*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0037*/ uint32 unknown037; // Introduced during HoT
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type;
/*0057*/ uint32 spellid;
@@ -4267,16 +4233,10 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id;
/*0085*/ uint32 next_id;
/*0089*/ uint32 cost2;
/*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0093*/ uint8 unknown80[7];
/*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category;
/*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0108*/ uint32 unknown0096;
/*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0];
};
@@ -4293,6 +4253,13 @@ struct AA_Action {
/*16*/
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -4311,7 +4278,14 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AATable_Struct {
@@ -4321,7 +4295,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4404,7 +4378,7 @@ struct RoFSlotStruct
struct ItemSerializationHeader
{
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
/*000*/ char unknown000[13]; // New for HoT. Looks like a string.
/*017*/ uint32 stacksize;
/*021*/ uint32 unknown004;
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
@@ -4550,7 +4524,7 @@ struct ItemSecondaryBodyStruct
uint32 augtype;
// swapped augrestrict and augdistiller positions
// (this swap does show the proper augment restrictions in Item Information window now)
// unsure what the purpose of augdistiller is at this time 3/17/2014
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
uint32 augdistiller; // New to December 10th 2012 client - NEW
uint32 augrestrict;
AugSlotStruct augslots[6];
@@ -4714,33 +4688,17 @@ struct AugmentInfo_Struct
struct VeteranRewardItem
{
/*000*/ uint32 name_length;
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
/*???*/ uint32 item_id;
/*???*/ uint32 charges;
};
struct VeteranRewardEntry
{
/*000*/ uint32 claim_id; // guessed
/*004*/ uint32 avaliable_count;
/*008*/ uint32 claim_count;
/*012*/ char enabled;
/*013*/ //VeteranRewardItem items[0];
/*000*/ uint32 item_id;
/*004*/ uint32 charges;
/*008*/ char item_name[64];
};
struct VeteranReward
{
/*000*/ uint32 claim_count;
/*004*/ //VeteranRewardEntry entries[0];
};
struct VeteranClaim
{
/*000*/ char name[68]; //name + other data
/*068*/ uint32 claim_id;
/*072*/ uint32 unknown072;
/*076*/ uint32 action;
/*000*/ uint32 claim_id;
/*004*/ uint32 number_available;
/*008*/ uint32 claim_count;
/*012*/ VeteranRewardItem items[8];
};
struct ExpeditionEntryHeader_Struct
+205 -231
View File
@@ -336,72 +336,71 @@ namespace SoD
{
//consume the packet
EQApplicationPacket *in = *p;
delete in;
//*p = nullptr;
//
//if (in->size == 0) {
//
// in->size = 4;
//
// in->pBuffer = new uchar[in->size];
//
// *((uint32 *)in->pBuffer) = 0;
//
// dest->FastQueuePacket(&in, ack_req);
//
// return;
//}
//
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
//
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
//
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
// opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
//
// delete in;
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
//
// if (Serialized) {
//
// uchar *OldBuffer = in->pBuffer;
// in->pBuffer = new uchar[in->size + Length];
// memcpy(in->pBuffer, OldBuffer, in->size);
//
// safe_delete_array(OldBuffer);
//
// memcpy(in->pBuffer + in->size, Serialized, Length);
// in->size += Length;
//
// safe_delete_array(Serialized);
//
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
*p = nullptr;
if (in->size == 0) {
in->size = 4;
in->pBuffer = new uchar[in->size];
*((uint32 *)in->pBuffer) = 0;
dest->FastQueuePacket(&in, ack_req);
return;
}
//store away the emu struct
unsigned char *__emu_buffer = in->pBuffer;
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
in->pBuffer = new uchar[4];
*(uint32 *)in->pBuffer = ItemCount;
in->size = 4;
for (int r = 0; r < ItemCount; r++, eq++) {
uint32 Length = 0;
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
if (Serialized) {
uchar *OldBuffer = in->pBuffer;
in->pBuffer = new uchar[in->size + Length];
memcpy(in->pBuffer, OldBuffer, in->size);
safe_delete_array(OldBuffer);
memcpy(in->pBuffer + in->size, Serialized, Length);
in->size += Length;
safe_delete_array(Serialized);
}
else {
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
}
}
delete[] __emu_buffer;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClientUpdate)
@@ -447,9 +446,7 @@ namespace SoD
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
eq->sequence = emu->sequence;
FINISH_ENCODE();
}
@@ -1267,14 +1264,14 @@ namespace SoD
ENCODE(OP_MoveItem)
{
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//eq->from_slot = ServerToSoDSlot(emu->from_slot);
//eq->to_slot = ServerToSoDSlot(emu->to_slot);
//OUT(number_in_stack);
//
//FINISH_ENCODE();
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
eq->from_slot = ServerToSoDSlot(emu->from_slot);
eq->to_slot = ServerToSoDSlot(emu->to_slot);
OUT(number_in_stack);
FINISH_ENCODE();
}
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
@@ -1545,13 +1542,13 @@ namespace SoD
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
eq->equipment[r].material = emu->item_material[r];
eq->equipment[r].unknown1 = 0;
eq->equipment[r].elitematerial = 0;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint[r].color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1559,7 +1556,6 @@ namespace SoD
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1610,46 +1606,26 @@ namespace SoD
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
}
}
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1900,7 +1876,6 @@ namespace SoD
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -1916,96 +1891,76 @@ namespace SoD
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
FINISH_ENCODE();
return;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
}
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
eq->char_count = char_count;
eq->total_chars = 10;
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -2400,7 +2355,7 @@ namespace SoD
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2472,23 +2427,42 @@ namespace SoD
ENCODE(OP_ZonePlayerToBind)
{
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
FINISH_ENCODE();
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
}
ENCODE(OP_ZoneServerInfo)
@@ -2741,7 +2715,7 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -2768,7 +2742,7 @@ namespace SoD
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
}
}
}
@@ -2778,11 +2752,11 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
@@ -2793,9 +2767,9 @@ namespace SoD
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].material = emu->equipment[k].material;
Equipment[k].unknown1 = emu->equipment[k].unknown1;
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -3265,16 +3239,16 @@ namespace SoD
DECODE(OP_MoveItem)
{
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot);
//
//emu->from_slot = SoDToServerSlot(eq->from_slot);
//emu->to_slot = SoDToServerSlot(eq->to_slot);
//IN(number_in_stack);
//
//FINISH_DIRECT_DECODE();
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot);
emu->from_slot = SoDToServerSlot(eq->from_slot);
emu->to_slot = SoDToServerSlot(eq->to_slot);
IN(number_in_stack);
FINISH_DIRECT_DECODE();
}
DECODE(OP_PetCommands)
@@ -3355,7 +3329,7 @@ namespace SoD
default:
emu->command = eq->command;
}
IN(target);
OUT(unknown);
FINISH_DIRECT_DECODE();
}
@@ -3510,7 +3484,7 @@ namespace SoD
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.Color);
IN(color.color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
@@ -3560,7 +3534,7 @@ namespace SoD
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
const ItemData *item = inst->GetUnscaledItem();
const Item_Struct *item = inst->GetUnscaledItem();
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
SoD::structs::ItemSerializationHeader hdr;
hdr.stacksize = stackable ? charges : 1;
@@ -3958,7 +3932,7 @@ namespace SoD
/*
// TEST CODE: <watch>
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
*/
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
+3 -6
View File
@@ -101,8 +101,6 @@ namespace SoD {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -176,10 +174,9 @@ namespace SoD {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+111 -131
View File
@@ -103,53 +103,54 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
struct CharSelectEquip {
//totally guessed;
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 Unknown; // New field to SoD
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 unknown; // New field to SoD
};
@@ -157,22 +158,20 @@ struct CharacterSelectEntry_Struct
** Character Selection Struct
**
*/
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/
};
@@ -286,7 +285,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -547,7 +546,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
@@ -564,7 +563,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -666,7 +665,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges; // expendable
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
};
@@ -677,6 +676,9 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -684,42 +686,26 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -939,7 +925,7 @@ struct PlayerProfile_Struct
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
/*08292*/ uint32 aapoints; // Unspent AA points
/*08296*/ uint8 unknown06160[4];
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
@@ -1091,7 +1077,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1205,8 +1191,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*04*/
};
@@ -1272,10 +1258,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -1973,7 +1958,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2372,7 +2357,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2392,8 +2377,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
@@ -3701,35 +3686,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -3819,16 +3799,10 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0081*/ uint8 unknown80[7];
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0096*/ uint32 unknown0096;
/*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0];
};
@@ -3844,6 +3818,12 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3861,12 +3841,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+201 -228
View File
@@ -318,70 +318,69 @@ namespace SoF
{
//consume the packet
EQApplicationPacket *in = *p;
delete in;
//*p = nullptr;
//
//if (in->size == 0) {
// in->size = 4;
// in->pBuffer = new uchar[in->size];
// *((uint32 *)in->pBuffer) = 0;
//
// dest->FastQueuePacket(&in, ack_req);
// return;
//}
//
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
//
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
//
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
// opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
//
// delete in;
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
//
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
//
// if (Serialized) {
// uchar *OldBuffer = in->pBuffer;
//
// in->pBuffer = new uchar[in->size + Length];
// memcpy(in->pBuffer, OldBuffer, in->size);
//
// safe_delete_array(OldBuffer);
//
// memcpy(in->pBuffer + in->size, Serialized, Length);
// in->size += Length;
//
// safe_delete_array(Serialized);
//
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
*p = nullptr;
if (in->size == 0) {
in->size = 4;
in->pBuffer = new uchar[in->size];
*((uint32 *)in->pBuffer) = 0;
dest->FastQueuePacket(&in, ack_req);
return;
}
//store away the emu struct
unsigned char *__emu_buffer = in->pBuffer;
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
in->pBuffer = new uchar[4];
*(uint32 *)in->pBuffer = ItemCount;
in->size = 4;
for (int r = 0; r < ItemCount; r++, eq++) {
uint32 Length = 0;
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
if (Serialized) {
uchar *OldBuffer = in->pBuffer;
in->pBuffer = new uchar[in->size + Length];
memcpy(in->pBuffer, OldBuffer, in->size);
safe_delete_array(OldBuffer);
memcpy(in->pBuffer + in->size, Serialized, Length);
in->size += Length;
safe_delete_array(Serialized);
}
else {
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
}
}
delete[] __emu_buffer;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClientUpdate)
@@ -427,9 +426,7 @@ namespace SoF
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
eq->sequence = emu->sequence;
FINISH_ENCODE();
}
@@ -932,14 +929,14 @@ namespace SoF
ENCODE(OP_MoveItem)
{
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//eq->from_slot = ServerToSoFSlot(emu->from_slot);
//eq->to_slot = ServerToSoFSlot(emu->to_slot);
//OUT(number_in_stack);
//
//FINISH_ENCODE();
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
eq->from_slot = ServerToSoFSlot(emu->from_slot);
eq->to_slot = ServerToSoFSlot(emu->to_slot);
OUT(number_in_stack);
FINISH_ENCODE();
}
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
@@ -1203,13 +1200,13 @@ namespace SoF
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
eq->equipment[r].material = emu->item_material[r];
eq->equipment[r].unknown1 = 0;
eq->equipment[r].elitematerial = 0;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint[r].color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1217,7 +1214,6 @@ namespace SoF
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1268,46 +1264,26 @@ namespace SoF
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
}
}
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1559,7 +1535,6 @@ namespace SoF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -1575,96 +1550,76 @@ namespace SoF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
FINISH_ENCODE();
return;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
}
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
eq->char_count = char_count;
eq->total_chars = 10;
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -1986,7 +1941,7 @@ namespace SoF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1996,23 +1951,42 @@ namespace SoF
ENCODE(OP_ZonePlayerToBind)
{
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
FINISH_ENCODE();
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
}
ENCODE(OP_ZoneServerInfo)
@@ -2070,10 +2044,10 @@ namespace SoF
eq->drakkin_heritage = emu->drakkin_heritage;
eq->gender = emu->gender;
for (k = 0; k < 9; k++) {
eq->equipment[k].Material = emu->equipment[k].Material;
eq->equipment[k].Unknown1 = emu->equipment[k].Unknown1;
eq->equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
eq->colors[k].Color = emu->colors[k].Color;
eq->equipment[k].material = emu->equipment[k].material;
eq->equipment[k].unknown1 = emu->equipment[k].unknown1;
eq->equipment[k].elitematerial = emu->equipment[k].elitematerial;
eq->colors[k].color = emu->colors[k].color;
}
eq->StandState = emu->StandState;
eq->guildID = emu->guildID;
@@ -2092,7 +2066,6 @@ namespace SoF
eq->runspeed = emu->runspeed;
eq->light = emu->light;
eq->level = emu->level;
eq->PlayerState = emu->PlayerState;
eq->lfg = emu->lfg;
eq->hairstyle = emu->hairstyle;
eq->haircolor = emu->haircolor;
@@ -2136,7 +2109,7 @@ namespace SoF
eq->petOwnerId = emu->petOwnerId;
eq->pvp = 0; // 0 = non-pvp colored name, 1 = red pvp name
for (k = 0; k < 9; k++) {
eq->colors[k].Color = emu->colors[k].Color;
eq->colors[k].color = emu->colors[k].color;
}
eq->anon = emu->anon;
eq->face = emu->face;
@@ -2604,16 +2577,16 @@ namespace SoF
DECODE(OP_MoveItem)
{
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
//
//emu->from_slot = SoFToServerSlot(eq->from_slot);
//emu->to_slot = SoFToServerSlot(eq->to_slot);
//IN(number_in_stack);
//
//FINISH_DIRECT_DECODE();
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
emu->from_slot = SoFToServerSlot(eq->from_slot);
emu->to_slot = SoFToServerSlot(eq->to_slot);
IN(number_in_stack);
FINISH_DIRECT_DECODE();
}
DECODE(OP_PetCommands)
@@ -2694,7 +2667,7 @@ namespace SoF
default:
emu->command = eq->command;
}
IN(target);
OUT(unknown);
FINISH_DIRECT_DECODE();
}
@@ -2835,7 +2808,7 @@ namespace SoF
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.Color);
IN(color.color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
@@ -2885,7 +2858,7 @@ namespace SoF
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
const ItemData *item = inst->GetUnscaledItem();
const Item_Struct *item = inst->GetUnscaledItem();
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
SoF::structs::ItemSerializationHeader hdr;
hdr.stacksize = stackable ? charges : 1;
@@ -3281,7 +3254,7 @@ namespace SoF
/*
// TEST CODE: <watch>
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
*/
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
+3 -6
View File
@@ -101,8 +101,6 @@ namespace SoF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -176,10 +174,9 @@ namespace SoF {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+109 -129
View File
@@ -103,74 +103,72 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/
};
@@ -241,8 +239,7 @@ struct Spawn_Struct {
/*0506*/ uint8 light; // Spawn's lightsource
/*0507*/ uint8 unknown0507[4];
/*0511*/ uint8 level; // Spawn Level
/*0512*/ uint32 PlayerState;
/*0516*/ uint8 unknown0516[12];
/*0512*/ uint8 unknown0512[16];
/*0528*/ uint8 lfg;
/*0529*/ uint8 unknown0529[4];
/*0533*/ uint8 hairstyle; // Sets the style of hair
@@ -526,7 +523,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
@@ -543,7 +540,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -645,7 +642,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges; // expendable charges
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
};
@@ -656,6 +653,9 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -663,42 +663,26 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -917,7 +901,7 @@ struct PlayerProfile_Struct //23576 Octets
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
/*08292*/ uint32 aapoints; // Unspent AA points
/*08296*/ uint8 unknown06160[4];
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
@@ -1069,7 +1053,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1183,8 +1167,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*04*/
};
@@ -1250,10 +1234,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -1948,7 +1931,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2307,7 +2290,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2327,8 +2310,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
@@ -3565,35 +3548,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -3683,14 +3661,10 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0081*/ uint8 unknown80[7];
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0096*/ uint16 unknown0096;
/*0098*/ uint32 total_abilities;
/*0102*/ AA_Ability abilities[0];
};
@@ -3706,6 +3680,12 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3723,12 +3703,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct {
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+2 -7
View File
@@ -41,11 +41,6 @@
memset(__packet->pBuffer, 0, len); \
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
#define ALLOC_LEN_ENCODE(len) \
__packet->pBuffer = new unsigned char[len]; \
__packet->size = len; \
memset(__packet->pBuffer, 0, len); \
//a shorter assignment for direct mode
#undef OUT
#define OUT(x) eq->x = emu->x;
@@ -129,14 +124,14 @@
//check length of packet before decoding. Call before setup.
#define DECODE_LENGTH_EXACT(struct_) \
if(__packet->size != sizeof(struct_)) { \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
return; \
}
#define DECODE_LENGTH_ATLEAST(struct_) \
if(__packet->size < sizeof(struct_)) { \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
return; \
}
+111 -194
View File
@@ -122,7 +122,7 @@ namespace Titanium
EAT_ENCODE(OP_GuildMemberLevelUpdate); // added ;
EAT_ENCODE(OP_ZoneServerReady); // added ;
ENCODE(OP_Action)
{
ENCODE_LENGTH_EXACT(Action_Struct);
@@ -263,42 +263,40 @@ namespace Titanium
EQApplicationPacket *in = *p;
*p = nullptr;
delete in;
//store away the emu struct
unsigned char *__emu_buffer = in->pBuffer;
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int itemcount = in->size / sizeof(InternalSerializedItem_Struct);
//if (itemcount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
// delete in;
// return;
//}
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
////do the transform...
//int r;
//std::string serial_string;
//for (r = 0; r < itemcount; r++, eq++) {
// uint32 length;
// char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0);
// if (serialized) {
// serial_string.append(serialized, length + 1);
// safe_delete_array(serialized);
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//
//}
//
//in->size = serial_string.length();
//in->pBuffer = new unsigned char[in->size];
//memcpy(in->pBuffer, serial_string.c_str(), serial_string.length());
//
//delete[] __emu_buffer;
//
//dest->FastQueuePacket(&in, ack_req);
int itemcount = in->size / sizeof(InternalSerializedItem_Struct);
if (itemcount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//do the transform...
int r;
std::string serial_string;
for (r = 0; r < itemcount; r++, eq++) {
uint32 length;
char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0);
if (serialized) {
serial_string.append(serialized, length + 1);
safe_delete_array(serialized);
}
else {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
}
}
in->size = serial_string.length();
in->pBuffer = new unsigned char[in->size];
memcpy(in->pBuffer, serial_string.c_str(), serial_string.length());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_DeleteCharge) { ENCODE_FORWARD(OP_MoveItem); }
@@ -328,7 +326,7 @@ namespace Titanium
{
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
@@ -778,14 +776,14 @@ namespace Titanium
ENCODE(OP_MoveItem)
{
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//eq->from_slot = ServerToTitaniumSlot(emu->from_slot);
//eq->to_slot = ServerToTitaniumSlot(emu->to_slot);
//OUT(number_in_stack);
//
//FINISH_ENCODE();
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
eq->from_slot = ServerToTitaniumSlot(emu->from_slot);
eq->to_slot = ServerToTitaniumSlot(emu->to_slot);
OUT(number_in_stack);
FINISH_ENCODE();
}
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
@@ -867,7 +865,7 @@ namespace Titanium
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
OUT(item_material[r]);
OUT(item_tint[r].Color);
OUT(item_tint[r].color);
}
// OUT(unknown00224[48]);
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
@@ -924,46 +922,24 @@ namespace Titanium
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
}
}
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER_ITEMS; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1072,7 +1048,7 @@ namespace Titanium
ENCODE(OP_ReadBook)
{
// no apparent slot translation needed
// no apparent slot translation needed -U
EQApplicationPacket *in = *p;
*p = nullptr;
@@ -1100,8 +1076,8 @@ namespace Titanium
unsigned int r;
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
OUT(aa_list[r].AA);
OUT(aa_list[r].value);
OUT(aa_list[r].aa_skill);
OUT(aa_list[r].aa_value);
}
FINISH_ENCODE();
@@ -1157,98 +1133,39 @@ namespace Titanium
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
SETUP_DIRECT_ENCODE(CharacterSelect_Struct, structs::CharacterSelect_Struct);
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
for (size_t index = 0; index < 10; ++index) {
memset(eq->Name[index], 0, 64);
}
// Non character-indexed packet fields
eq->Unknown830[0] = 0;
eq->Unknown830[1] = 0;
eq->Unknown0962[0] = 0;
eq->Unknown0962[1] = 0;
size_t char_index = 0;
for (; char_index < emu->CharCount && char_index < 8; ++char_index) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq->Race[char_index] = emu_cse->Race;
if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1;
for (int index = 0; index < _MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = emu_cse->Equip[index].Color.Color;
int r;
for (r = 0; r < 10; r++) {
OUT(zone[r]);
OUT(eyecolor1[r]);
OUT(eyecolor2[r]);
OUT(hairstyle[r]);
OUT(primary[r]);
if (emu->race[r] > 473)
eq->race[r] = 1;
else
eq->race[r] = emu->race[r];
OUT(class_[r]);
OUT_str(name[r]);
OUT(gender[r]);
OUT(level[r]);
OUT(secondary[r]);
OUT(face[r]);
OUT(beard[r]);
int k;
for (k = 0; k < 9; k++) {
eq->equip[r][k] = emu->equip[r][k].material;
eq->cs_colors[r][k].color = emu->equip[r][k].color.color;
}
eq->BeardColor[char_index] = emu_cse->BeardColor;
eq->HairStyle[char_index] = emu_cse->HairStyle;
for (int index = 0; index < _MaterialCount; ++index) {
eq->Equip[char_index][index] = emu_cse->Equip[index].Material;
}
eq->SecondaryIDFile[char_index] = emu_cse->SecondaryIDFile;
eq->Unknown820[char_index] = (uint8)0xFF;
eq->Deity[char_index] = emu_cse->Deity;
eq->GoHome[char_index] = emu_cse->GoHome;
eq->Tutorial[char_index] = emu_cse->Tutorial;
eq->Beard[char_index] = emu_cse->Beard;
eq->Unknown902[char_index] = (uint8)0xFF;
eq->PrimaryIDFile[char_index] = emu_cse->PrimaryIDFile;
eq->HairColor[char_index] = emu_cse->HairColor;
eq->Zone[char_index] = emu_cse->Zone;
eq->Class[char_index] = emu_cse->Class;
eq->Face[char_index] = emu_cse->Face;
memcpy(eq->Name[char_index], emu_cse->Name, 64);
eq->Gender[char_index] = emu_cse->Gender;
eq->EyeColor1[char_index] = emu_cse->EyeColor1;
eq->EyeColor2[char_index] = emu_cse->EyeColor2;
eq->Level[char_index] = emu_cse->Level;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
for (; char_index < 10; ++char_index) {
eq->Race[char_index] = 0;
for (int index = 0; index < _MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = 0;
}
eq->BeardColor[char_index] = 0;
eq->HairStyle[char_index] = 0;
for (int index = 0; index < _MaterialCount; ++index) {
eq->Equip[char_index][index] = 0;
}
eq->SecondaryIDFile[char_index] = 0;
eq->Unknown820[char_index] = (uint8)0xFF;
eq->Deity[char_index] = 0;
eq->GoHome[char_index] = 0;
eq->Tutorial[char_index] = 0;
eq->Beard[char_index] = 0;
eq->Unknown902[char_index] = (uint8)0xFF;
eq->PrimaryIDFile[char_index] = 0;
eq->HairColor[char_index] = 0;
eq->Zone[char_index] = 0;
eq->Class[char_index] = 0;
eq->Face[char_index] = 0;
strncpy(eq->Name[char_index], "<none>", 6);
eq->Gender[char_index] = 0;
eq->EyeColor1[char_index] = 0;
eq->EyeColor2[char_index] = 0;
eq->Level[char_index] = 0;
OUT(haircolor[r]);
OUT(gohome[r]);
OUT(tutorial[r]);
OUT(deity[r]);
OUT(beardcolor[r]);
eq->unknown820[r] = 0xFF;
eq->unknown902[r] = 0xFF;
}
FINISH_ENCODE();
@@ -1310,7 +1227,7 @@ namespace Titanium
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1353,7 +1270,7 @@ namespace Titanium
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1466,7 +1383,7 @@ namespace Titanium
OUT(spawn_id);
OUT(material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1551,15 +1468,15 @@ namespace Titanium
eq->beardcolor = emu->beardcolor;
// eq->unknown0147[4] = emu->unknown0147[4];
eq->level = emu->level;
eq->PlayerState = emu->PlayerState;
// eq->unknown0259[4] = emu->unknown0259[4];
eq->beard = emu->beard;
strcpy(eq->suffix, emu->suffix);
eq->petOwnerId = emu->petOwnerId;
eq->guildrank = emu->guildrank;
// eq->unknown0194[3] = emu->unknown0194[3];
for (k = 0; k < 9; k++) {
eq->equipment[k] = emu->equipment[k].Material;
eq->colors[k].Color = emu->colors[k].Color;
eq->equipment[k] = emu->equipment[k].material;
eq->colors[k].color = emu->colors[k].color;
}
for (k = 0; k < 8; k++) {
eq->set_to_0xFF[k] = 0xFF;
@@ -1623,7 +1540,7 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_ApplyPoison)
{
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
@@ -1854,16 +1771,16 @@ namespace Titanium
DECODE(OP_MoveItem)
{
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot);
//
//emu->from_slot = TitaniumToServerSlot(eq->from_slot);
//emu->to_slot = TitaniumToServerSlot(eq->to_slot);
//IN(number_in_stack);
//
//FINISH_DIRECT_DECODE();
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot);
emu->from_slot = TitaniumToServerSlot(eq->from_slot);
emu->to_slot = TitaniumToServerSlot(eq->to_slot);
IN(number_in_stack);
FINISH_DIRECT_DECODE();
}
DECODE(OP_PetCommands)
@@ -1944,14 +1861,14 @@ namespace Titanium
default:
emu->command = eq->command;
}
IN(target);
OUT(unknown);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ReadBook)
{
// no apparent slot translation needed
// no apparent slot translation needed -U
DECODE_LENGTH_ATLEAST(structs::BookRequest_Struct);
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
@@ -2035,7 +1952,7 @@ namespace Titanium
IN(spawn_id);
IN(material);
IN(color.Color);
IN(color.color);
IN(wear_slot_id);
emu->unknown06 = 0;
emu->elite_material = 0;
@@ -2072,7 +1989,7 @@ namespace Titanium
int16 slot_id = ServerToTitaniumSlot(slot_id_in);
uint32 merchant_slot = inst->GetMerchantSlot();
int16 charges = inst->GetCharges();
const ItemData *item = inst->GetUnscaledItem();
const Item_Struct *item = inst->GetUnscaledItem();
int i;
uint32 sub_length;
@@ -2153,7 +2070,7 @@ namespace Titanium
return serverSlot; // deprecated
}
static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot)
{
//int16 TitaniumCorpse;
@@ -2168,7 +2085,7 @@ namespace Titanium
return titaniumSlot; // deprecated
}
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot)
{
//uint32 ServerCorpse;
+3 -6
View File
@@ -100,8 +100,6 @@ namespace Titanium {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 16;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -175,10 +173,9 @@ namespace Titanium {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const size_t BANDOLIERS_SIZE = 4; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 4;
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 4;
static const size_t TEXT_LINK_BODY_LENGTH = 45;
}
+90 -103
View File
@@ -99,14 +99,16 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
@@ -115,32 +117,31 @@ struct Color_Struct
** Length: 1704 Bytes
**
*/
struct CharacterSelect_Struct
{
/*0000*/ uint32 Race[10]; // Characters Race
/*0040*/ Color_Struct CS_Colors[10][9]; // Characters Equipment Colors
/*0400*/ uint8 BeardColor[10]; // Characters beard Color
/*0410*/ uint8 HairStyle[10]; // Characters hair style
/*0420*/ uint32 Equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
/*0780*/ uint32 SecondaryIDFile[10]; // Characters secondary IDFile number
/*0820*/ uint8 Unknown820[10]; // 10x ff
/*0830*/ uint8 Unknown830[2]; // 2x 00
/*0832*/ uint32 Deity[10]; // Characters Deity
/*0872*/ uint8 GoHome[10]; // 1=Go Home available, 0=not
/*0882*/ uint8 Tutorial[10]; // 1=Tutorial available, 0=not
/*0892*/ uint8 Beard[10]; // Characters Beard Type
/*0902*/ uint8 Unknown902[10]; // 10x ff
/*0912*/ uint32 PrimaryIDFile[10]; // Characters primary IDFile number
/*0952*/ uint8 HairColor[10]; // Characters Hair Color
/*0962*/ uint8 Unknown0962[2]; // 2x 00
/*0964*/ uint32 Zone[10]; // Characters Current Zone
/*1004*/ uint8 Class[10]; // Characters Classes
/*1014*/ uint8 Face[10]; // Characters Face Type
/*1024*/ char Name[10][64]; // Characters Names
/*1664*/ uint8 Gender[10]; // Characters Gender
/*1674*/ uint8 EyeColor1[10]; // Characters Eye Color
/*1684*/ uint8 EyeColor2[10]; // Characters Eye 2 Color
/*1694*/ uint8 Level[10]; // Characters Levels
struct CharacterSelect_Struct {
/*0000*/ uint32 race[10]; // Characters Race
/*0040*/ Color_Struct cs_colors[10][9]; // Characters Equipment Colors
/*0400*/ uint8 beardcolor[10]; // Characters beard Color
/*0410*/ uint8 hairstyle[10]; // Characters hair style
/*0420*/ uint32 equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
/*0820*/ uint8 unknown820[10]; // 10x ff
/*0830*/ uint8 unknown830[2]; // 2x 00
/*0832*/ uint32 deity[10]; // Characters Deity
/*0872*/ uint8 gohome[10]; // 1=Go Home available, 0=not
/*0882*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
/*0892*/ uint8 beard[10]; // Characters Beard Type
/*0902*/ uint8 unknown902[10]; // 10x ff
/*0912*/ uint32 primary[10]; // Characters primary IDFile number
/*0952*/ uint8 haircolor[10]; // Characters Hair Color
/*0962*/ uint8 unknown0962[2]; // 2x 00
/*0964*/ uint32 zone[10]; // Characters Current Zone
/*1004*/ uint8 class_[10]; // Characters Classes
/*1014*/ uint8 face[10]; // Characters Face Type
/*1024*/ char name[10][64]; // Characters Names
/*1664*/ uint8 gender[10]; // Characters Gender
/*1674*/ uint8 eyecolor1[10]; // Characters Eye Color
/*1684*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
/*1694*/ uint8 level[10]; // Characters Levels
/*1704*/
};
@@ -212,7 +213,7 @@ struct Spawn_Struct {
/*0146*/ uint8 beardcolor; // Beard color
/*0147*/ uint8 unknown0147[4];
/*0151*/ uint8 level; // Spawn Level
/*0152*/ uint32 PlayerState; // PlayerState controls some animation stuff
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
/*0156*/ uint8 beard; // Beard style
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
@@ -445,7 +446,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
};
@@ -457,7 +458,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
@@ -585,48 +586,34 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 4;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
uint32 tribute;
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -830,7 +817,7 @@ struct PlayerProfile_Struct
/*06152*/ uint32 aapoints_spent; // Number of spent AA points
/*06156*/ uint32 aapoints; // Unspent AA points
/*06160*/ uint8 unknown06160[4];
/*06164*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // bandolier contents
/*06164*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // bandolier contents
/*07444*/ uint8 unknown07444[5120];
/*12564*/ PotionBelt_Struct potionbelt; // potion belt
/*12852*/ uint8 unknown12852[8];
@@ -950,7 +937,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1062,8 +1049,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*04*/
};
@@ -1101,9 +1088,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 11 */ uint32 unknown11;
/* 15 */ uint32 sequence; // see above notes in Action_Struct
/* 19 */ uint32 unknown19;
/* 23 */
};
@@ -1700,7 +1687,7 @@ struct AdventureRequestResponse_Struct{
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2010,7 +1997,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint16 unknown008[2]; //
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2029,8 +2016,8 @@ struct Object_Struct {
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*92*/
};
//01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
@@ -3043,35 +3030,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct Arrow_Struct {
@@ -3179,6 +3161,11 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3196,11 +3183,11 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct {
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+212 -245
View File
@@ -387,7 +387,7 @@ namespace UF
__packet->WriteUInt32(emu->entries[i].num_hits);
__packet->WriteString("");
}
__packet->WriteUInt8(emu->type);
__packet->WriteUInt8(!emu->all_buffs);
FINISH_ENCODE();
/*
@@ -474,69 +474,68 @@ namespace UF
{
//consume the packet
EQApplicationPacket *in = *p;
delete in;
//*p = nullptr;
//
//if (in->size == 0) {
//
// in->size = 4;
// in->pBuffer = new uchar[in->size];
// *((uint32 *)in->pBuffer) = 0;
//
// dest->FastQueuePacket(&in, ack_req);
// return;
//}
//
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
//
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
//
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
// opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
//
// delete in;
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
//
// if (Serialized) {
//
// uchar *OldBuffer = in->pBuffer;
// in->pBuffer = new uchar[in->size + Length];
// memcpy(in->pBuffer, OldBuffer, in->size);
//
// safe_delete_array(OldBuffer);
//
// memcpy(in->pBuffer + in->size, Serialized, Length);
// in->size += Length;
//
// safe_delete_array(Serialized);
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
*p = nullptr;
if (in->size == 0) {
in->size = 4;
in->pBuffer = new uchar[in->size];
*((uint32 *)in->pBuffer) = 0;
dest->FastQueuePacket(&in, ack_req);
return;
}
//store away the emu struct
unsigned char *__emu_buffer = in->pBuffer;
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
in->pBuffer = new uchar[4];
*(uint32 *)in->pBuffer = ItemCount;
in->size = 4;
for (int r = 0; r < ItemCount; r++, eq++) {
uint32 Length = 0;
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
if (Serialized) {
uchar *OldBuffer = in->pBuffer;
in->pBuffer = new uchar[in->size + Length];
memcpy(in->pBuffer, OldBuffer, in->size);
safe_delete_array(OldBuffer);
memcpy(in->pBuffer + in->size, Serialized, Length);
in->size += Length;
safe_delete_array(Serialized);
}
else {
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
}
}
delete[] __emu_buffer;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClientUpdate)
@@ -582,9 +581,7 @@ namespace UF
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
eq->sequence = emu->sequence;
FINISH_ENCODE();
}
@@ -858,8 +855,8 @@ namespace UF
// field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same
// issue.
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown, observed 0
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown, observed 0
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // This appears to be the size field.
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
@@ -1506,14 +1503,14 @@ namespace UF
ENCODE(OP_MoveItem)
{
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//eq->from_slot = ServerToUFSlot(emu->from_slot);
//eq->to_slot = ServerToUFSlot(emu->to_slot);
//OUT(number_in_stack);
//
//FINISH_ENCODE();
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
eq->from_slot = ServerToUFSlot(emu->from_slot);
eq->to_slot = ServerToUFSlot(emu->to_slot);
OUT(number_in_stack);
FINISH_ENCODE();
}
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
@@ -1794,13 +1791,13 @@ namespace UF
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
eq->equipment[r].material = emu->item_material[r];
eq->equipment[r].unknown1 = 0;
eq->equipment[r].elitematerial = 0;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint[r].color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1808,7 +1805,6 @@ namespace UF
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1872,46 +1868,26 @@ namespace UF
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
}
}
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -2136,9 +2112,9 @@ namespace UF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{
eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].charges = emu->aa_list[i].charges;
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
}
FINISH_ENCODE();
@@ -2183,7 +2159,6 @@ namespace UF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -2199,104 +2174,77 @@ namespace UF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars'
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
eq->TotalChars = adjusted_total;
FINISH_ENCODE();
return;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
}
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
eq->char_count = char_count;
eq->total_chars = 10;
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars' in this client
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
eq->TotalChars = adjusted_total;
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
}
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -2673,7 +2621,7 @@ namespace UF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2745,23 +2693,42 @@ namespace UF
ENCODE(OP_ZonePlayerToBind)
{
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
FINISH_ENCODE();
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
}
ENCODE(OP_ZoneServerInfo)
@@ -3009,7 +2976,7 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -3035,7 +3002,7 @@ namespace UF
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
}
}
}
@@ -3045,11 +3012,11 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
@@ -3059,9 +3026,9 @@ namespace UF
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].material = emu->equipment[k].material;
Equipment[k].unknown1 = emu->equipment[k].unknown1;
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -3362,7 +3329,7 @@ namespace UF
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
emu->sequence = eq->sequence;
FINISH_DIRECT_DECODE();
}
@@ -3587,16 +3554,16 @@ namespace UF
DECODE(OP_MoveItem)
{
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
//
//Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
//
//emu->from_slot = UFToServerSlot(eq->from_slot);
//emu->to_slot = UFToServerSlot(eq->to_slot);
//IN(number_in_stack);
//
//FINISH_DIRECT_DECODE();
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
emu->from_slot = UFToServerSlot(eq->from_slot);
emu->to_slot = UFToServerSlot(eq->to_slot);
IN(number_in_stack);
FINISH_DIRECT_DECODE();
}
DECODE(OP_PetCommands)
@@ -3605,7 +3572,7 @@ namespace UF
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
IN(command);
IN(target);
IN(unknown);
FINISH_DIRECT_DECODE();
}
@@ -3761,7 +3728,7 @@ namespace UF
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.Color);
IN(color.color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
@@ -3812,7 +3779,7 @@ namespace UF
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
const ItemData *item = inst->GetUnscaledItem();
const Item_Struct *item = inst->GetUnscaledItem();
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
UF::structs::ItemSerializationHeader hdr;
hdr.stacksize = stackable ? charges : 1;
@@ -3850,7 +3817,7 @@ namespace UF
//ORNAMENT IDFILE / ICON -
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = aug_weap->Icon;
@@ -3867,7 +3834,7 @@ namespace UF
UF::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = ornaIcon;
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown061 = 0; //possibly ornament / special ornament
hdrf.isCopied = 0; //Flag for item to be 'Copied'
hdrf.ItemClass = item->ItemClass;
@@ -4266,7 +4233,7 @@ namespace UF
/*
// TEST CODE: <watch>
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
*/
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
+3 -6
View File
@@ -101,8 +101,6 @@ namespace UF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -176,10 +174,9 @@ namespace UF {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+111 -133
View File
@@ -103,53 +103,53 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union {
struct {
uint8 blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
};
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 Unknown; // New field to Underfoot
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 unknown; // New field to Underfoot
};
@@ -157,22 +157,20 @@ struct CharacterSelectEntry_Struct
** Character Selection Struct
**
*/
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
/*12*/
};
@@ -286,7 +284,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -551,7 +549,7 @@ struct SpellBuff_Struct
/*003*/ uint8 effect; // not real
/*004*/ uint32 unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -568,7 +566,7 @@ struct SpellBuffFade_Struct_Underfoot {
/*007*/ uint8 unknown7;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*016*/ uint32 duration;
/*020*/ uint32 num_hits;
/*024*/ uint32 playerId; // Global player ID?
/*028*/ uint32 unknown020;
@@ -585,7 +583,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*012*/ uint32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -713,7 +711,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges; // expendable
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Underfoot
};
@@ -724,6 +722,9 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -731,42 +732,26 @@ struct Tribute_Struct {
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
bandolierRange,
bandolierAmmo
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -989,7 +974,7 @@ struct PlayerProfile_Struct
/*11236*/ uint32 aapoints_spent; // Number of spent AA points
/*11240*/ uint32 aapoints; // Unspent AA points
/*11244*/ uint8 unknown11244[4];
/*11248*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*11248*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*17648*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*18008*/ uint8 unknown18008[8];
/*18016*/ uint32 available_slots;
@@ -1146,7 +1131,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1260,8 +1245,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*04*/
};
@@ -1330,10 +1315,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -2032,7 +2016,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemData item;
Item_Struct item;
uint8 iss_unknown001[6];
};*/
@@ -2188,7 +2172,7 @@ struct GroupFollow_Struct { // Underfoot Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
/*120*/ int32 tics_remaining[BUFF_COUNT];
/*120*/ uint32 tics_remaining[BUFF_COUNT];
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
};
@@ -2441,7 +2425,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2461,8 +2445,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
@@ -3774,35 +3758,30 @@ struct DynamicWall_Struct {
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
};
// Not 100% sure on this struct. Live as of 1/1/11 is different than UF. Seems to work 'OK'
@@ -3892,16 +3871,10 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0081*/ uint8 unknown80[7];
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0096*/ uint32 unknown0096;
/*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0];
};
@@ -3917,6 +3890,11 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@@ -3935,7 +3913,7 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
@@ -3945,7 +3923,7 @@ struct AATable_Struct {
/*12*/ int32 unknown012;
/*16*/ int32 unknown016;
/*20*/ int32 unknown020;
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+6 -3
View File
@@ -47,6 +47,7 @@ const ProcLauncher::ProcRef ProcLauncher::ProcError = -1;
ProcLauncher::ProcLauncher()
{
_eqp
#ifndef WIN32
if(signal(SIGCHLD, ProcLauncher::HandleSigChild) == SIG_ERR)
fprintf(stderr, "Unable to register child signal handler. Thats bad.");
@@ -55,6 +56,7 @@ ProcLauncher::ProcLauncher()
}
void ProcLauncher::Process() {
_eqp
#ifdef _WINDOWS
std::map<ProcRef, Spec *>::iterator cur, end, tmp;
cur = m_running.begin();
@@ -108,7 +110,7 @@ void ProcLauncher::Process() {
}
void ProcLauncher::ProcessTerminated(std::map<ProcRef, Spec *>::iterator &it) {
_eqp
if(it->second->handler != nullptr)
it->second->handler->OnTerminate(it->first, it->second);
@@ -121,6 +123,7 @@ void ProcLauncher::ProcessTerminated(std::map<ProcRef, Spec *>::iterator &it) {
}
ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
_eqp
//consume the pointer
Spec *it = to_launch;
to_launch = nullptr;
@@ -275,6 +278,7 @@ ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
//if graceful is true, we try to be nice about it if possible
bool ProcLauncher::Terminate(const ProcRef &proc, bool graceful) {
_eqp
//we are only willing to kill things we started...
std::map<ProcRef, Spec *>::iterator res = m_running.find(proc);
if(res == m_running.end())
@@ -301,6 +305,7 @@ bool ProcLauncher::Terminate(const ProcRef &proc, bool graceful) {
}
void ProcLauncher::TerminateAll(bool final) {
_eqp
if(!final) {
//send a nice terminate to each process, with intention of waiting for them
std::map<ProcRef, Spec *>::iterator cur, end;
@@ -333,8 +338,6 @@ void ProcLauncher::HandleSigChild(int signum) {
}
#endif
ProcLauncher::Spec::Spec() {
handler = nullptr;
}
-92
View File
@@ -1,92 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PROFILER_H
#define PROFILER_H
#ifdef EQPROFILE
#include "../common/rdtsc.h"
#include "../common/types.h"
class ScopedProfiler;
class GeneralProfiler {
friend class ScopedProfiler;
public:
inline GeneralProfiler(unsigned int _count) {
count = _count;
timers = new RDTSC_Collector[count];
}
inline virtual ~GeneralProfiler() {
safe_delete_array(timers);
}
inline double getTotalDuration(unsigned int id) {
return(id<count? timers[id].getTotalDuration() : 0);
}
inline double getAverage(unsigned int id) {
return(id<count? timers[id].getAverage() : 0);
}
inline unsigned long long getTicks(unsigned int id) {
return(id<count? timers[id].getTicks() : 0);
}
inline unsigned long long getTotalTicks(unsigned int id) {
return(id<count? timers[id].getTotalTicks() : 0);
}
inline unsigned long long getCount(unsigned int id) {
return(id<count? timers[id].getCount() : 0);
}
inline void reset() {
unsigned int r;
RDTSC_Collector *cur = timers;
for(r = 0; r < count; r++, cur++)
cur->reset();
}
RDTSC_Collector *timers;
unsigned int count;
};
class ScopedProfiler {
public:
inline ScopedProfiler(RDTSC_Collector *c) {
_it = c;
c->start();
}
inline ~ScopedProfiler() {
_it->stop();
}
protected:
RDTSC_Collector *_it;
};
#define _GP(obj, pkg, name) ScopedProfiler __eqemu_profiler(&obj.timers[pkg::name])
#else // else !EQPROFILE
//no profiling, dummy functions
#define _GP(obj, pkg, name) ;
#endif
#endif
-3
View File
@@ -175,7 +175,6 @@ bool PersistentTimer::Store(Database *db) {
}
bool PersistentTimer::Clear(Database *db) {
std::string query = StringFormat("DELETE FROM timers "
"WHERE char_id = %lu AND type = %u ",
(unsigned long)_char_id, _type);
@@ -416,7 +415,6 @@ PersistentTimer *PTimerList::Get(pTimerType type) {
}
void PTimerList::ToVector(std::vector< std::pair<pTimerType, PersistentTimer *> > &out) {
std::pair<pTimerType, PersistentTimer *> p;
std::map<pTimerType, PersistentTimer *>::iterator s;
@@ -432,7 +430,6 @@ void PTimerList::ToVector(std::vector< std::pair<pTimerType, PersistentTimer *>
}
bool PTimerList::ClearOffline(Database *db, uint32 char_id, pTimerType type) {
std::string query = StringFormat("DELETE FROM timers WHERE char_id=%lu AND type=%u ",(unsigned long)char_id, type);
#ifdef DEBUG_PTIMERS
+1 -2
View File
@@ -39,8 +39,7 @@ enum { //values for pTimerType
pTimerDisciplineReuseStart = 14,
pTimerDisciplineReuseEnd = 24,
pTimerCombatAbility = 25,
pTimerCombatAbility2 = 26, // RoF2+ Tiger Claw is unlinked from other monk skills, generic in case other classes ever need it
pTimerBeggingPickPocket = 27,
pTimerBeggingPickPocket = 26,
pTimerLayHands = 87, //these IDs are used by client too
pTimerHarmTouch = 89, //so dont change them
-2
View File
@@ -47,8 +47,6 @@
#define IKSAR 128
#define VAHSHIR 130
#define CONTROLLED_BOAT 141
#define MINOR_ILL_OBJ 142
#define TREE 143
#define IKSAR_SKELETON 161
#define FROGLOK 330
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
-167
View File
@@ -1,167 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 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 "rdtsc.h"
#include "types.h"
#ifdef _WINDOWS
#include <sys/timeb.h>
#include "../common/timer.h"
#else
#include <unistd.h>
#include <sys/time.h>
#endif
#ifdef i386
#define USE_RDTSC
#endif
bool RDTSC_Timer::_inited = false;
int64 RDTSC_Timer::_ticsperms = 0;
RDTSC_Timer::RDTSC_Timer() {
if(!_inited) {
//find our clock rate
RDTSC_Timer::init();
}
_start = 0;
_end = 0;
}
RDTSC_Timer::RDTSC_Timer(bool start_it) {
if(!_inited) {
//find our clock rate
RDTSC_Timer::init();
}
if(start_it)
start();
else {
_start = 0;
_end = 0;
}
}
int64 RDTSC_Timer::rdtsc() {
int64 res = 0;
#ifdef USE_RDTSC
#ifndef WIN64
#ifdef WIN32
//untested!
unsigned long highw, loww;
__asm {
push eax
push edx
rdtsc
mov highw, eax
mov loww, edx
pop edx
pop eax
}
res = ((int64)highw)<<32 | loww;
#else
//gnu version
__asm__ __volatile__ ("rdtsc" : "=A" (res));
#endif
#else
//fall back to get time of day
timeval t;
gettimeofday(&t, nullptr);
res = ((int64)t.tv_sec) * 1000 + t.tv_usec;
#endif
#endif
return(res);
}
void RDTSC_Timer::init() {
#ifdef USE_RDTSC
int64 before, after, sum;
int r;
sum = 0;
// run an average to increase accuracy of clock rate
for(r = 0; r < CALIBRATE_LOOPS; r++) {
before = rdtsc();
//sleep a know duration to figure out clock rate
#ifdef _WINDOWS
Sleep(SLEEP_TIME);
#else
usleep(SLEEP_TIME * 1000); //ms * 1000
#endif
after = rdtsc();
sum += after - before;
}
//ticks per sleep / ms per sleep
_ticsperms = (sum / CALIBRATE_LOOPS) / SLEEP_TIME;
#else
//if using gettimeofday, this is fixed at 1000
_ticsperms = 1000;
#endif
// printf("Tics per milisecond: %llu \n", _ticsperms);
_inited = true; //only want to do this once
}
//start the timer
void RDTSC_Timer::start() {
_start = rdtsc();
_end = 0;
}
//stop the timer
void RDTSC_Timer::stop() {
_end = rdtsc();
}
//calculate the elapsed duration
double RDTSC_Timer::getDuration() {
return(((double)(getTicks())) / double(_ticsperms));
}
RDTSC_Collector::RDTSC_Collector() : RDTSC_Timer() {
reset();
}
RDTSC_Collector::RDTSC_Collector(bool start_it) : RDTSC_Timer(start_it) {
reset();
}
void RDTSC_Collector::stop() {
RDTSC_Timer::stop();
_sum += RDTSC_Timer::getTicks();
_count++;
}
//calculate the elapsed duration
double RDTSC_Collector::getTotalDuration() {
return(((double)(getTotalTicks())) / double(_ticsperms));
}
double RDTSC_Collector::getAverage() {
return(((double)(getTotalTicks())) / double(_ticsperms * _count));
}
void RDTSC_Collector::reset() {
_sum = 0;
_count = 0;
}
-86
View File
@@ -1,86 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RDTSC_H
#define RDTSC_H
#define CALIBRATE_LOOPS 3
#define SLEEP_TIME 10 //in ms
/*
This class implementes the highest possibly prescision timer
which is avaliable on the current archetecture.
On intel, this uses the rdtsc instruction to get the actual
clock cycle count, and elsewhere it falls back to gettimeofday
All calculations are carried out in 64 bit integers.
*/
#include "types.h"
class RDTSC_Timer {
public:
RDTSC_Timer();
RDTSC_Timer(bool start_it);
void start(); //start the timer
virtual void stop(); //stop the timer
double getDuration(); //returns the number of miliseconds elapsed
//access functions
int64 getTicks() { return(_end - _start); }
static int64 ticksPerMS() { return(_ticsperms); }
protected:
static int64 rdtsc();
int64 _start;
int64 _end;
protected:
static void init();
static bool _inited;
static int64 _ticsperms;
};
//this is a timer which can be started and stoped many times.
//each time it contributes its counter to a sum, whic is used
//to find net duration.
class RDTSC_Collector : public RDTSC_Timer {
public:
RDTSC_Collector();
RDTSC_Collector(bool start_it);
void reset();
void stop(); //stop the timer
double getTotalDuration(); //returns the number of miliseconds elapsed
double getAverage();
int64 getTotalTicks() { return(_sum); }
int64 getCount() { return(_count); }
protected:
int64 _sum;
int64 _count;
};
#endif
+497 -496
View File
File diff suppressed because it is too large Load Diff
+134 -1
View File
@@ -181,7 +181,14 @@
#define ServerOP_CZMessagePlayer 0x4008
#define ServerOP_ReloadWorld 0x4009
#define ServerOP_ReloadLogs 0x4010
#define ServerOP_QSSendQuery 0x5000
/* Query Server OP Codes */
#define ServerOP_QSPlayerLogTrades 0x5010
#define ServerOP_QSPlayerLogHandins 0x5011
#define ServerOP_QSPlayerLogNPCKills 0x5012
#define ServerOP_QSPlayerLogDeletes 0x5013
#define ServerOP_QSPlayerLogMoves 0x5014
#define ServerOP_QSPlayerLogMerchantTransactions 0x5015
#define ServerOP_QSSendQuery 0x5016
#define ServerOP_CZSignalNPC 0x5017
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018
@@ -1106,6 +1113,132 @@ struct CZClientSignalByName_Struct {
uint32 data;
};
struct QSTradeItems_Struct {
uint32 from_id;
uint16 from_slot;
uint32 to_id;
uint16 to_slot;
uint32 item_id;
uint16 charges;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
};
struct QSPlayerLogTrade_Struct {
uint32 char1_id;
MoneyUpdate_Struct char1_money;
uint16 char1_count;
uint32 char2_id;
MoneyUpdate_Struct char2_money;
uint16 char2_count;
uint16 _detail_count;
QSTradeItems_Struct items[0];
};
struct QSHandinItems_Struct {
char action_type[7]; // handin, return or reward
uint16 char_slot;
uint32 item_id;
uint16 charges;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
};
struct QSPlayerLogHandin_Struct {
uint32 quest_id;
uint32 char_id;
MoneyUpdate_Struct char_money;
uint16 char_count;
uint32 npc_id;
MoneyUpdate_Struct npc_money;
uint16 npc_count;
uint16 _detail_count;
QSHandinItems_Struct items[0];
};
struct QSPlayerLogNPCKillSub_Struct{
uint32 NPCID;
uint32 ZoneID;
uint32 Type;
};
struct QSPlayerLogNPCKillsPlayers_Struct{
uint32 char_id;
};
struct QSPlayerLogNPCKill_Struct{
QSPlayerLogNPCKillSub_Struct s1;
QSPlayerLogNPCKillsPlayers_Struct Chars[0];
};
struct QSDeleteItems_Struct {
uint16 char_slot;
uint32 item_id;
uint16 charges;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
};
struct QSPlayerLogDelete_Struct {
uint32 char_id;
uint16 stack_size; // '0' indicates full stack or non-stackable item move
uint16 char_count;
QSDeleteItems_Struct items[0];
};
struct QSMoveItems_Struct {
uint16 from_slot;
uint16 to_slot;
uint32 item_id;
uint16 charges;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
};
struct QSPlayerLogMove_Struct {
uint32 char_id;
uint16 from_slot;
uint16 to_slot;
uint16 stack_size; // '0' indicates full stack or non-stackable item move
uint16 char_count;
bool postaction;
QSMoveItems_Struct items[0];
};
struct QSTransactionItems_Struct {
uint16 char_slot;
uint32 item_id;
uint16 charges;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
};
struct QSMerchantLogTransaction_Struct {
uint32 zone_id;
uint32 merchant_id;
MoneyUpdate_Struct merchant_money;
uint16 merchant_count;
uint32 char_id;
MoneyUpdate_Struct char_money;
uint16 char_count;
QSTransactionItems_Struct items[0];
};
struct QSGeneralQuery_Struct {
char QueryString[0];
};
+276 -165
View File
@@ -43,6 +43,7 @@ SharedDatabase::~SharedDatabase() {
bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
{
_eqp
std::string query = StringFormat("UPDATE account SET hideme = %i WHERE id = %i", hideme, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -54,6 +55,7 @@ bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
uint8 SharedDatabase::GetGMSpeed(uint32 account_id)
{
_eqp
std::string query = StringFormat("SELECT gmspeed FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -70,6 +72,7 @@ uint8 SharedDatabase::GetGMSpeed(uint32 account_id)
bool SharedDatabase::SetGMSpeed(uint32 account_id, uint8 gmspeed)
{
_eqp
std::string query = StringFormat("UPDATE account SET gmspeed = %i WHERE id = %i", gmspeed, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -80,6 +83,7 @@ bool SharedDatabase::SetGMSpeed(uint32 account_id, uint8 gmspeed)
}
uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
_eqp
uint32 EntitledTime = 0;
std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
auto results = QueryDatabase(query);
@@ -91,6 +95,7 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
{
_eqp
// Delete cursor items
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i "
"AND ((slotid >= 8000 AND slotid <= 8999) "
@@ -118,6 +123,7 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iter
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst)
{
_eqp
// Delete cursor items
std::string query = StringFormat("SELECT itemid, charges FROM sharedbank "
"WHERE acctid = %d AND slotid = %d",
@@ -150,81 +156,80 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
}
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
_eqp
// If we never save tribute slots..how are we to ever benefit from them!!? The client
// object is destroyed upon zoning - including its inventory object..and if tributes
// don't exist in the database, then they will never be loaded when the new client
// object is created in the new zone object... Something to consider... -U
//
// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline)
return true;
//// If we never save tribute slots..how are we to ever benefit from them!!? The client
//// object is destroyed upon zoning - including its inventory object..and if tributes
//// don't exist in the database, then they will never be loaded when the new client
//// object is created in the new zone object... Something to consider... -U
////
//// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline)
//
////never save tribute slots:
//if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
// return true;
//
//if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
// // Shared bank inventory
// if (!inst)
// return DeleteSharedBankSlot(char_id, slot_id);
// else
// return UpdateSharedBankSlot(char_id, inst, slot_id);
//}
//else if (!inst) { // All other inventory
// return DeleteInventorySlot(char_id, slot_id);
//}
//
//return UpdateInventorySlot(char_id, inst, slot_id);
//never save tribute slots:
if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
return true;
if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
// Shared bank inventory
if (!inst)
return DeleteSharedBankSlot(char_id, slot_id);
else
return UpdateSharedBankSlot(char_id, inst, slot_id);
}
else if (!inst) { // All other inventory
return DeleteInventorySlot(char_id, slot_id);
}
return UpdateInventorySlot(char_id, inst, slot_id);
}
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
return true;
_eqp
// need to check 'inst' argument for valid pointer
//
//uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
//if (inst->IsType(ItemClassCommon)) {
// for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
// ItemInst *auginst = inst->GetItem(i);
// augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
// }
//}
//
//uint16 charges = 0;
//if(inst->GetCharges() >= 0)
// charges = inst->GetCharges();
//else
// charges = 0x7FFF;
//
//// Update/Insert item
//std::string query = StringFormat("REPLACE INTO inventory "
// "(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
// "augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
// "VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
// "%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
// (unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
// (unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0),
// inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
// (unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
// (unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(),
// (unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel());
//auto results = QueryDatabase(query);
//
//// Save bag contents, if slot supports bag contents
//if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id))
// for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
// const ItemInst* baginst = inst->GetItem(idx);
// SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx));
// }
//
//if (!results.Success()) {
// return false;
//}
//
//return true;
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
if (inst->IsType(ItemClassCommon)) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst = inst->GetItem(i);
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
}
}
uint16 charges = 0;
if(inst->GetCharges() >= 0)
charges = inst->GetCharges();
else
charges = 0x7FFF;
// Update/Insert item
std::string query = StringFormat("REPLACE INTO inventory "
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
(unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
(unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0),
inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
(unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
(unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(),
(unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel());
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id))
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
}
if (!results.Success()) {
return false;
}
return true;
}
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
_eqp
// need to check 'inst' argument for valid pointer
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
@@ -255,12 +260,10 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) {
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
// messages through attrition (and the modded code in SaveInventory)
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) {
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx));
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
}
}
@@ -272,6 +275,7 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
}
bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
_eqp
// Delete item
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid = %i", char_id, slot_id);
@@ -281,10 +285,10 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
}
// Delete bag slots, if need be
if (!InventoryOld::SupportsContainers(slot_id))
if (!Inventory::SupportsContainers(slot_id))
return true;
int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN);
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN);
query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i",
char_id, base_slot_id, (base_slot_id+10));
results = QueryDatabase(query);
@@ -297,6 +301,7 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
}
bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
_eqp
// Delete item
uint32 account_id = GetAccountIDByChar(char_id);
@@ -307,10 +312,10 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
}
// Delete bag slots, if need be
if (!InventoryOld::SupportsContainers(slot_id))
if (!Inventory::SupportsContainers(slot_id))
return true;
int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN);
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN);
query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i "
"AND slotid >= %i AND slotid < %i",
account_id, base_slot_id, (base_slot_id+10));
@@ -326,6 +331,7 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
{
_eqp
std::string query = StringFormat("SELECT sharedplat FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -341,6 +347,7 @@ int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
}
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
_eqp
std::string query = StringFormat("UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -350,9 +357,9 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
return true;
}
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
const ItemData* myitem;
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
_eqp
const Item_Struct* myitem;
std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items "
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
@@ -373,7 +380,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* in
if(!myitem)
continue;
ItemInst* myinst = CreateBaseItemOld(myitem, charges);
ItemInst* myinst = CreateBaseItem(myitem, charges);
if(slot < 0)
slot = inv->FindFreeSlot(0, 0);
@@ -387,8 +394,9 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* in
// Retrieve shared bank inventory based on either account or character
bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid)
bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
{
_eqp
std::string query;
if (is_charid)
@@ -424,7 +432,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid)
aug[4] = (uint32)atoi(row[7]);
aug[5] = (uint32)atoi(row[8]);
const ItemData *item = GetItem(item_id);
const Item_Struct *item = GetItem(item_id);
if (!item) {
Log.Out(Logs::General, Logs::Error,
@@ -435,7 +443,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid)
int16 put_slot_id = INVALID_INDEX;
ItemInst *inst = CreateBaseItemOld(item, charges);
ItemInst *inst = CreateBaseItem(item, charges);
if (inst && item->ItemClass == ItemClassCommon) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (aug[i])
@@ -487,69 +495,153 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid)
}
// Overloaded: Retrieve character inventory based on character id
bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv)
bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
{
std::string query = StringFormat("SELECT type, slot, bag_index, aug_index, item_id, charges, color, attuned, "
"custom_data, ornament_icon, ornament_idfile, ornament_hero_model, tracking_id "
"FROM character_inventory WHERE id=%u ORDER BY type, slot, bag_index, aug_index",
char_id);
_eqp
// Retrieve character inventory
std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, "
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM "
"inventory WHERE charid = %i ORDER BY slotid",
char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
Log.Out(Logs::General, Logs::Error, "Error with query in SharedDatabase::GetInventory, could not get inventory"
" for character %u", char_id);
Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the "
"following SQL Queries:\nalter table inventory add instnodrop "
"tinyint(1) unsigned default 0 not null;\n");
return false;
}
auto timestamps = GetItemRecastTimestamps(char_id);
for(auto row : results) {
int type = atoi(row[0]);
int slot = atoi(row[1]);
int bag_index = atoi(row[2]);
int aug_index = atoi(row[3]);
int item_id = atoi(row[4]);
int charges = atoi(row[5]);
auto inst = CreateItem(item_id, charges);
if(inst) {
uint32 color = (uint32)std::stoul(row[6]);
int attuned = atoi(row[7]);
uint32 ornament_icon = (uint32)std::stoul(row[9]);
uint32 ornament_idfile = (uint32)std::stoul(row[10]);
uint32 ornament_hero_model = (uint32)std::stoul(row[11]);
for (auto row = results.begin(); row != results.end(); ++row) {
int16 slot_id = atoi(row[0]);
uint32 item_id = atoi(row[1]);
uint16 charges = atoi(row[2]);
uint32 color = atoul(row[3]);
inst->SetColor(color);
inst->SetAttuned(attuned ? true : false);
inst->SetCustomData(row[8]);
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
inst->SetTrackingID(row[12]);
uint32 aug[EmuConstants::ITEM_COMMON_SIZE];
auto *item = inst->GetItem();
if(item->RecastDelay) {
if(timestamps.count(item->RecastType)) {
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
aug[0] = (uint32)atoul(row[4]);
aug[1] = (uint32)atoul(row[5]);
aug[2] = (uint32)atoul(row[6]);
aug[3] = (uint32)atoul(row[7]);
aug[4] = (uint32)atoul(row[8]);
aug[5] = (uint32)atoul(row[9]);
bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false;
uint32 ornament_icon = (uint32)atoul(row[12]);
uint32 ornament_idfile = (uint32)atoul(row[13]);
uint32 ornament_hero_model = (uint32)atoul(row[14]);
const Item_Struct *item = GetItem(item_id);
if (!item) {
Log.Out(Logs::General, Logs::Error,
"Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id,
slot_id);
continue;
}
int16 put_slot_id = INVALID_INDEX;
ItemInst *inst = CreateBaseItem(item, charges);
if (inst == nullptr)
continue;
if (row[11]) {
std::string data_str(row[11]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
}
if(!inv->Put(EQEmu::InventorySlot(type, slot, bag_index, aug_index), inst)) {
Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u.",
item_id, type, slot, bag_index, aug_index, char_id);
char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
}
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
if (instnodrop ||
(((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) ||
slot_id == MainPowerSource) &&
inst->GetItem()->Attuneable))
inst->SetAttuned(true);
if (color > 0)
inst->SetColor(color);
if (charges == 0x7FFF)
inst->SetCharges(-1);
else if (charges == 0 &&
inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable.
inst->SetCharges(1);
else
inst->SetCharges(charges);
if (item->RecastDelay) {
if (timestamps.count(item->RecastType))
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
else
inst->SetRecastTimestamp(0);
}
if (item->ItemClass == ItemClassCommon) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
}
if (slot_id >= 8000 && slot_id <= 8999) {
put_slot_id = inv->PushCursor(*inst);
} else if (slot_id >= 3111 && slot_id <= 3179) {
// Admins: please report any occurrences of this error
Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: "
"charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...",
char_id, item_id, slot_id);
put_slot_id = inv->PushCursor(*inst);
} else {
Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u. Item does not exist.",
item_id, type, slot, bag_index, aug_index, char_id);
put_slot_id = inv->PutItem(slot_id, *inst);
}
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id == INVALID_INDEX) {
Log.Out(Logs::General, Logs::Error,
"Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",
char_id, item_id, slot_id);
}
}
return true;
// Retrieve shared inventory
return GetSharedBank(char_id, inv, true);
}
// Overloaded: Retrieve character inventory based on account_id and character name
bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *inv)
bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
{
_eqp
// Retrieve character inventory
std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
@@ -585,12 +677,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *i
uint32 ornament_idfile = (uint32)atoul(row[13]);
uint32 ornament_hero_model = (uint32)atoul(row[14]);
const ItemData *item = GetItem(item_id);
const Item_Struct *item = GetItem(item_id);
int16 put_slot_id = INVALID_INDEX;
if (!item)
continue;
ItemInst *inst = CreateBaseItemOld(item, charges);
ItemInst *inst = CreateBaseItem(item, charges);
if (inst == nullptr)
continue;
@@ -659,6 +751,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *i
std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
{
_eqp
std::map<uint32, uint32> timers;
std::string query = StringFormat("SELECT recast_type,timestamp FROM character_item_recast WHERE id=%u", char_id);
auto results = QueryDatabase(query);
@@ -672,6 +765,7 @@ std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type)
{
_eqp
std::string query = StringFormat("SELECT timestamp FROM character_item_recast WHERE id=%u AND recast_type=%u",
char_id, recast_type);
auto results = QueryDatabase(query);
@@ -684,6 +778,7 @@ uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type
void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
{
_eqp
// This actually isn't strictly live-like. Live your recast timestamps are forever
std::string query =
StringFormat("DELETE FROM character_item_recast WHERE id = %u and timestamp < UNIX_TIMESTAMP()", char_id);
@@ -692,6 +787,7 @@ void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
{
_eqp
item_count = -1;
max_id = 0;
@@ -714,6 +810,7 @@ void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
}
bool SharedDatabase::LoadItems() {
_eqp
if(items_mmf) {
return true;
}
@@ -729,12 +826,12 @@ bool SharedDatabase::LoadItems() {
if(items == -1) {
EQ_EXCEPT("SharedDatabase", "Database returned no result");
}
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<ItemData>::estimated_size(items, max_item));
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(items, max_item));
if(items_mmf->Size() != size) {
EQ_EXCEPT("SharedDatabase", "Couldn't load items because items_mmf->Size() != size");
}
items_hash = new EQEmu::FixedMemoryHashSet<ItemData>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
items_hash = new EQEmu::FixedMemoryHashSet<Item_Struct>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
mutex.Unlock();
} catch(std::exception& ex) {
Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what());
@@ -745,7 +842,8 @@ bool SharedDatabase::LoadItems() {
}
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) {
EQEmu::FixedMemoryHashSet<ItemData> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
_eqp
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
char ndbuffer[4];
bool disableNoRent = false;
@@ -773,7 +871,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
}
ItemData item;
Item_Struct item;
const std::string query = "SELECT source,"
#define F(x) "`"#x"`,"
@@ -786,7 +884,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
for(auto row = results.begin(); row != results.end(); ++row) {
memset(&item, 0, sizeof(ItemData));
memset(&item, 0, sizeof(Item_Struct));
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
strcpy(item.Name,row[ItemField::name]);
@@ -1001,7 +1099,8 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
const ItemData* SharedDatabase::GetItem(uint32 id) {
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
_eqp
if (id == 0)
{
return nullptr;
@@ -1020,7 +1119,8 @@ const ItemData* SharedDatabase::GetItem(uint32 id) {
return nullptr;
}
const ItemData* SharedDatabase::IterateItems(uint32* id) {
const Item_Struct* SharedDatabase::IterateItems(uint32* id) {
_eqp
if(!items_hash || !id) {
return nullptr;
}
@@ -1042,6 +1142,7 @@ const ItemData* SharedDatabase::IterateItems(uint32* id) {
std::string SharedDatabase::GetBook(const char *txtfile)
{
_eqp
char txtfile2[20];
std::string txtout;
strcpy(txtfile2, txtfile);
@@ -1066,6 +1167,7 @@ std::string SharedDatabase::GetBook(const char *txtfile)
}
void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
_eqp
list_count = 0;
max_lists = 0;
@@ -1085,6 +1187,7 @@ void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
}
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
_eqp
if(!faction_hash) {
return nullptr;
}
@@ -1097,6 +1200,7 @@ const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
}
void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists) {
_eqp
EQEmu::FixedMemoryHashSet<NPCFactionList> hash(reinterpret_cast<uint8*>(data), size, list_count, max_lists);
NPCFactionList faction;
@@ -1146,6 +1250,7 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co
}
bool SharedDatabase::LoadNPCFactionLists() {
_eqp
if(faction_hash) {
return true;
}
@@ -1176,14 +1281,15 @@ bool SharedDatabase::LoadNPCFactionLists() {
}
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItemOld(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
const ItemData* item = nullptr;
_eqp
const Item_Struct* item = nullptr;
ItemInst* inst = nullptr;
item = GetItem(item_id);
if (item) {
inst = CreateBaseItemOld(item, charges);
inst = CreateBaseItem(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
@@ -1205,14 +1311,15 @@ ItemInst* SharedDatabase::CreateItemOld(uint32 item_id, int16 charges, uint32 au
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItemOld(const ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
_eqp
ItemInst* inst = nullptr;
if (item) {
inst = CreateBaseItemOld(item, charges);
inst = CreateBaseItem(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItemOld()");
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
return nullptr;
}
@@ -1229,7 +1336,8 @@ ItemInst* SharedDatabase::CreateItemOld(const ItemData* item, int16 charges, uin
return inst;
}
ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges) {
ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) {
_eqp
ItemInst* inst = nullptr;
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
@@ -1243,7 +1351,7 @@ ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges)
inst = new ItemInst(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItemOld()");
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()");
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
return nullptr;
}
@@ -1255,29 +1363,8 @@ ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges)
return inst;
}
EQEmu::ItemInstance::pointer SharedDatabase::CreateItem(uint32 item_id, int16 charges, bool unique) {
const ItemData* item = GetItem(item_id);
if(item) {
if(charges == 0 && item->MaxCharges == -1) {
charges = 1;
}
if(charges <= 0 && item->Stackable) {
charges = 1;
}
EQEmu::ItemInstance::pointer inst = EQEmu::ItemInstance::pointer(new EQEmu::ItemInstance(item, charges));
if(unique) {
inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
//Set Tracking here
}
return inst;
}
return EQEmu::ItemInstance::pointer(nullptr);
}
int32 SharedDatabase::DeleteStalePlayerCorpses() {
_eqp
if(RuleB(Zone, EnableShadowrest)) {
std::string query = StringFormat(
"UPDATE `character_corpses` SET `is_buried` = 1 WHERE `is_buried` = 0 AND "
@@ -1300,7 +1387,8 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() {
return results.RowsAffected();
}
bool SharedDatabase::GetCommandSettings(std::map<std::string,uint8> &commands) {
bool SharedDatabase::GetCommandSettings(std::map<std::string, uint8> &commands) {
_eqp
const std::string query = "SELECT command, access FROM commands";
auto results = QueryDatabase(query);
@@ -1317,6 +1405,7 @@ bool SharedDatabase::GetCommandSettings(std::map<std::string,uint8> &commands) {
}
bool SharedDatabase::LoadSkillCaps() {
_eqp
if(skill_caps_mmf)
return true;
@@ -1343,6 +1432,7 @@ bool SharedDatabase::LoadSkillCaps() {
}
void SharedDatabase::LoadSkillCaps(void *data) {
_eqp
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
@@ -1370,6 +1460,7 @@ void SharedDatabase::LoadSkillCaps(void *data) {
}
uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Level) {
_eqp
if(!skill_caps_mmf) {
return 0;
}
@@ -1399,6 +1490,7 @@ uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Leve
}
uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Level) {
_eqp
if(!skill_caps_mmf) {
return 0;
}
@@ -1448,6 +1540,7 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Lev
}
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
_eqp
std::string query = StringFormat("SELECT `spellid`, `type` FROM `damageshieldtypes` WHERE `spellid` > 0 "
"AND `spellid` <= %i", iMaxSpellID);
@@ -1465,10 +1558,12 @@ void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpe
}
const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
_eqp
return nullptr; // nothing here for now... database and/or sharemem pulls later
}
int SharedDatabase::GetMaxSpellID() {
_eqp
std::string query = "SELECT MAX(id) FROM spells_new";
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1481,6 +1576,7 @@ int SharedDatabase::GetMaxSpellID() {
}
void SharedDatabase::LoadSpells(void *data, int max_spells) {
_eqp
SPDat_Spell_Struct *sp = reinterpret_cast<SPDat_Spell_Struct*>(data);
const std::string query = "SELECT * FROM spells_new ORDER BY id ASC";
@@ -1643,6 +1739,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
}
int SharedDatabase::GetMaxBaseDataLevel() {
_eqp
const std::string query = "SELECT MAX(level) FROM base_data";
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1658,6 +1755,7 @@ int SharedDatabase::GetMaxBaseDataLevel() {
}
bool SharedDatabase::LoadBaseData() {
_eqp
if(base_data_mmf) {
return true;
}
@@ -1686,6 +1784,7 @@ bool SharedDatabase::LoadBaseData() {
}
void SharedDatabase::LoadBaseData(void *data, int max_level) {
_eqp
char *base_ptr = reinterpret_cast<char*>(data);
const std::string query = "SELECT * FROM base_data ORDER BY level, class ASC";
@@ -1735,6 +1834,7 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
}
const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) {
_eqp
if(!base_data_mmf) {
return nullptr;
}
@@ -1764,6 +1864,7 @@ const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) {
}
void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries) {
_eqp
loot_table_count = 0;
max_loot_table = 0;
loot_table_entries = 0;
@@ -1784,6 +1885,7 @@ void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot
}
void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries) {
_eqp
loot_drop_count = 0;
max_loot_drop = 0;
loot_drop_entries = 0;
@@ -1805,6 +1907,7 @@ void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_d
}
void SharedDatabase::LoadLootTables(void *data, uint32 size) {
_eqp
EQEmu::FixedMemoryVariableHashSet<LootTable_Struct> hash(reinterpret_cast<uint8*>(data), size);
uint8 loot_table[sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * 128)];
@@ -1858,6 +1961,7 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) {
}
void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
_eqp
EQEmu::FixedMemoryVariableHashSet<LootDrop_Struct> hash(reinterpret_cast<uint8*>(data), size);
uint8 loot_drop[sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * 1260)];
@@ -1906,6 +2010,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
}
bool SharedDatabase::LoadLoot() {
_eqp
if(loot_table_mmf || loot_drop_mmf)
return true;
@@ -1930,6 +2035,7 @@ bool SharedDatabase::LoadLoot() {
}
const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
_eqp
if(!loot_table_hash)
return nullptr;
@@ -1944,6 +2050,7 @@ const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
}
const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
_eqp
if(!loot_drop_hash)
return nullptr;
@@ -1958,6 +2065,7 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
}
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
auto results = QueryDatabase(query);
auto row = results.begin();
@@ -1968,11 +2076,13 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes
}
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
auto results = QueryDatabase(query);
}
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("SELECT BotInspectMessage FROM bots WHERE BotID = %i", botid);
auto results = QueryDatabase(query);
@@ -1989,6 +2099,7 @@ void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* m
}
void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message) {
_eqp
std::string msg = EscapeString(message->text);
std::string query = StringFormat("UPDATE bots SET BotInspectMessage = '%s' WHERE BotID = %i", msg.c_str(), botid);
QueryDatabase(query);
+12 -14
View File
@@ -9,19 +9,18 @@
#include "base_data.h"
#include "fixed_memory_hash_set.h"
#include "fixed_memory_variable_hash_set.h"
#include "inventory.h"
#include <list>
#include <map>
class EvolveInfo;
class InventoryOld;
class Inventory;
class ItemInst;
struct BaseDataStruct;
struct InspectMessage_Struct;
struct PlayerProfile_Struct;
struct SPDat_Spell_Struct;
struct ItemData;
struct Item_Struct;
struct NPCFactionList;
struct LootTable_Struct;
struct LootDrop_Struct;
@@ -66,15 +65,15 @@ class SharedDatabase : public Database
bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst);
bool GetSharedBank(uint32 id, InventoryOld* inv, bool is_charid);
bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid);
int32 GetSharedPlatinum(uint32 account_id);
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
bool GetInventory(uint32 char_id, EQEmu::Inventory* inv);
bool GetInventory(uint32 account_id, char* name, InventoryOld* inv);
bool GetInventory(uint32 char_id, Inventory* inv);
bool GetInventory(uint32 account_id, char* name, Inventory* inv);
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type);
void ClearOldRecastTimestamps(uint32 char_id);
bool SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
std::string GetBook(const char *txtfile);
@@ -82,10 +81,9 @@ class SharedDatabase : public Database
/*
Item Methods
*/
ItemInst* CreateItemOld(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateItemOld(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateBaseItemOld(const ItemData* item, int16 charges = 0);
EQEmu::ItemInstance::pointer CreateItem(uint32 item_id, int16 charges = 0, bool unique = true);
ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateItem(const Item_Struct* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateBaseItem(const Item_Struct* item, int16 charges = 0);
/*
Shared Memory crap
@@ -95,8 +93,8 @@ class SharedDatabase : public Database
void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
bool LoadItems();
const ItemData* IterateItems(uint32* id);
const ItemData* GetItem(uint32 id);
const Item_Struct* IterateItems(uint32* id);
const Item_Struct* GetItem(uint32 id);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
//faction lists
@@ -132,7 +130,7 @@ class SharedDatabase : public Database
EQEmu::MemoryMappedFile *skill_caps_mmf;
EQEmu::MemoryMappedFile *items_mmf;
EQEmu::FixedMemoryHashSet<ItemData> *items_hash;
EQEmu::FixedMemoryHashSet<Item_Struct> *items_hash;
EQEmu::MemoryMappedFile *faction_mmf;
EQEmu::FixedMemoryHashSet<NPCFactionList> *faction_hash;
EQEmu::MemoryMappedFile *loot_table_mmf;
-51
View File
@@ -55,54 +55,3 @@ bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
return false;
}
}
float EQEmu::GetSkillMeleePushForce(SkillUseTypes skill)
{
// This is the force/magnitude of the push from an attack of this skill type
// You can find these numbers in the clients skill struct
switch (skill) {
case Skill1HBlunt:
case Skill1HSlashing:
case SkillHandtoHand:
case SkillThrowing:
return 0.1f;
case Skill2HBlunt:
case Skill2HSlashing:
case SkillEagleStrike:
case SkillKick:
case SkillTigerClaw:
//case Skill2HPiercing:
return 0.2f;
case SkillArchery:
return 0.15f;
case SkillBackstab:
case SkillBash:
return 0.3f;
case SkillDragonPunch:
case SkillRoundKick:
return 0.25f;
case SkillFlyingKick:
return 0.4f;
case Skill1HPiercing:
case SkillFrenzy:
return 0.05f;
case SkillIntimidation:
return 2.5f;
default:
return 0.0f;
}
}
bool EQEmu::IsBardInstrumentSkill(SkillUseTypes skill)
{
switch (skill) {
case SkillBrassInstruments:
case SkillSinging:
case SkillStringedInstruments:
case SkillWindInstruments:
case SkillPercussionInstruments:
return true;
default:
return false;
}
}
-4
View File
@@ -171,8 +171,6 @@ enum SkillUseTypes
// temporary until it can be sorted out...
#define HIGHEST_SKILL SkillFrenzy
// Spell Effects use this value to determine if an effect applies to all skills.
#define ALL_SKILLS -1
// server profile does not reflect this yet..so, prefixed with 'PACKET_'
#define PACKET_SKILL_ARRAY_SIZE 100
@@ -270,8 +268,6 @@ typedef enum {
namespace EQEmu {
bool IsTradeskill(SkillUseTypes skill);
bool IsSpecializedSkill(SkillUseTypes skill);
float GetSkillMeleePushForce(SkillUseTypes skill);
bool IsBardInstrumentSkill(SkillUseTypes skill);
}
#endif
+7 -7
View File
@@ -72,7 +72,7 @@
#include "../common/eqemu_logsys.h"
#include "../common/eqemu_logsys.h"
#include "classes.h"
#include "spdat.h"
@@ -162,7 +162,7 @@ bool IsCureSpell(uint16 spell_id)
bool CureEffect = false;
for(int i = 0; i < EFFECT_COUNT; i++){
if (sp.effectid[i] == SE_DiseaseCounter || sp.effectid[i] == SE_PoisonCounter
if (sp.effectid[i] == SE_DiseaseCounter || sp.effectid[i] == SE_PoisonCounter
|| sp.effectid[i] == SE_CurseCounter || sp.effectid[i] == SE_CorruptionCounter)
CureEffect = true;
}
@@ -405,7 +405,7 @@ bool IsPartialCapableSpell(uint16 spell_id)
{
if (spells[spell_id].no_partial_resist)
return false;
if (IsPureNukeSpell(spell_id))
return true;
@@ -447,7 +447,7 @@ bool IsTGBCompatibleSpell(uint16 spell_id)
bool IsBardSong(uint16 spell_id)
{
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 127 && !spells[spell_id].IsDisciplineBuff)
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 255)
return true;
return false;
@@ -693,9 +693,9 @@ bool IsCombatSkill(uint16 spell_id)
{
if (!IsValidSpell(spell_id))
return false;
//Check if Discipline
if ((spells[spell_id].mana == 0 && (spells[spell_id].EndurCost || spells[spell_id].EndurUpkeep)))
if ((spells[spell_id].mana == 0 && (spells[spell_id].EndurCost || spells[spell_id].EndurUpkeep)))
return true;
return false;
@@ -1040,7 +1040,7 @@ bool IsCastonFadeDurationSpell(uint16 spell_id)
bool IsPowerDistModSpell(uint16 spell_id)
{
if (IsValidSpell(spell_id) &&
if (IsValidSpell(spell_id) &&
(spells[spell_id].max_dist_mod || spells[spell_id].min_dist_mod) && spells[spell_id].max_dist > spells[spell_id].min_dist)
return true;
+17 -19
View File
@@ -38,7 +38,6 @@
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
const int Z_AGGRO=10;
@@ -133,7 +132,7 @@ typedef enum {
/* 42 */ ST_Directional = 0x2a, //ae around this target between two angles
/* 43 */ ST_GroupClientAndPet = 0x2b,
/* 44 */ ST_Beam = 0x2c,
/* 45 */ ST_Ring = 0x2d,
/* 45 */ ST_Ring = 0x2d,
/* 46 */ ST_TargetsTarget = 0x2e, // uses the target of your target
/* 47 */ ST_PetMaster = 0x2f, // uses the master as target
/* 48 */ // UNKNOWN
@@ -151,10 +150,10 @@ typedef enum {
} DmgShieldType;
//Spell Effect IDs
// https://forums.daybreakgames.com/eq/index.php?threads/enumerated-spa-list.206288/
// full listing: https://forums.station.sony.com/eq/index.php?threads/enumerated-spa-list.206288/
// mirror: http://pastebin.com/MYeQqGwe
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
#define SE_ArmorClass 1 // implemented
#define SE_ArmorClass 1 // implemented
#define SE_ATK 2 // implemented
#define SE_MovementSpeed 3 // implemented - SoW, SoC, etc
#define SE_STR 4 // implemented
@@ -197,7 +196,7 @@ typedef enum {
#define SE_Destroy 41 // implemented - Disintegrate, Banishment of Shadows
#define SE_ShadowStep 42 // implemented
#define SE_Berserk 43 // implemented (*not used in any known live spell) Makes client 'Berserk' giving crip blow chance.
#define SE_Lycanthropy 44 // implemented
#define SE_Lycanthropy 44 // implemented
#define SE_Vampirism 45 // implemented (*not used in any known live spell) Stackable lifetap from melee.
#define SE_ResistFire 46 // implemented
#define SE_ResistCold 47 // implemented
@@ -247,7 +246,7 @@ typedef enum {
#define SE_SummonCorpse 91 // implemented
#define SE_InstantHate 92 // implemented - add hate
#define SE_StopRain 93 // implemented - Wake of Karana
#define SE_NegateIfCombat 94 // implemented
#define SE_NegateIfCombat 94 // implemented
#define SE_Sacrifice 95 // implemented
#define SE_Silence 96 // implemented
#define SE_ManaPool 97 // implemented
@@ -299,7 +298,7 @@ typedef enum {
#define SE_LimitCastTimeMin 143 // implemented
#define SE_LimitCastTimeMax 144 // implemented (*not used in any known live spell)
#define SE_Teleport2 145 // implemented - Banishment of the Pantheon
//#define SE_ElectricityResist 146 // *not implemented (Lightning Rod: 23233)
//#define SE_ElectricityResist 146 // *not implemented (Lightning Rod: 23233)
#define SE_PercentalHeal 147 // implemented
#define SE_StackingCommand_Block 148 // implemented?
#define SE_StackingCommand_Overwrite 149 // implemented?
@@ -529,7 +528,7 @@ typedef enum {
#define SE_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades.
#define SE_ApplyEffect 374 // implemented
#define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount
//#define SE_Fling 376 // *not implemented - used in 2 test spells (12945 | Movement Test Spell 1)
//#define SE_Fling 376 // *not implemented - used in 2 test spells (12945 | Movement Test Spell 1)
#define SE_CastOnFadeEffectNPC 377 // implemented - Triggers only if fades after natural duration (On live these are usually players spells that effect an NPC).
#define SE_SpellEffectResistChance 378 // implemented - Increase chance to resist specific spell effect (base1=value, base2=spell effect id)
#define SE_ShadowStepDirectional 379 // implemented - handled by client
@@ -560,7 +559,7 @@ typedef enum {
#define SE_LimitSpellSubclass 404 // *not implemented - Limits to specific types of spells (see CheckSpellCategory) [Categories NOT defined yet]
#define SE_TwoHandBluntBlock 405 // implemented - chance to block attacks when using two hand blunt weapons (similiar to shield block)
#define SE_CastonNumHitFade 406 // implemented - casts a spell when a buff fades due to its numhits being depleted
#define SE_CastonFocusEffect 407 // implemented - casts a spell if focus limits are met (ie triggers when a focus effects is applied)
#define SE_CastonFocusEffect 407 // implemented - casts a spell if focus limits are met (ie triggers when a focus effects is applied)
#define SE_LimitHPPercent 408 // implemented - limited to a certain percent of your hp(ie heals up to 50%)
#define SE_LimitManaPercent 409 // implemented - limited to a certain percent of your mana
#define SE_LimitEndPercent 410 // implemented - limited to a certain percent of your end
@@ -576,7 +575,7 @@ typedef enum {
#define SE_FcLimitUse 420 // implemented - increases numhits count by percent (Note: not used in any known live spells)
#define SE_FcIncreaseNumHits 421 // implemented[AA] - increases number of hits a buff has till fade. (focus)
#define SE_LimitUseMin 422 // implemented - limit a focus to require a min amount of numhits value (used with above)
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
//#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
@@ -600,9 +599,9 @@ typedef enum {
#define SE_ImprovedTaunt 444 // implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y
//#define SE_AddMercSlot 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs.
#define SE_AStacker 446 // implementet - bufff stacking blocker (26219 | Qirik's Watch)
#define SE_BStacker 447 // implemented
#define SE_BStacker 447 // implemented
#define SE_CStacker 448 // implemented
#define SE_DStacker 449 // implemented
#define SE_DStacker 449 // implemented
#define SE_MitigateDotDamage 450 // implemented DOT spell mitigation rune with max value
#define SE_MeleeThresholdGuard 451 // implemented Partial Melee Rune that only is lowered if melee hits are over X amount of damage
#define SE_SpellThresholdGuard 452 // implemented Partial Spell Rune that only is lowered if spell hits are over X amount of damage
@@ -618,7 +617,6 @@ typedef enum {
#define DF_Permanent 50
#define DF_Aura 51
// note this struct is historical, we don't actually need it to be
// aligned to anything, but for maintaining it it is kept in the order that
@@ -734,31 +732,31 @@ struct SPDat_Spell_Struct
/* 197 */ bool not_extendable;
/* 198- 199 */
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
/* 201 */ int viral_range;
/* 201 */ int viral_range;
/* 202 */
/* 203 */ //int songcap; // individual song cap (how live currently does it, not implemented)
/* 204 */
/* 205 */ bool no_block;
/* 206 */
/* 206 */
/* 207 */ int spellgroup;
/* 208 */ int rank; //increments AA effects with same name
/* 209 */ int powerful_flag; // Need more investigation to figure out what to call this, for now we know -1 makes charm spells not break before their duration is complete, it does alot more though
/* 210 */ // bool DurationFrozen; ???
/* 210 */ // bool DurationFrozen; ???
/* 211 */ int CastRestriction; //Various restriction categories for spells most seem targetable race related but have also seen others for instance only castable if target hp 20% or lower or only if target out of combat
/* 212 */ bool AllowRest;
/* 213 */ bool InCombat; //Allow spell if target is in combat
/* 214 */ bool OutofCombat; //Allow spell if target is out of combat
/* 215 - 217 */
/* 218 */ int aemaxtargets; //Is used for various AE effects
/* 218 */ int aemaxtargets; //Is used for various AE effects
/* 219 */ int maxtargets; //Is used for beam and ring spells for target # limits (not implemented)
/* 220 - 223 */
/* 220 - 223 */
/* 224 */ bool persistdeath; // buff doesn't get stripped on death
/* 225 - 226 */
/* 227 */ float min_dist; //spell power modified by distance from caster (Min Distance)
/* 228 */ float min_dist_mod; //spell power modified by distance from caster (Modifier at Min Distance)
/* 229 */ float max_dist; //spell power modified by distance from caster (Max Distance)
/* 230 */ float max_dist_mod; //spell power modified by distance from caster (Modifier at Max Distance)
/* 231 */ float min_range; //Min casting range
/* 231 */ float min_range; //Min casting range
/* 232 - 236 */
uint8 DamageShieldType; // This field does not exist in spells_us.txt
};
+7
View File
@@ -64,6 +64,7 @@ const std::string vStringFormat(const char* format, va_list args)
const std::string StringFormat(const char* format, ...)
{
_eqp
va_list args;
va_start(args, format);
std::string output = vStringFormat(format,args);
@@ -121,6 +122,7 @@ void MakeLowerString(const char *source, char *target) {
}
int MakeAnyLenString(char** ret, const char* format, ...) {
_eqp
int buf_len = 128;
int chars = -1;
va_list argptr, tmpargptr;
@@ -140,6 +142,7 @@ int MakeAnyLenString(char** ret, const char* format, ...) {
}
uint32 AppendAnyLenString(char** ret, uint32* bufsize, uint32* strlen, const char* format, ...) {
_eqp
if (*bufsize == 0)
*bufsize = 256;
if (*ret == 0)
@@ -258,6 +261,7 @@ bool atobool(const char* iBool) {
// removes the crap and turns the underscores into spaces.
char *CleanMobName(const char *in, char *out)
{
_eqp
unsigned i, j;
for(i = j = 0; i < strlen(in); i++)
@@ -312,6 +316,7 @@ const char *ConvertArrayF(float input, char *returnchar)
}
std::vector<std::string> SplitString(const std::string &str, char delim) {
_eqp
std::vector<std::string> ret;
std::stringstream ss(str);
std::string item;
@@ -324,6 +329,7 @@ std::vector<std::string> SplitString(const std::string &str, char delim) {
}
std::string EscapeString(const std::string &s) {
_eqp
std::string ret;
size_t sz = s.length();
@@ -361,6 +367,7 @@ std::string EscapeString(const std::string &s) {
}
std::string EscapeString(const char *src, size_t sz) {
_eqp
std::string ret;
for(size_t i = 0; i < sz; ++i) {
+8
View File
@@ -11,6 +11,7 @@
//note: all encoders and decoders must be valid functions.
//so if you specify set_defaults=false
StructStrategy::StructStrategy() {
_eqp
int r;
for(r = 0; r < _maxEmuOpcode; r++) {
encoders[r] = PassEncoder;
@@ -19,6 +20,7 @@ StructStrategy::StructStrategy() {
}
void StructStrategy::Encode(EQApplicationPacket **p, std::shared_ptr<EQStream> dest, bool ack_req) const {
_eqp
if((*p)->GetOpcodeBypass() != 0) {
PassEncoder(p, dest, ack_req);
return;
@@ -30,6 +32,7 @@ void StructStrategy::Encode(EQApplicationPacket **p, std::shared_ptr<EQStream> d
}
void StructStrategy::Decode(EQApplicationPacket *p) const {
_eqp
EmuOpcode op = p->GetOpcode();
Decoder proc = decoders[op];
proc(p);
@@ -37,6 +40,7 @@ void StructStrategy::Decode(EQApplicationPacket *p) const {
void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, std::shared_ptr<EQStream> dest, bool ack_req) {
_eqp
EQApplicationPacket *p = *in_p;
*in_p = nullptr;
@@ -46,11 +50,13 @@ void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, std::shared_ptr<EQ
}
void StructStrategy::ErrorDecoder(EQApplicationPacket *p) {
_eqp
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Error decoding opcode %s: no decoder provided. Invalidating.", OpcodeManager::EmuToName(p->GetOpcode()));
p->SetOpcode(OP_Unknown);
}
void StructStrategy::PassEncoder(EQApplicationPacket **p, std::shared_ptr<EQStream> dest, bool ack_req) {
_eqp
dest->FastQueuePacket(p, ack_req);
}
@@ -67,10 +73,12 @@ namespace StructStrategyFactory {
static std::map<EmuOpcode, const StructStrategy *> strategies;
void RegisterPatch(EmuOpcode first_opcode, const StructStrategy *structs) {
_eqp
strategies[first_opcode] = structs;
}
const StructStrategy *FindPatch(EmuOpcode first_opcode) {
_eqp
std::map<EmuOpcode, const StructStrategy *>::const_iterator res;
res = strategies.find(first_opcode);
if(res == strategies.end())
+33
View File
@@ -75,6 +75,7 @@ TCPConnection::TCPConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 ir
rIP(irIP),
rPort(irPort)
{
_eqp
pState = TCPS_Connected;
pFree = false;
pEcho = false;
@@ -90,6 +91,7 @@ TCPConnection::TCPConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 ir
}
TCPConnection::~TCPConnection() {
_eqp
FinishDisconnect();
ClearBuffers();
if (ConnectionType == Outgoing) {
@@ -113,12 +115,14 @@ TCPConnection::~TCPConnection() {
}
void TCPConnection::SetState(State_t in_state) {
_eqp
MState.lock();
pState = in_state;
MState.unlock();
}
TCPConnection::State_t TCPConnection::GetState() const {
_eqp
State_t ret;
MState.lock();
ret = pState;
@@ -128,6 +132,7 @@ TCPConnection::State_t TCPConnection::GetState() const {
bool TCPConnection::GetSockName(char *host, uint16 *port)
{
_eqp
bool result=false;
LockMutex lock(&MState);
if (!Connected())
@@ -165,11 +170,13 @@ bool TCPConnection::GetSockName(char *host, uint16 *port)
}
void TCPConnection::Free() {
_eqp
Disconnect();
pFree = true;
}
bool TCPConnection::Send(const uchar* data, int32 size) {
_eqp
if (!Connected())
return false;
if (!size)
@@ -179,6 +186,7 @@ bool TCPConnection::Send(const uchar* data, int32 size) {
}
void TCPConnection::ServerSendQueuePushEnd(const uchar* data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == nullptr) {
sendbuf = new uchar[size];
@@ -198,6 +206,7 @@ void TCPConnection::ServerSendQueuePushEnd(const uchar* data, int32 size) {
}
void TCPConnection::ServerSendQueuePushEnd(uchar** data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == 0) {
sendbuf = *data;
@@ -221,6 +230,7 @@ void TCPConnection::ServerSendQueuePushEnd(uchar** data, int32 size) {
}
void TCPConnection::ServerSendQueuePushFront(uchar* data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == 0) {
sendbuf = new uchar[size];
@@ -240,6 +250,7 @@ void TCPConnection::ServerSendQueuePushFront(uchar* data, int32 size) {
}
bool TCPConnection::ServerSendQueuePop(uchar** data, int32* size) {
_eqp
bool ret;
if (!MSendQueue.trylock())
return false;
@@ -257,6 +268,7 @@ bool TCPConnection::ServerSendQueuePop(uchar** data, int32* size) {
}
bool TCPConnection::ServerSendQueuePopForce(uchar** data, int32* size) {
_eqp
bool ret;
MSendQueue.lock();
if (sendbuf) {
@@ -273,6 +285,7 @@ bool TCPConnection::ServerSendQueuePopForce(uchar** data, int32* size) {
}
char* TCPConnection::PopLine() {
_eqp
char* ret;
if (!MLineOutQueue.trylock())
return 0;
@@ -282,6 +295,7 @@ char* TCPConnection::PopLine() {
}
bool TCPConnection::LineOutQueuePush(char* line) {
_eqp
MLineOutQueue.lock();
LineOutQueue.push(line);
MLineOutQueue.unlock();
@@ -290,6 +304,7 @@ bool TCPConnection::LineOutQueuePush(char* line) {
void TCPConnection::FinishDisconnect() {
_eqp
MState.lock();
if (connection_socket != INVALID_SOCKET && connection_socket != 0) {
if (pState == TCPS_Connected || pState == TCPS_Disconnecting || pState == TCPS_Disconnected) {
@@ -314,6 +329,7 @@ void TCPConnection::FinishDisconnect() {
}
void TCPConnection::Disconnect() {
_eqp
MState.lock();
if(pState == TCPS_Connected || pState == TCPS_Connecting) {
pState = TCPS_Disconnecting;
@@ -322,6 +338,7 @@ void TCPConnection::Disconnect() {
}
bool TCPConnection::GetAsyncConnect() {
_eqp
bool ret;
MAsyncConnect.lock();
ret = pAsyncConnect;
@@ -330,6 +347,7 @@ bool TCPConnection::GetAsyncConnect() {
}
bool TCPConnection::SetAsyncConnect(bool iValue) {
_eqp
bool ret;
MAsyncConnect.lock();
ret = pAsyncConnect;
@@ -339,6 +357,7 @@ bool TCPConnection::SetAsyncConnect(bool iValue) {
}
bool TCPConnection::ConnectReady() const {
_eqp
State_t s = GetState();
if (s != TCPS_Ready && s != TCPS_Disconnected)
return(false);
@@ -346,6 +365,7 @@ bool TCPConnection::ConnectReady() const {
}
void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) {
_eqp
safe_delete_array(charAsyncConnect);
charAsyncConnect = new char[strlen(irAddress) + 1];
strcpy(charAsyncConnect, irAddress);
@@ -353,6 +373,7 @@ void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) {
}
void TCPConnection::AsyncConnect(uint32 irIP, uint16 irPort) {
_eqp
if (ConnectionType != Outgoing) {
// If this code runs, we got serious problems
// Crash and burn.
@@ -394,6 +415,7 @@ void TCPConnection::AsyncConnect(uint32 irIP, uint16 irPort) {
}
bool TCPConnection::Connect(const char* irAddress, uint16 irPort, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
uint32 tmpIP = ResolveIP(irAddress);
@@ -411,6 +433,7 @@ bool TCPConnection::Connect(const char* irAddress, uint16 irPort, char* errbuf)
}
bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (ConnectionType != Outgoing) {
@@ -499,6 +522,7 @@ bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf) {
}
void TCPConnection::ClearBuffers() {
_eqp
LockMutex lock1(&MSendQueue);
LockMutex lock3(&MRunLoop);
LockMutex lock4(&MState);
@@ -511,6 +535,7 @@ void TCPConnection::ClearBuffers() {
}
bool TCPConnection::CheckNetActive() {
_eqp
MState.lock();
if (pState == TCPS_Connected || pState == TCPS_Disconnecting) {
MState.unlock();
@@ -523,6 +548,7 @@ bool TCPConnection::CheckNetActive() {
/* This is always called from an IO thread. Either the server socket's thread, or a
* special thread we create when we make an outbound connection. */
bool TCPConnection::Process() {
_eqp
char errbuf[TCPConnection_ErrorBufferSize];
switch(GetState()) {
case TCPS_Ready:
@@ -594,6 +620,7 @@ bool TCPConnection::Process() {
}
bool TCPConnection::RecvData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (!Connected()) {
@@ -666,16 +693,19 @@ bool TCPConnection::RecvData(char* errbuf) {
bool TCPConnection::GetEcho() {
_eqp
bool ret;
ret = pEcho;
return ret;
}
void TCPConnection::SetEcho(bool iValue) {
_eqp
pEcho = iValue;
}
bool TCPConnection::ProcessReceivedData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (!recvbuf)
@@ -810,6 +840,7 @@ bool TCPConnection::ProcessReceivedData(char* errbuf) {
}
bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
/************ Get first send packet on queue and send it! ************/
@@ -891,6 +922,7 @@ bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
}
ThreadReturnType TCPConnection::TCPConnectionLoop(void* tmp) {
_eqp
#ifdef _WINDOWS
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif
@@ -933,6 +965,7 @@ ThreadReturnType TCPConnection::TCPConnectionLoop(void* tmp) {
}
bool TCPConnection::RunLoop() {
_eqp
bool ret;
MRunLoop.lock();
ret = pRunLoop;
+9 -3
View File
@@ -24,18 +24,22 @@
Timeoutable::Timeoutable(uint32 check_frequency)
: next_check(check_frequency)
{
_eqp
timeout_manager.AddMember(this);
}
Timeoutable::~Timeoutable() {
_eqp
timeout_manager.DeleteMember(this);
}
TimeoutManager::TimeoutManager() {
_eqp
}
void TimeoutManager::CheckTimeouts() {
_eqp
std::vector<Timeoutable *>::iterator cur,end;
cur = members.begin();
end = members.end();
@@ -43,7 +47,7 @@ void TimeoutManager::CheckTimeouts() {
Timeoutable *it = *cur;
if(it->next_check.Check()) {
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None,, "Checking timeout on 0x%x\n", it);
Log.Out(Logs::General, Logs::None, "Checking timeout on 0x%x\n", it);
#endif
it->CheckTimeout();
}
@@ -52,19 +56,21 @@ void TimeoutManager::CheckTimeouts() {
//methods called by Timeoutable objects:
void TimeoutManager::AddMember(Timeoutable *who) {
_eqp
if(who == nullptr)
return;
DeleteMember(who); //just in case... prolly not needed.
members.push_back(who);
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None,, "Adding timeoutable 0x%x\n", who);
Log.Out(Logs::General, Logs::None, "Adding timeoutable 0x%x\n", who);
#endif
}
void TimeoutManager::DeleteMember(Timeoutable *who) {
_eqp
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None,, "Removing timeoutable 0x%x\n", who);
Log.Out(Logs::General, Logs::None, "Removing timeoutable 0x%x\n", who);
#endif
std::vector<Timeoutable *>::iterator cur,end;
cur = members.begin();
+1
View File
@@ -81,6 +81,7 @@ int gettimeofday (timeval *tp, ...)
/* This function checks if the timer triggered */
bool Timer::Check(bool iReset)
{
_eqp
if (enabled && current_time-start_time > timer_time) {
if (iReset) {
if (pUseAcurateTiming)
+1 -16
View File
@@ -18,6 +18,7 @@
#ifndef TYPES_H
#define TYPES_H
#include <eqp_profiler.h>
#include <stdint.h>
typedef uint8_t byte;
typedef uint8_t uint8;
@@ -83,20 +84,4 @@ typedef const char Const_char; //for perl XS
#define DLLFUNC extern "C"
#endif
// htonll and ntohll already defined on windows
#ifndef WIN32
# if defined(__linux__)
# include <endian.h>
# elif defined(__FreeBSD__) || defined(__NetBSD__)
# include <sys/endian.h>
# elif defined (__OpenBSD__)
# include <sys/types.h>
# define be16toh(x) betoh16(x)
# define be32toh(x) betoh32(x)
# define be64toh(x) betoh64(x)
# endif
# define htonll(x) htobe64(x)
# define ntohll(x) be64toh(x)
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More