Compare commits

..

15 Commits

386 changed files with 26455 additions and 98590 deletions
+8 -10
View File
@@ -1,18 +1,16 @@
language: cpp
compiler: gcc
sudo: false
addons:
apt:
packages:
- libmysqlclient-dev
- libperl-dev
- libboost-dev
- liblua5.1-0-dev
- zlib1g-dev
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev
script:
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON
- make -j8
- make
- ./bin/tests
branches:
only:
- master
- stable
notifications:
email: false
irc:
+11 -5
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,14 +333,18 @@ IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/recast/debug_utils/include")
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/recast/detour/include")
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/recast/detour_tile_cache/include")
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/recast/recast/include")
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)
ADD_SUBDIRECTORY(recast)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory)
+207 -574
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);
}
+20 -23
View File
@@ -21,12 +21,6 @@ IF(MYSQL_ROOT)
NAMES mysql.h
PATHS ${MYSQL_ROOT}/include
PATH_SUFFIXES mysql
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_PATH(MySQL_INCLUDE_DIR
NAMES mysql.h
PATH_SUFFIXES mysql
)
ELSE(MYSQL_ROOT)
FIND_PATH(MySQL_INCLUDE_DIR
@@ -36,46 +30,49 @@ ELSE(MYSQL_ROOT)
ENDIF(MYSQL_ROOT)
# Library
SET(MySQL_NAMES libmysql)
SET(MySQL_NAMES mysqlclient_r mysqlclient)
IF(MYSQL_ROOT)
FIND_LIBRARY(MySQL_LIBRARY
FIND_LIBRARY(MySQL_LIBRARY_DEBUG
NAMES ${MySQL_NAMES}
PATHS ${MYSQL_ROOT}/lib
PATHS ${MYSQL_ROOT}/lib/debug /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_LIBRARY(MySQL_LIBRARY
FIND_LIBRARY(MySQL_LIBRARY_RELEASE
NAMES ${MySQL_NAMES}
PATHS ${MYSQL_ROOT}/lib /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql
)
ELSE(MYSQL_ROOT)
FIND_LIBRARY(MySQL_LIBRARY
NAMES ${MySQL_NAMES} mysqlclient_r mysqlclient
FIND_LIBRARY(MySQL_LIBRARY_DEBUG
NAMES ${MySQL_NAMES}
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql
)
FIND_LIBRARY(MySQL_LIBRARY_RELEASE
NAMES ${MySQL_NAMES}
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql
)
ENDIF(MYSQL_ROOT)
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
SET(MySQL_FOUND TRUE)
SET( MySQL_LIBRARIES ${MySQL_LIBRARY} )
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_DEBUG} ${MySQL_LIBRARY_RELEASE} )
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
SET(MySQL_FOUND FALSE)
SET( MySQL_LIBRARIES )
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
# handle the QUIETLY and REQUIRED arguments and set MySQL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MySQL DEFAULT_MSG MySQL_LIBRARY MySQL_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MySQL DEFAULT_MSG MySQL_LIBRARY_DEBUG MySQL_LIBRARY_RELEASE MySQL_INCLUDE_DIR)
IF(MySQL_FOUND)
SET( MySQL_LIBRARY_RELEASE ${MySQL_LIBRARY} )
SET( MySQL_LIBRARY_DEBUG ${MySQL_LIBRARY} )
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_RELEASE} ${MySQL_LIBRARY_DEBUG} )
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_DEBUG} ${MySQL_LIBRARY_RELEASE} )
ELSE(MySQL_FOUND)
SET( MySQL_LIBRARIES )
ENDIF(MySQL_FOUND)
+2 -6
View File
@@ -39,7 +39,6 @@ SET(common_sources
mutex.cpp
mysql_request_result.cpp
mysql_request_row.cpp
opcode_map.cpp
opcodemgr.cpp
packet_dump.cpp
packet_dump_file.cpp
@@ -49,7 +48,6 @@ SET(common_sources
proc_launcher.cpp
ptimer.cpp
races.cpp
rdtsc.cpp
rulesys.cpp
serverinfo.cpp
shareddb.cpp
@@ -62,9 +60,9 @@ SET(common_sources
timeoutmgr.cpp
timer.cpp
unix.cpp
uuid.cpp
worldconn.cpp
xml_parser.cpp
pathfind.cpp
platform.cpp
patches/patches.cpp
patches/sod.cpp
@@ -157,15 +155,12 @@ SET(common_headers
packet_dump.h
packet_dump_file.h
packet_functions.h
pathfind.h
platform.h
proc_launcher.h
profiler.h
ptimer.h
queue.h
races.h
random.h
rdtsc.h
rulesys.h
ruletypes.h
seperator.h
@@ -184,6 +179,7 @@ SET(common_headers
types.h
unix.h
useperl.h
uuid.h
version.h
worldconn.h
xml_parser.h
-3
View File
@@ -63,12 +63,9 @@ 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 += (uint32)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; }
uint16 ReadUInt16() { uint16 value = *(uint16 *)(pBuffer + _rpos); _rpos += sizeof(uint16); return value; }
uint16 ReadUInt16(uint32 Offset) const { uint16 value = *(uint16 *)(pBuffer + Offset); return value; }
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
+25 -130
View File
@@ -1,50 +1,22 @@
/*
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
#include "types.h"
static const uint32 BIT_Client62 = 0x00000001; // 1 (unsupported - placeholder for scripts)
static const uint32 BIT_Titanium = 0x00000002; // 2
static const uint32 BIT_SoF = 0x00000004; // 4
static const uint32 BIT_SoD = 0x00000008; // 8
static const uint32 BIT_UF = 0x00000010; // 16
static const uint32 BIT_RoF = 0x00000020; // 32
static const uint32 BIT_RoF2 = 0x00000040; // 64
static const uint32 BIT_TitaniumAndEarlier = 0x00000003; // 3
static const uint32 BIT_SoFAndEarlier = 0x00000007; // 7
static const uint32 BIT_SoDAndEarlier = 0x0000000F; // 15
static const uint32 BIT_UFAndEarlier = 0x0000001F; // 31
static const uint32 BIT_RoFAndEarlier = 0x0000003F; // 63
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC; // 4294967292
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8; // 4294967288
static const uint32 BIT_UFAndLater = 0xFFFFFFF0; // 4294967280
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0; // 4294967264
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0; // 4294967232
static const uint32 BIT_Client62 = 1;
static const uint32 BIT_Titanium = 2;
static const uint32 BIT_SoF = 4;
static const uint32 BIT_SoD = 8;
static const uint32 BIT_UF = 16;
static const uint32 BIT_RoF = 32;
static const uint32 BIT_RoF2 = 64;
static const uint32 BIT_TitaniumAndEarlier = 0x00000003;
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC;
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8;
static const uint32 BIT_UFAndLater = 0xFFFFFFF0;
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
static const uint32 BIT_AllClients = 0xFFFFFFFF;
enum class ClientVersion
@@ -74,109 +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;
}
}
static uint32 ExpansionFromClientVersion(ClientVersion clientVersion)
{
switch(clientVersion)
{
case ClientVersion::Unknown:
case ClientVersion::Client62:
case ClientVersion::Titanium:
return 0x000007FFU;
case ClientVersion::SoF:
return 0x00007FFFU;
case ClientVersion::SoD:
return 0x0000FFFFU;
case ClientVersion::UF:
return 0x0001FFFFU;
case ClientVersion::RoF:
case ClientVersion::RoF2:
return 0x000FFFFFU;
default:
return 0;
}
}
#endif /* CLIENTVERSIONS_H */
+108 -81
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)");
@@ -348,17 +364,18 @@ bool Database::DeleteCharacter(char *name) {
query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
#ifdef BOTS
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); // note: only use of GetMobTypeById()
#else
#ifdef BOTS
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid);
#else
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d'", charid);
#endif
#endif
QueryDatabase(query);
return true;
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
_eqp
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -678,6 +695,7 @@ 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, 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,18 +1212,24 @@ uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
bool Database::CheckNameFilter(const char* name, bool surname)
{
_eqp
std::string str_name = name;
// the minimum 4 is enforced by the client too
if (!name || strlen(name) < 4)
if(surname)
{
return false;
// the minimum 4 is enforced by the client too
if(!name || strlen(name) < 3)
{
return false;
}
}
// Given name length is enforced by the client too
if (!surname && strlen(name) > 15)
else
{
return false;
// the minimum 4 is enforced by the client too
if(!name || strlen(name) < 4 || strlen(name) > 15)
{
return false;
}
}
for (size_t i = 0; i < str_name.size(); i++)
@@ -1252,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);
@@ -1268,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);
@@ -1292,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);
@@ -1312,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);
@@ -1331,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()) {
@@ -1344,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()) {
@@ -1358,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;
@@ -1375,11 +1418,13 @@ 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) {
std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", GetZoneID(iZonename), iCharID);
_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);
if (!results.Success()) {
@@ -1390,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);
@@ -1401,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);
@@ -1415,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!
@@ -1433,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;
@@ -1482,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);
@@ -1505,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);
@@ -1517,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);
@@ -1536,35 +1586,41 @@ 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());
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", EscapeString(who).c_str(), EscapeString(against).c_str(), escape_str);
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str);
QueryDatabase(query);
safe_delete_array(escape_str);
}
void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc) {
_eqp
std::string query;
if (id == 0) {
// removing from group
@@ -1584,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)
@@ -1605,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);
@@ -1615,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;
}
@@ -1626,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;
@@ -1650,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);
@@ -1668,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);
@@ -1727,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);
@@ -1737,7 +1800,7 @@ void Database::ClearAllGroupLeaders(void) {
}
void Database::ClearGroupLeader(uint32 gid) {
_eqp
if(gid == 0)
{
ClearAllGroupLeaders();
@@ -1752,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);
@@ -1768,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
@@ -1789,7 +1854,7 @@ void Database::ClearRaid(uint32 rid) {
}
void Database::ClearAllRaids(void) {
_eqp
std::string query("delete from raid_members");
auto results = QueryDatabase(query);
@@ -1799,7 +1864,7 @@ void Database::ClearAllRaids(void) {
void Database::ClearAllRaidDetails(void)
{
_eqp
std::string query("delete from raid_details");
auto results = QueryDatabase(query);
@@ -1808,7 +1873,7 @@ void Database::ClearAllRaidDetails(void)
}
void Database::ClearRaidDetails(uint32 rid) {
_eqp
if(rid == 0)
{
//clear all raids
@@ -1827,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);
@@ -1848,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
@@ -1879,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);
@@ -1936,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);
@@ -1979,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);
@@ -1996,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;
@@ -2003,6 +2074,7 @@ void Database::ClearAllRaidLeaders(void)
void Database::ClearRaidLeader(uint32 gid, uint32 rid)
{
_eqp
if (rid == 0) {
ClearAllRaidLeaders();
return;
@@ -2014,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)
@@ -2067,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`, "
@@ -2113,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);
@@ -2128,6 +2202,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings)
{
_eqp
std::string query =
"SELECT "
"log_category_id, "
@@ -2168,51 +2243,3 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings)
}
}
}
void Database::ClearInvSnapshots(bool use_rule)
{
uint32 del_time = time(nullptr);
if (use_rule) { del_time -= RuleI(Character, InvSnapshotHistoryD) * 86400; }
std::string query = StringFormat("DELETE FROM inventory_snapshots WHERE time_index <= %lu", (unsigned long)del_time);
QueryDatabase(query);
}
struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
{
TimeOfDay_Struct eqTime;
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
auto results = QueryDatabase(query);
if (!results.Success() || results.RowCount() == 0){
Log.Out(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults.");
eqTime.minute = 0;
eqTime.hour = 9;
eqTime.day = 1;
eqTime.month = 1;
eqTime.year = 3100;
realtime = time(0);
}
else{
auto row = results.begin();
eqTime.minute = atoi(row[0]);
eqTime.hour = atoi(row[1]);
eqTime.day = atoi(row[2]);
eqTime.month = atoi(row[3]);
eqTime.year = atoi(row[4]);
realtime = atoi(row[5]);
}
return eqTime;
}
bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year)
{
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(0));
auto results = QueryDatabase(query);
return results.Success();
}
+1 -5
View File
@@ -23,7 +23,6 @@
#include "global_define.h"
#include "eqemu_logsys.h"
#include "types.h"
#include "dbcore.h"
#include "linked_list.h"
@@ -210,6 +209,7 @@ public:
/* Database Conversions 'database_conversions.cpp' */
bool CheckDatabaseConversions();
bool CheckDatabaseConvertBotsPostPPDeblob();
bool CheckDatabaseConvertCorpseDeblob();
bool CheckDatabaseConvertPPDeblob();
@@ -241,8 +241,6 @@ public:
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
void AddReport(std::string who, std::string against, std::string lines);
struct TimeOfDay_Struct LoadTime(time_t &realtime);
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp();
void ClearPTimers(uint32 charid);
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
@@ -250,8 +248,6 @@ public:
void SetLFP(uint32 CharID, bool LFP);
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
void ClearInvSnapshots(bool use_rule = true);
/* EQEmuLogSys */
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
+176 -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;
@@ -470,6 +459,7 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50)
bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertPPDeblob();
CheckDatabaseConvertBotsPostPPDeblob();
CheckDatabaseConvertCorpseDeblob();
/* Fetch Automatic Upgrade Script */
@@ -493,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 14");
system("perl eqemu_update.pl V 2");
/* Run Automatic Database Upgrade Script */
system("perl eqemu_update.pl ran_from_world");
@@ -1440,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);
}
}
}
@@ -1456,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);
}
}
@@ -1490,6 +1480,163 @@ bool Database::CheckDatabaseConvertPPDeblob(){
return true;
}
bool Database::CheckDatabaseConvertBotsPostPPDeblob(){
#ifdef BOTS
int runbotsconvert = 0;
/* Check For Legacy Bot References */
std::string rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`");
auto results = QueryDatabase(rquery);
if (results.RowCount() == 1){
auto row = results.begin();
std::string table_check = row[1];
if (table_check.find("character_data") == -1){
runbotsconvert = 1;
printf("\n\n::: Legacy Bot Views and Function Detected... \n");
printf("----------------------------------------------------------\n\n");
printf(" Database currently has bot view/function linkage to obselete \n");
printf(" table references and will now be converted...\n\n");
printf(" It is recommended that you backup your database \n");
printf(" before continuing the automatic conversion process...\n\n");
printf("----------------------------------------------------------\n\n");
std::cout << "Press ENTER to continue....." << std::endl << std::endl;
std::cin.ignore(1);
}
}
if (runbotsconvert == 1){
printf("Running bot views/function database conversion... \n");
/* Update view `vwbotcharactermobs` */
rquery = StringFormat("DROP VIEW `vwBotCharacterMobs`;");
results = QueryDatabase(rquery);
rquery = StringFormat(
"CREATE VIEW `vwBotCharacterMobs` AS\n"
"SELECT _utf8'C' AS mobtype,\n" // Natedog: '_utf8'
"c.`id`,\n"
"c.`name`,\n"
"c.`class`,\n"
"c.`level`,\n"
"c.`last_login`,\n"
"c.`zone_id`\n"
"FROM `character_data` AS c\n"
"UNION ALL\n"
"SELECT _utf8'B' AS mobtype,\n" // Natedog: '_utf8'
"b.`BotID` AS id,\n"
"b.`Name` AS name,\n"
"b.`Class` AS class,\n"
"b.`BotLevel` AS level,\n"
"0 AS timelaston,\n"
"0 AS zoneid\n"
"FROM bots AS b;"
);
results = QueryDatabase(rquery);
/* Update function `GetMobType` */
rquery = StringFormat("DROP FUNCTION IF EXISTS `GetMobType`;");
results = QueryDatabase(rquery);
rquery = StringFormat(
"CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)\n"
"BEGIN\n"
" DECLARE Result CHAR(1);\n"
"\n"
" SET Result = NULL;\n"
"\n"
" IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN\n"
" SET Result = 'C';\n"
" ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN\n"
" SET Result = 'B';\n"
" END IF;\n "
"\n"
" RETURN Result;\n"
"END"
);
results = QueryDatabase(rquery);
/* Update view `vwgroups` */
rquery = StringFormat("DROP VIEW IF EXISTS `vwGroups`;");
results = QueryDatabase(rquery);
rquery = StringFormat(
"CREATE VIEW `vwGroups` AS\n"
"SELECT g.`groupid` AS groupid,\n"
"GetMobType(g.`name`) AS mobtype,\n"
"g.`name` AS name,\n"
"g.`charid` AS mobid,\n"
"IFNULL(c.`level`, b.`BotLevel`) AS level\n"
"FROM `group_id` AS g\n"
"LEFT JOIN `character_data` AS c ON g.`name` = c.`name`\n"
"LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;"
);
results = QueryDatabase(rquery);
/* Update view `vwbotgroups` */
rquery = StringFormat("DROP VIEW IF EXISTS `vwBotGroups`;");
results = QueryDatabase(rquery);
rquery = StringFormat(
"CREATE VIEW `vwBotGroups` AS\n"
"SELECT g.`BotGroupId`,\n"
"g.`BotGroupName`,\n"
"g.`BotGroupLeaderBotId`,\n"
"b.`Name` AS BotGroupLeaderName,\n"
"b.`BotOwnerCharacterId`,\n"
"c.`name` AS BotOwnerCharacterName\n"
"FROM `botgroup` AS g\n"
"JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`\n"
"JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`\n"
"ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;"
);
results = QueryDatabase(rquery);
/* Update view `vwguildmembers` */
rquery = StringFormat("DROP VIEW IF EXISTS `vwGuildMembers`;");
results = QueryDatabase(rquery);
rquery = StringFormat(
"CREATE VIEW `vwGuildMembers` AS\n"
"SELECT 'C' AS mobtype,\n"
"cm.`char_id`,\n"
"cm.`guild_id`,\n"
"cm.`rank`,\n"
"cm.`tribute_enable`,\n"
"cm.`total_tribute`,\n"
"cm.`last_tribute`,\n"
"cm.`banker`,\n"
"cm.`public_note`,\n"
"cm.`alt`\n"
"FROM `guild_members` AS cm\n"
"UNION ALL\n"
"SELECT 'B' AS mobtype,\n"
"bm.`char_id`,\n"
"bm.`guild_id`,\n"
"bm.`rank`,\n"
"bm.`tribute_enable`,\n"
"bm.`total_tribute`,\n"
"bm.`last_tribute`,\n"
"bm.`banker`,\n"
"bm.`public_note`,\n"
"bm.`alt`\n"
"FROM `botguildmembers` AS bm;"
);
results = QueryDatabase(rquery);
}
if (runbotsconvert == 1){
printf("\n\nBot views/function conversion complete, continuing world bootup...\n");
}
#endif
return true;
}
bool Database::CheckDatabaseConvertCorpseDeblob(){
Convert::DBPlayerCorpse_Struct_temp* dbpc;
Convert::classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c;
+1 -6
View File
@@ -128,12 +128,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
if (Log.log_settings[Logs::MySQLQuery].is_category_enabled == 1)
{
if ((strncasecmp(query, "select", 6) == 0))
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
else
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
}
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u rows returned)", query, rowCount, requestResult.RowCount());
return requestResult;
}
+2 -7
View File
@@ -215,7 +215,6 @@ N(OP_GroupUpdate),
N(OP_GroupUpdateB),
N(OP_GroupUpdateLeaderAA),
N(OP_GuildBank),
N(OP_GuildBankItemList),
N(OP_GuildCreate),
N(OP_GuildDelete),
N(OP_GuildDemote),
@@ -349,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),
@@ -366,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),
@@ -523,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),
@@ -536,8 +534,6 @@ N(OP_WorldLogout),
N(OP_WorldObjectsSent),
N(OP_WorldUnknown001),
N(OP_XTargetAutoAddHaters),
N(OP_XTargetOpen),
N(OP_XTargetOpenResponse),
N(OP_XTargetRequest),
N(OP_XTargetResponse),
N(OP_YellForHelp),
@@ -551,5 +547,4 @@ N(OP_ZoneServerInfo),
N(OP_ZoneServerReady),
N(OP_ZoneSpawns),
N(OP_ZoneUnavail),
N(OP_ResetAA),
// mail and chat opcodes located in ../mail_oplist.h
+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();
+1 -48
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
{
+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();
}
}
+174 -248
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
@@ -124,81 +123,83 @@ struct LDoNTrapTemplate
///////////////////////////////////////////////////////////////////////////////
// All clients translate the character select information to some degree
/*
** 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*/
};
/*
@@ -273,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
@@ -367,11 +367,6 @@ union
};
struct PlayerState_Struct {
/*00*/ uint32 spawn_id;
/*04*/ uint32 state;
};
/*
** New Spawn
** Length: 176 Bytes
@@ -553,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*/
@@ -566,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;
@@ -584,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;
};
@@ -726,7 +727,6 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges;
};
@@ -756,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;
@@ -1120,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;
@@ -1161,7 +1144,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
/*004*/ uint32 unknown;
};
/*
@@ -1266,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;
@@ -1280,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*/
};
@@ -1319,10 +1302,10 @@ 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;
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 11 */ uint32 unknown11;
/* 15 */ uint32 sequence; // see above notes in Action_Struct
/* 19 */ uint32 unknown19;
/* 23 */
};
/*
@@ -2149,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
@@ -2422,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*/
@@ -2535,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; //
@@ -2554,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
@@ -2612,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
@@ -2778,8 +2761,7 @@ struct BazaarWelcome_Struct {
BazaarWindowStart_Struct Beginning;
uint32 Traders;
uint32 Items;
uint32 Unknown012;
uint32 Unknown016;
uint8 Unknown012[8];
};
struct BazaarSearch_Struct {
@@ -3164,7 +3146,6 @@ struct Trader_ShowItems_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Unknown08[3];
/*020*/
};
struct TraderBuy_Struct{
@@ -3210,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{
@@ -4031,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 {
@@ -4124,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 {
@@ -4219,52 +4194,6 @@ struct UseAA_Struct {
uint32 end;
};
//new AA stuff
//reference only
struct AARankInfo_Struct
{
uint32 id;
int32 upper_hotkey_sid;
int32 lower_hotkey_sid;
int32 title_sid;
int32 desc_sid;
int32 level_req;
int32 cost;
uint32 seq;
uint32 current_level;
uint32 type;
int32 spell;
int32 spell_type;
int32 spell_refresh;
int32 classes;
int32 max_level;
int32 prev_id;
int32 next_id;
int32 total_cost;
int32 expansion;
int32 category;
uint32 charges;
uint8 grant_only;
uint32 total_effects;
uint32 total_prereqs;
};
struct AARankPrereq_Struct
{
int32 aa_id;
int32 points;
};
struct AARankEffect_Struct
{
int32 effect_id;
int32 base1;
int32 base2;
int32 slot;
};
//old AA stuff
struct AA_Ability {
/*00*/ uint32 skill_id;
/*04*/ uint32 base1;
@@ -4319,10 +4248,18 @@ struct SendAA_Struct {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*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;
@@ -4340,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 {
@@ -4593,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
@@ -4724,22 +4668,6 @@ struct GuildBankItemUpdate_Struct
/*226*/ uint16 Unknown226;
};
// newer clients (RoF+) send a list that contains 240 entries
// The packets don't actually use all 64 chars in the strings, but we'll just overallocate for these
struct GuildBankItemListEntry_Struct
{
uint8 vaild;
uint32 permissions;
char whofor[64];
char donator[64];
uint32 item_id;
uint32 item_icon;
uint32 quantity;
uint8 allow_merge; // 1 here for non-full stacks
uint8 usable;
char item_name[64];
};
struct GuildBankClear_Struct
{
/*00*/ uint32 Action;
@@ -4786,7 +4714,7 @@ struct BuffIconEntry_Struct
{
uint32 buff_slot;
uint32 spell_id;
int32 tics_remaining;
uint32 tics_remaining;
uint32 num_hits;
};
@@ -4795,8 +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
int32 tic_timer;
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;
+19
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) {
@@ -254,10 +261,15 @@ void EQEmuConfig::do_files(TiXmlElement *ele)
if (text) {
OpCodesFile = text;
}
text = ParseTextBlock(ele, "eqtime", true);
if (text) {
EQTimeFile = text;
}
}
void EQEmuConfig::do_directories(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "maps", true);
if (text) {
@@ -275,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);
@@ -314,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);
}
@@ -404,6 +418,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "OpCodesFile") {
return (OpCodesFile);
}
if (var_name == "EQTimeFile") {
return (EQTimeFile);
}
if (var_name == "MapDir") {
return (MapDir);
}
@@ -438,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;
@@ -468,6 +486,7 @@ void EQEmuConfig::Dump() const
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
std::cout << "SpellsFile = " << SpellsFile << std::endl;
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
std::cout << "EQTimeFile = " << EQTimeFile << std::endl;
std::cout << "MapDir = " << MapDir << std::endl;
std::cout << "QuestDir = " << QuestDir << std::endl;
std::cout << "PluginDir = " << PluginDir << std::endl;
+2
View File
@@ -79,6 +79,7 @@ class EQEmuConfig : public XMLParser
// From <files/>
std::string SpellsFile;
std::string OpCodesFile;
std::string EQTimeFile;
// From <directories/>
std::string MapDir;
@@ -153,6 +154,7 @@ class EQEmuConfig : public XMLParser
// Files
SpellsFile = "spells_us.txt";
OpCodesFile = "opcodes.conf";
EQTimeFile = "eqtime.cfg";
// Dirs
MapDir = "Maps";
QuestDir = "quests";
+36 -26
View File
@@ -96,13 +96,13 @@ 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;
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
log_settings[Logs::Crash].log_to_console = Logs::General;
log_settings[Logs::MySQLError].log_to_console = Logs::General;
log_settings[Logs::Login_Server].log_to_console = Logs::General;
/* Declare process file names for log writing
If there is no process_file_name declared, no log file will be written, simply
@@ -123,21 +123,26 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
{
std::string ret;
ret.push_back('[');
ret.append(Logs::LogCategoryName[log_category]);
ret.push_back(']');
ret.push_back(' ');
ret.append(in_message);
return ret;
std::string category_string;
if (log_category > 0 && Logs::LogCategoryName[log_category])
category_string = StringFormat("[%s] ", Logs::LogCategoryName[log_category]);
return StringFormat("%s%s", category_string.c_str(), in_message.c_str());
}
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
{
/* Check if category enabled for process */
if (log_settings[log_category].log_to_gmsay == 0)
return;
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
if (log_category == Logs::LogCategory::Netcode)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_gmsay < debug_level)
return;
/* Check to see if the process that actually ran this is zone */
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
on_log_gmsay_hook(log_category, message);
@@ -155,6 +160,14 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
crash_log.close();
}
/* Check if category enabled for process */
if (log_settings[log_category].log_to_file == 0)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_file < debug_level)
return;
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
@@ -233,6 +246,13 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
{
/* Check if category enabled for process */
if (log_settings[log_category].log_to_console == 0)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_console < debug_level)
return;
#ifdef _WINDOWS
HANDLE console_handle;
@@ -253,32 +273,22 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
}
bool log_to_file = true;
if (log_settings[log_category].log_to_file < debug_level) {
log_to_file = false;
}
bool log_to_gmsay = true;
if (log_settings[log_category].log_to_gmsay < debug_level) {
log_to_gmsay = false;
}
_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)
if (nothing_to_log)
return;
va_list args;
va_start(args, message);
std::string output_message = vStringFormat(message.c_str(), args);
va_end(args);
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
+6 -4
View File
@@ -48,12 +48,14 @@ namespace Logs {
Combat,
Commands,
Crash,
Database,
Debug,
Doors,
Error,
Guilds,
Inventory,
Launcher,
LoginServer,
Netcode,
Normal,
Object,
@@ -82,7 +84,6 @@ namespace Logs {
Client_Server_Packet_Unhandled,
Server_Client_Packet_With_Dump,
Client_Server_Packet_With_Dump,
Login_Server,
MaxCategoryID /* Don't Remove this*/
};
@@ -97,12 +98,14 @@ namespace Logs {
"Combat",
"Commands",
"Crash",
"Database",
"Debug",
"Doors",
"Error",
"Guilds",
"Inventory",
"Launcher",
"LoginServer",
"Netcode",
"Normal",
"Object",
@@ -123,15 +126,14 @@ namespace Logs {
"WebInterface Server",
"World Server",
"Zone Server",
"MySQL Error",
"MySQL Query",
"MySQLError",
"MySQLQuery",
"Mercenaries",
"Quest Debug",
"Packet :: Server -> Client",
"Packet :: Client -> Server Unhandled",
"Packet :: Server -> Client (Dump)",
"Packet :: Client -> Server (Dump)",
"Login Server"
};
}
+107 -40
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,34 +124,100 @@ 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;
}
//saveFile and loadFile need to use long for the save datatype...
//For some reason, ifstream/ofstream have problems with EQEmu datatypes in files.
bool EQTime::saveFile(const char *filename)
{
std::ofstream of;
of.open(filename);
if(!of)
{
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
return false;
}
//Enable for debugging
of << EQT_VERSION << std::endl;
of << (long)eqTime.start_eqtime.day << std::endl;
of << (long)eqTime.start_eqtime.hour << std::endl;
of << (long)eqTime.start_eqtime.minute << std::endl;
of << (long)eqTime.start_eqtime.month << std::endl;
of << eqTime.start_eqtime.year << std::endl;
of << eqTime.start_realtime << std::endl;
of.close();
return true;
}
bool EQTime::loadFile(const char *filename)
{
int version=0;
long in_data=0;
std::ifstream in;
in.open(filename);
if(!in)
{
Log.Out(Logs::General, Logs::Error, "Could not load EQTime file %s", filename);
return false;
}
in >> version;
in.ignore(80, '\n');
if(version != EQT_VERSION)
{
Log.Out(Logs::General, Logs::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION);
return false;
}
//in >> eqTime.start_eqtime.day;
in >> in_data;
in.ignore(80, '\n');
eqTime.start_eqtime.day = in_data;
//in >> eqTime.start_eqtime.hour;
in >> in_data;
eqTime.start_eqtime.hour = in_data;
in.ignore(80, '\n');
//in >> eqTime.start_eqtime.minute;
in >> in_data;
in.ignore(80, '\n');
eqTime.start_eqtime.minute = in_data;
//in >> eqTime.start_eqtime.month;
in >> in_data;
in.ignore(80, '\n');
eqTime.start_eqtime.month = in_data;
in >> eqTime.start_eqtime.year;
in.ignore(80, '\n');
in >> eqTime.start_realtime;
//Enable for debugging...
in.close();
return true;
}
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);
@@ -164,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;
}
@@ -172,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) {
@@ -203,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;
}
}
+9 -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
@@ -39,6 +39,12 @@ public:
static void ToString(TimeOfDay_Struct *t, std::string &str);
//Database functions
//bool loadDB(Database q);
//bool setDB(Database q);
bool loadFile(const char *filename);
bool saveFile(const char *filename);
private:
//This is our reference clock.
eqTimeOfDay eqTime;
+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);
-2
View File
@@ -54,8 +54,6 @@ struct ExtendedProfile_Struct {
uint32 mercTimerRemaining; /* Not Used */
uint8 mercGender; /* Not Used */
int32 mercState; /* Not Used */
uint32 last_invsnapshot_time; /* Used */
uint32 next_invsnapshot_time; /* Used */
};
#pragma pack()
+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;
}
+1 -7
View File
@@ -154,12 +154,11 @@ enum { //reuse times
enum { //timer settings, all in milliseconds
AImovement_duration = 100,
AIthink_duration = 150,
AIscanarea_delay = 6000,
AIscanarea_delay = 500,
AIfeignremember_delay = 500,
AItarget_check_duration = 500,
AIClientScanarea_delay = 750, //used in REVERSE_AGGRO
AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help
AI_check_signal_timer_delay = 500, // How often EVENT_SIGNAL checks are processed
ClientProximity_interval = 150,
CombatEventTimer_expire = 12000,
Tribute_duration = 600000,
@@ -233,8 +232,6 @@ enum { //some random constants
#define GROUP_EXP_PER_POINT 1000
#define RAID_EXP_PER_POINT 2000
#define ZONE_CONTROLLER_NPC_ID 10
//Some hard coded statuses from commands and other places:
enum {
minStatusToBeGM = 40,
@@ -273,9 +270,6 @@ enum {
#define NPC_DEFAULT_LOGGING_ENABLED false
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
#define SAYLINK_ITEM_ID 0xFFFFF
/*
+66 -12
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);
@@ -867,18 +899,19 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
//factored out so I dont have to copy this crap.
#ifdef BOTS
#define GuildMemberBaseQuery \
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
" g.`banker`, g.`public_note`, g.`alt`" \
" FROM `vw_bot_character_mobs` AS c LEFT JOIN `vw_guild_members` AS g ON c.`id` = g.`char_id` AND c.`mob_type` = g.`mob_type` "
"SELECT c.id,c.name,c.class,c.level,c.timelaston,c.zoneid," \
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
" g.banker,g.public_note,g.alt" \
" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype "
#else
#define GuildMemberBaseQuery \
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
" g.`banker`, g.`public_note`, g.`alt` " \
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
" g.banker,g.public_note,g.alt " \
" 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;
@@ -969,7 +1005,7 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
//load up the rank info for each guild.
std::string query;
#ifdef BOTS
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C'", char_id);
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mobtype = 'C'", char_id);
#else
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d", char_id);
#endif
@@ -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);
+19 -809
View File
@@ -660,7 +660,7 @@ 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 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;
@@ -993,43 +993,34 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
return INVALID_INDEX;
}
uint8 Inventory::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 Inventory::dumpEntireInventory() {
@@ -1195,7 +1186,7 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
// Internal Method: Checks an inventory bucket for a particular item
int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity)
{
uint32 quantity_found = 0;
uint8 quantity_found = 0;
for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) {
auto inst = iter->second;
@@ -1241,9 +1232,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
// 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
uint32 quantity_found = 0;
uint8 quantity_found = 0;
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
auto inst = *iter;
@@ -1288,7 +1279,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
// Internal Method: Checks an inventory bucket for a particular item
int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity)
{
uint32 quantity_found = 0;
uint8 quantity_found = 0;
for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) {
auto inst = iter->second;
@@ -1320,7 +1311,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
// Internal Method: Checks an inventory queue type bucket for a particular item
int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
{
uint32 quantity_found = 0;
uint8 quantity_found = 0;
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
auto inst = *iter;
@@ -1440,11 +1431,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
//
ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new Item_Struct(*item);
} else {
m_item = nullptr;
}
m_item = item;
m_charges = charges;
m_price = 0;
m_attuned = false;
@@ -1471,13 +1458,6 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
m_item = new Item_Struct(*m_item);
}
else {
m_item = nullptr;
}
m_charges = charges;
m_price = 0;
m_merchantslot = 0;
@@ -1526,11 +1506,7 @@ ItemInst::ItemInst(ItemInstTypes use_type) {
ItemInst::ItemInst(const ItemInst& copy)
{
m_use_type=copy.m_use_type;
if(copy.m_item)
m_item = new Item_Struct(*copy.m_item);
else
m_item = nullptr;
m_item=copy.m_item;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
@@ -1583,7 +1559,6 @@ ItemInst::ItemInst(const ItemInst& copy)
ItemInst::~ItemInst()
{
Clear();
safe_delete(m_item);
safe_delete(m_scaledItem);
safe_delete(m_evolveInfo);
}
@@ -2173,7 +2148,7 @@ 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 (Inventory::SupportsContainers(slot_id)) { return true; }
else if (m_item->Slots & (1 << slot_id)) { return true; }
@@ -2322,708 +2297,6 @@ void ItemInst::ClearTimers() {
m_timers.clear();
}
int ItemInst::GetItemArmorClass(bool augments) const
{
int ac = 0;
const auto item = GetItem();
if (item) {
ac = item->AC;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
ac += GetAugment(i)->GetItemArmorClass();
}
return ac;
}
int ItemInst::GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments) const
{
const auto item = GetItem();
if (item) {
switch (item->ElemDmgType) {
case RESIST_MAGIC:
magic += item->ElemDmgAmt;
break;
case RESIST_FIRE:
fire += item->ElemDmgAmt;
break;
case RESIST_COLD:
cold += item->ElemDmgAmt;
break;
case RESIST_POISON:
poison += item->ElemDmgAmt;
break;
case RESIST_DISEASE:
disease += item->ElemDmgAmt;
break;
case RESIST_CHROMATIC:
chromatic += item->ElemDmgAmt;
break;
case RESIST_PRISMATIC:
prismatic += item->ElemDmgAmt;
break;
case RESIST_PHYSICAL:
physical += item->ElemDmgAmt;
break;
case RESIST_CORRUPTION:
corruption += item->ElemDmgAmt;
break;
}
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
GetAugment(i)->GetItemElementalDamage(magic, fire, cold, poison, disease, chromatic, prismatic, physical, corruption);
}
return magic + fire + cold + poison + disease + chromatic + prismatic + physical + corruption;
}
int ItemInst::GetItemElementalFlag(bool augments) const
{
int flag = 0;
const auto item = GetItem();
if (item) {
flag = item->ElemDmgType;
if (flag)
return flag;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) {
if (GetAugment(i))
flag = GetAugment(i)->GetItemElementalFlag();
if (flag)
return flag;
}
}
}
return flag;
}
int ItemInst::GetItemElementalDamage(bool augments) const
{
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->ElemDmgAmt;
if (damage)
return damage;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) {
if (GetAugment(i))
damage = GetAugment(i)->GetItemElementalDamage();
if (damage)
return damage;
}
}
}
return damage;
}
int ItemInst::GetItemRecommendedLevel(bool augments) const
{
int level = 0;
const auto item = GetItem();
if (item) {
level = item->RecLevel;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) {
int temp = 0;
if (GetAugment(i)) {
temp = GetAugment(i)->GetItemRecommendedLevel();
if (temp > level)
level = temp;
}
}
}
}
return level;
}
int ItemInst::GetItemRequiredLevel(bool augments) const
{
int level = 0;
const auto item = GetItem();
if (item) {
level = item->ReqLevel;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) {
int temp = 0;
if (GetAugment(i)) {
temp = GetAugment(i)->GetItemRequiredLevel();
if (temp > level)
level = temp;
}
}
}
}
return level;
}
int ItemInst::GetItemWeaponDamage(bool augments) const
{
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->Damage;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
damage += GetAugment(i)->GetItemWeaponDamage();
}
}
return damage;
}
int ItemInst::GetItemBackstabDamage(bool augments) const
{
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->BackstabDmg;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
damage += GetAugment(i)->GetItemBackstabDamage();
}
}
return damage;
}
int ItemInst::GetItemBaneDamageBody(bool augments) const
{
int body = 0;
const auto item = GetItem();
if (item) {
body = item->BaneDmgBody;
if (body)
return body;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i)) {
body = GetAugment(i)->GetItemBaneDamageBody();
if (body)
return body;
}
}
}
return body;
}
int ItemInst::GetItemBaneDamageRace(bool augments) const
{
int race = 0;
const auto item = GetItem();
if (item) {
race = item->BaneDmgRace;
if (race)
return race;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i)) {
race = GetAugment(i)->GetItemBaneDamageRace();
if (race)
return race;
}
}
}
return race;
}
int ItemInst::GetItemBaneDamageBody(bodyType against, bool augments) const
{
int damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgBody == against)
damage += item->BaneDmgAmt;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
damage += GetAugment(i)->GetItemBaneDamageBody(against);
}
}
return damage;
}
int ItemInst::GetItemBaneDamageRace(uint16 against, bool augments) const
{
int damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgRace == against)
damage += item->BaneDmgRaceAmt;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
damage += GetAugment(i)->GetItemBaneDamageRace(against);
}
}
return damage;
}
int ItemInst::GetItemMagical(bool augments) const
{
const auto item = GetItem();
if (item) {
if (item->Magic)
return 1;
if (augments) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i) && GetAugment(i)->GetItemMagical())
return 1;
}
}
return 0;
}
int ItemInst::GetItemHP(bool augments) const
{
int hp = 0;
const auto item = GetItem();
if (item) {
hp = item->HP;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
hp += GetAugment(i)->GetItemHP();
}
return hp;
}
int ItemInst::GetItemMana(bool augments) const
{
int mana = 0;
const auto item = GetItem();
if (item) {
mana = item->Mana;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
mana += GetAugment(i)->GetItemMana();
}
return mana;
}
int ItemInst::GetItemEndur(bool augments) const
{
int endur = 0;
const auto item = GetItem();
if (item) {
endur = item->Endur;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
endur += GetAugment(i)->GetItemEndur();
}
return endur;
}
int ItemInst::GetItemAttack(bool augments) const
{
int atk = 0;
const auto item = GetItem();
if (item) {
atk = item->Attack;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
atk += GetAugment(i)->GetItemAttack();
}
return atk;
}
int ItemInst::GetItemStr(bool augments) const
{
int str = 0;
const auto item = GetItem();
if (item) {
str = item->AStr;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
str += GetAugment(i)->GetItemStr();
}
return str;
}
int ItemInst::GetItemSta(bool augments) const
{
int sta = 0;
const auto item = GetItem();
if (item) {
sta = item->ASta;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
sta += GetAugment(i)->GetItemSta();
}
return sta;
}
int ItemInst::GetItemDex(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->ADex;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemDex();
}
return total;
}
int ItemInst::GetItemAgi(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->AAgi;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemAgi();
}
return total;
}
int ItemInst::GetItemInt(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->AInt;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemInt();
}
return total;
}
int ItemInst::GetItemWis(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->AWis;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemWis();
}
return total;
}
int ItemInst::GetItemCha(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->ACha;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemCha();
}
return total;
}
int ItemInst::GetItemMR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->MR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemMR();
}
return total;
}
int ItemInst::GetItemFR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->FR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemFR();
}
return total;
}
int ItemInst::GetItemCR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->CR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemCR();
}
return total;
}
int ItemInst::GetItemPR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->PR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemPR();
}
return total;
}
int ItemInst::GetItemDR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->DR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemDR();
}
return total;
}
int ItemInst::GetItemCorrup(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->SVCorruption;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemCorrup();
}
return total;
}
int ItemInst::GetItemHeroicStr(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicStr;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicStr();
}
return total;
}
int ItemInst::GetItemHeroicSta(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicSta;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicSta();
}
return total;
}
int ItemInst::GetItemHeroicDex(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicDex;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicDex();
}
return total;
}
int ItemInst::GetItemHeroicAgi(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicAgi;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicAgi();
}
return total;
}
int ItemInst::GetItemHeroicInt(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicInt;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicInt();
}
return total;
}
int ItemInst::GetItemHeroicWis(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicWis;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicWis();
}
return total;
}
int ItemInst::GetItemHeroicCha(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicCha;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicCha();
}
return total;
}
int ItemInst::GetItemHeroicMR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicMR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicMR();
}
return total;
}
int ItemInst::GetItemHeroicFR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicFR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicFR();
}
return total;
}
int ItemInst::GetItemHeroicCR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicCR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicCR();
}
return total;
}
int ItemInst::GetItemHeroicPR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicPR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicPR();
}
return total;
}
int ItemInst::GetItemHeroicDR(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicDR;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicDR();
}
return total;
}
int ItemInst::GetItemHeroicCorrup(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->HeroicSVCorrup;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i))
total += GetAugment(i)->GetItemHeroicCorrup();
}
return total;
}
int ItemInst::GetItemHaste(bool augments) const
{
int total = 0;
const auto item = GetItem();
if (item) {
total = item->Haste;
if (augments)
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugment(i)) {
int temp = GetAugment(i)->GetItemHaste();
if (temp > total)
total = temp;
}
}
return total;
}
//
// class EvolveInfo
@@ -3088,66 +2361,3 @@ bool Item_Struct::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 lightTypeCandle:
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]);
}
+1 -93
View File
@@ -29,7 +29,6 @@ class EvolveInfo; // Stores information about an evolving item family
#include "../common/eq_constants.h"
#include "../common/item_struct.h"
#include "../common/timer.h"
#include "../common/bodytypes.h"
#include <list>
#include <map>
@@ -205,7 +204,7 @@ public:
int GetSlotByItemInst(ItemInst *inst);
uint8 FindBrightestLightType();
uint8 FindHighestLightValue();
void dumpEntireInventory();
void dumpWornItems();
@@ -419,58 +418,6 @@ public:
void StopTimer(std::string name);
void ClearTimers();
// Get a total of a stat, including augs
// These functions should be used in place of other code manually totaling
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
// and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance
// by default these do not recurse into augs
int GetItemArmorClass(bool augments = false) const;
int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const;
// These two differ in the fact that they're quick checks (they are checked BEFORE the one above
int GetItemElementalFlag(bool augments = false) const;
int GetItemElementalDamage(bool augments = false) const;
int GetItemRecommendedLevel(bool augments = false) const;
int GetItemRequiredLevel(bool augments = false) const;
int GetItemWeaponDamage(bool augments = false) const;
int GetItemBackstabDamage(bool augments = false) const;
// these two are just quick checks
int GetItemBaneDamageBody(bool augments = false) const;
int GetItemBaneDamageRace(bool augments = false) const;
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
int GetItemMagical(bool augments = false) const;
int GetItemHP(bool augments = false) const;
int GetItemMana(bool augments = false) const;
int GetItemEndur(bool augments = false) const;
int GetItemAttack(bool augments = false) const;
int GetItemStr(bool augments = false) const;
int GetItemSta(bool augments = false) const;
int GetItemDex(bool augments = false) const;
int GetItemAgi(bool augments = false) const;
int GetItemInt(bool augments = false) const;
int GetItemWis(bool augments = false) const;
int GetItemCha(bool augments = false) const;
int GetItemMR(bool augments = false) const;
int GetItemFR(bool augments = false) const;
int GetItemCR(bool augments = false) const;
int GetItemPR(bool augments = false) const;
int GetItemDR(bool augments = false) const;
int GetItemCorrup(bool augments = false) const;
int GetItemHeroicStr(bool augments = false) const;
int GetItemHeroicSta(bool augments = false) const;
int GetItemHeroicDex(bool augments = false) const;
int GetItemHeroicAgi(bool augments = false) const;
int GetItemHeroicInt(bool augments = false) const;
int GetItemHeroicWis(bool augments = false) const;
int GetItemHeroicCha(bool augments = false) const;
int GetItemHeroicMR(bool augments = false) const;
int GetItemHeroicFR(bool augments = false) const;
int GetItemHeroicCR(bool augments = false) const;
int GetItemHeroicPR(bool augments = false) const;
int GetItemHeroicDR(bool augments = false) const;
int GetItemHeroicCorrup(bool augments = false) const;
int GetItemHaste(bool augments = false) const;
protected:
//////////////////////////
// Protected Members
@@ -525,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
-4
View File
@@ -41,7 +41,6 @@ F(ac)
F(deity)
F(skillmodvalue)
F(UNK033)
F(skillmodmax)
F(skillmodtype)
F(banedmgrace)
F(banedmgamt)
@@ -173,10 +172,7 @@ F(bardlevel)
F(questitemflag)
F(svcorruption)
F(purity)
F(evoitem)
F(evoid)
F(evolvinglevel)
F(evomax)
F(backstabdmg)
F(dsmitigation)
F(heroic_str)
+2 -6
View File
@@ -51,7 +51,7 @@
**
*/
struct ItemEffect_Struct {
int32 Effect;
int16 Effect;
uint8 Type;
uint8 Level;
uint8 Level2;
@@ -130,7 +130,6 @@ struct Item_Struct {
uint32 Deity; // Bitmask of Deities that can equip this item
//uint32 Unk033
int32 SkillModValue; // % Mod to skill specified in SkillModType
int32 SkillModMax; // Max skill point modification
uint32 SkillModType; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace; // Bane Damage Race
int8 BaneDmgAmt; // Bane Damage Body Amount
@@ -186,7 +185,7 @@ struct Item_Struct {
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;
@@ -219,10 +218,7 @@ struct Item_Struct {
// Begin SoF Fields
int32 SVCorruption;
uint32 Purity;
uint8 EvolvingItem;
uint32 EvolvingID;
uint8 EvolvingLevel;
uint8 EvolvingMax;
uint32 BackstabDmg;
uint32 DSMitigation;
int32 HeroicStr;
+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 -4
View File
@@ -146,7 +146,6 @@ INr(OP_GuildDelete); //?
IN(OP_GuildPublicNote, GuildUpdate_PublicNote);
INz(OP_GetGuildsList); //?
IN(OP_SetGuildMOTD, GuildMOTD_Struct);
IN(OP_SetRunMode, SetRunMode_Struct);
INz(OP_GuildPeace); //?
INz(OP_GuildWar); //?
IN(OP_GuildLeader, GuildMakeLeader);
@@ -181,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
@@ -400,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
@@ -450,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
+250 -476
View File
File diff suppressed because it is too large Load Diff
+279 -637
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;
}
-9
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
@@ -57,7 +53,6 @@ E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupInvite)
E(OP_GroupUpdate)
E(OP_GuildBank)
E(OP_GuildMemberList)
E(OP_GuildMemberUpdate)
E(OP_GuildsList)
@@ -112,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)
@@ -125,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)
@@ -153,7 +146,6 @@ D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_GuildBank)
D(OP_GuildDemote)
D(OP_GuildRemove)
D(OP_GuildStatus)
@@ -178,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)
+181 -359
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,11 +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; // was [9]
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 30 */
};
@@ -1859,114 +1828,6 @@ struct GuildUpdate_Struct {
GuildsListEntry_Struct entry;
};
struct GuildBankAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
};
struct GuildBankDepositAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint32 Fail; //1 = Fail, 0 = Success
};
struct GuildBankPromote_Struct
{
/*00*/ uint32 Action; // 3
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*12*/ uint32 Slot;
/*16*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
/*20*/ uint32 unknown20;
};
struct GuildBankPermissions_Struct
{
/*00*/ uint32 Action; // 6
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID;
/*10*/ uint16 Unknown10; // Saw 1, probably indicating it is the main area rather than deposits
/*12*/ uint32 ItemID;
/*16*/ uint32 Permissions;
/*20*/ char MemberName[64];
};
struct GuildBankViewItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID; // 0 = Deposit area, 1 = Main area
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Unknown16;
};
struct GuildBankWithdrawItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID;
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Quantity;
/*20*/
};
struct GuildBankItemUpdate_Struct
{
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
{
Action = inAction;
Unknown004 = inUnknown004;
SlotID = inSlotID;
Area = inArea;
Unknown012 = inUnknown012;
ItemID = inItemID;
Icon = inIcon;
Quantity = inQuantity;
Permissions = inPermissions;
AllowMerge = inAllowMerge;
Useable = inUseable;
ItemName[0] = '\0';
Donator[0] = '\0';
WhoFor[0] = '\0';
};
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown08;
/*012*/ uint16 SlotID;
/*014*/ uint16 Area;
/*016*/ uint32 Unknown012;
/*020*/ uint32 ItemID;
/*024*/ uint32 Icon;
/*028*/ uint32 Quantity;
/*032*/ uint32 Permissions;
/*036*/ uint8 AllowMerge;
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char ItemName[64];
/*102*/ char Donator[64];
/*166*/ char WhoFor[64];
/*230*/ uint16 Unknown226;
};
struct GuildBankClear_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*12*/ uint32 DepositAreaCount;
/*16*/ uint32 MainAreaCount;
};
/*
** Money Loot
** Length: 22 Bytes
@@ -2582,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 {
@@ -3053,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 {
@@ -3341,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;
@@ -3365,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;
@@ -3414,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{
@@ -3729,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*/
};
@@ -4250,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 {
@@ -4299,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*/
};
@@ -4362,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;
@@ -4377,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];
};
@@ -4398,11 +4223,17 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*12*/ uint32 exp_value;
/*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
@@ -4422,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 {
@@ -4432,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 {
@@ -4660,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];
@@ -4732,7 +4570,7 @@ struct ClickEffectStruct
struct ProcEffectStruct
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4747,7 +4585,7 @@ struct ProcEffectStruct
struct WornEffectStruct //worn, focus and scroll effect
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4835,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;
}
-5
View File
@@ -42,7 +42,6 @@ E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupInvite)
E(OP_GroupUpdate)
E(OP_GuildBank)
E(OP_GuildMemberList)
E(OP_GuildMemberUpdate)
E(OP_GuildsList)
@@ -97,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)
@@ -110,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)
@@ -138,7 +135,6 @@ D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_GuildBank)
D(OP_GuildDemote)
D(OP_GuildRemove)
D(OP_GuildStatus)
@@ -163,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)
+158 -309
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,11 +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; // was [9]
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 30 */
};
@@ -1889,114 +1859,6 @@ struct GuildUpdate_Struct {
GuildsListEntry_Struct entry;
};
struct GuildBankAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
};
struct GuildBankDepositAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint32 Fail; //1 = Fail, 0 = Success
};
struct GuildBankPromote_Struct
{
/*00*/ uint32 Action; // 3
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*12*/ uint32 Slot;
/*16*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
/*20*/ uint32 unknown20;
};
struct GuildBankPermissions_Struct
{
/*00*/ uint32 Action; // 6
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID;
/*10*/ uint16 Unknown10; // Saw 1, probably indicating it is the main area rather than deposits
/*12*/ uint32 ItemID;
/*16*/ uint32 Permissions;
/*20*/ char MemberName[64];
};
struct GuildBankViewItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID; // 0 = Deposit area, 1 = Main area
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Unknown16;
};
struct GuildBankWithdrawItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*08*/ uint16 SlotID;
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Quantity;
/*20*/
};
struct GuildBankItemUpdate_Struct
{
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
{
Action = inAction;
Unknown004 = inUnknown004;
SlotID = inSlotID;
Area = inArea;
Unknown012 = inUnknown012;
ItemID = inItemID;
Icon = inIcon;
Quantity = inQuantity;
Permissions = inPermissions;
AllowMerge = inAllowMerge;
Useable = inUseable;
ItemName[0] = '\0';
Donator[0] = '\0';
WhoFor[0] = '\0';
};
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown08;
/*012*/ uint16 SlotID;
/*014*/ uint16 Area;
/*016*/ uint32 Unknown012;
/*020*/ uint32 ItemID;
/*024*/ uint32 Icon;
/*028*/ uint32 Quantity;
/*032*/ uint32 Permissions;
/*036*/ uint8 AllowMerge;
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char ItemName[64];
/*102*/ char Donator[64];
/*166*/ char WhoFor[64];
/*230*/ uint16 Unknown226;
};
struct GuildBankClear_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*12*/ uint32 DepositAreaCount;
/*16*/ uint32 MainAreaCount;
};
/*
** Money Loot
** Length: 22 Bytes
@@ -2610,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 {
@@ -3730,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*/
};
@@ -4251,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 {
@@ -4361,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;
@@ -4376,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];
};
@@ -4397,11 +4248,18 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*12*/ uint32 exp_value;
/*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;
@@ -4420,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 {
@@ -4430,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 {
@@ -4513,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 = ?
@@ -4659,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];
@@ -4731,7 +4596,7 @@ struct ClickEffectStruct
struct ProcEffectStruct
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4746,7 +4611,7 @@ struct ProcEffectStruct
struct WornEffectStruct //worn, focus and scroll effect
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4823,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
+187 -195
View File
@@ -446,10 +446,7 @@ namespace SoD
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(special);
eq->sequence = emu->sequence;
FINISH_ENCODE();
}
@@ -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);
@@ -1678,8 +1654,8 @@ namespace SoD
OUT(copper_bank);
OUT(platinum_shared);
// OUT(unknown13156[84]);
OUT(expansions);
//eq->expansions = 16383;
//OUT(expansions);
eq->expansions = 16383;
// OUT(unknown13244[12]);
OUT(autosplit);
// OUT(unknown13260[16]);
@@ -1863,150 +1839,128 @@ namespace SoD
ENCODE(OP_SendAATable)
{
EQApplicationPacket *inapp = *p;
*p = nullptr;
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
SETUP_VAR_ENCODE(SendAA_Struct);
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
eq->id = emu->id;
eq->unknown004 = 1;
eq->id = emu->id;
eq->hotkey_sid = emu->upper_hotkey_sid;
eq->hotkey_sid2 = emu->lower_hotkey_sid;
eq->desc_sid = emu->desc_sid;
eq->title_sid = emu->title_sid;
eq->class_type = emu->level_req;
eq->cost = emu->cost;
eq->seq = emu->seq;
eq->current_level = emu->current_level;
eq->type = emu->type;
eq->spellid = emu->spell;
eq->spell_type = emu->spell_type;
eq->spell_refresh = emu->spell_refresh;
eq->classes = emu->classes;
eq->max_level = emu->max_level;
eq->last_id = emu->prev_id;
eq->next_id = emu->next_id;
eq->cost2 = emu->total_cost;
eq->grant_only = emu->grant_only;
eq->expendable_charges = emu->charges;
eq->aa_expansion = emu->expansion;
eq->special_category = emu->category;
eq->total_abilities = emu->total_effects;
for(auto i = 0; i < eq->total_abilities; ++i) {
eq->abilities[i].skill_id = inapp->ReadUInt32();
eq->abilities[i].base1 = inapp->ReadUInt32();
eq->abilities[i].base2 = inapp->ReadUInt32();
eq->abilities[i].slot = inapp->ReadUInt32();
// Check clientver field to verify this AA should be sent for SoF
// clientver 1 is for all clients and 5 is for SoD
if (emu->clientver <= 5)
{
OUT(id);
eq->unknown004 = 1;
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->title_sid = emu->id - emu->current_level + 1;
//eq->desc_sid = emu->id - emu->current_level + 1;
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->title_sid = emu->sof_next_skill;
eq->desc_sid = emu->sof_next_skill;
OUT(class_type);
OUT(cost);
OUT(seq);
OUT(current_level);
OUT(prereq_skill);
OUT(prereq_minpoints);
eq->type = emu->sof_type;
OUT(spellid);
OUT(spell_type);
OUT(spell_refresh);
OUT(classes);
OUT(berserker);
//eq->max_level = emu->sof_max_level;
OUT(max_level);
OUT(last_id);
OUT(next_id);
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
OUT(abilities[r].skill_id);
OUT(abilities[r].base1);
OUT(abilities[r].base2);
OUT(abilities[r].slot);
}
}
if(emu->total_prereqs > 0) {
eq->prereq_skill = inapp->ReadUInt32();
eq->prereq_minpoints = inapp->ReadUInt32();
}
dest->FastQueuePacket(&outapp);
delete inapp;
FINISH_ENCODE();
}
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();
@@ -2207,6 +2161,25 @@ namespace SoD
ptr += sizeof(uint32);
ptr += 1;
}
/*std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
uint8 write_var8 = 1;
ss.write((const char*)&emu->entity_id, sizeof(uint32));
ss.write((const char*)&emu->count, sizeof(uint16));
write_var8 = 0;
for(uint16 i = 0; i < emu->count; ++i)
{
ss.write((const char*)&emu->entries[i].buff_slot, sizeof(uint32));
ss.write((const char*)&emu->entries[i].spell_id, sizeof(uint32));
ss.write((const char*)&emu->entries[i].tics_remaining, sizeof(uint32));
ss.write((const char*)&write_var8, sizeof(uint8));
}
__packet->size = ss.str().length();
__packet->pBuffer = new unsigned char[__packet->size];
memcpy(__packet->pBuffer, ss.str().c_str(), __packet->size);
*/
FINISH_ENCODE();
}
@@ -2382,7 +2355,7 @@ namespace SoD
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2454,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)
@@ -2723,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
@@ -2750,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);
}
}
}
@@ -2760,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);
}
@@ -2775,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);
@@ -3337,7 +3329,7 @@ namespace SoD
default:
emu->command = eq->command;
}
IN(target);
OUT(unknown);
FINISH_DIRECT_DECODE();
}
@@ -3492,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;
+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;
}
+115 -135
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,11 +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; // was [9]
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -2373,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
@@ -2393,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
@@ -3702,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 {
@@ -3814,21 +3793,16 @@ struct SendAA_Struct {
/*0049*/ uint32 spellid;
/*0053*/ uint32 spell_type;
/*0057*/ uint32 spell_refresh;
/*0061*/ uint32 classes;
/*0061*/ uint16 classes;
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
/*0065*/ uint32 max_level;
/*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];
};
@@ -3840,10 +3814,16 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*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 {
@@ -4111,7 +4091,7 @@ struct ClickEffectStruct
struct ProcEffectStruct
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4126,7 +4106,7 @@ struct ProcEffectStruct
struct WornEffectStruct //worn, focus and scroll effect
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
+166 -192
View File
@@ -426,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();
}
@@ -1202,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
@@ -1216,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);
@@ -1267,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);
@@ -1335,8 +1312,8 @@ namespace SoF
OUT(copper_bank);
OUT(platinum_shared);
// OUT(unknown13156[84]);
OUT(expansions);
//eq->expansions = 16383;
//OUT(expansions);
eq->expansions = 16383;
// OUT(unknown13244[12]);
OUT(autosplit);
// OUT(unknown13260[16]);
@@ -1520,150 +1497,129 @@ namespace SoF
ENCODE(OP_SendAATable)
{
EQApplicationPacket *inapp = *p;
*p = nullptr;
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
SETUP_VAR_ENCODE(SendAA_Struct);
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
eq->id = emu->id;
eq->unknown004 = 1;
eq->id = emu->id;
eq->hotkey_sid = emu->upper_hotkey_sid;
eq->hotkey_sid2 = emu->lower_hotkey_sid;
eq->desc_sid = emu->desc_sid;
eq->title_sid = emu->title_sid;
eq->class_type = emu->level_req;
eq->cost = emu->cost;
eq->seq = emu->seq;
eq->current_level = emu->current_level;
eq->type = emu->type;
eq->spellid = emu->spell;
eq->spell_type = emu->spell_type;
eq->spell_refresh = emu->spell_refresh;
eq->classes = emu->classes;
eq->max_level = emu->max_level;
eq->last_id = emu->prev_id;
eq->next_id = emu->next_id;
eq->cost2 = emu->total_cost;
eq->grant_only = emu->grant_only;
eq->expendable_charges = emu->charges;
eq->aa_expansion = emu->expansion;
eq->special_category = emu->category;
eq->total_abilities = emu->total_effects;
for(auto i = 0; i < eq->total_abilities; ++i) {
eq->abilities[i].skill_id = inapp->ReadUInt32();
eq->abilities[i].base1 = inapp->ReadUInt32();
eq->abilities[i].base2 = inapp->ReadUInt32();
eq->abilities[i].slot = inapp->ReadUInt32();
// Check clientver field to verify this AA should be sent for SoF
// clientver 1 is for all clients and 4 is for SoF
if (emu->clientver <= 4)
{
OUT(id);
eq->unknown004 = 1;
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->title_sid = emu->id - emu->current_level + 1;
//eq->desc_sid = emu->id - emu->current_level + 1;
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->title_sid = emu->sof_next_skill;
eq->desc_sid = emu->sof_next_skill;
OUT(class_type);
OUT(cost);
OUT(seq);
OUT(current_level);
OUT(prereq_skill);
OUT(prereq_minpoints);
eq->type = emu->sof_type;
OUT(spellid);
OUT(spell_type);
OUT(spell_refresh);
OUT(classes);
OUT(berserker);
//eq->max_level = emu->sof_max_level;
OUT(max_level);
OUT(last_id);
OUT(next_id);
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
OUT(abilities[r].skill_id);
OUT(abilities[r].base1);
OUT(abilities[r].base2);
OUT(abilities[r].slot);
}
}
if(emu->total_prereqs > 0) {
eq->prereq_skill = inapp->ReadUInt32();
eq->prereq_minpoints = inapp->ReadUInt32();
}
dest->FastQueuePacket(&outapp);
delete inapp;
FINISH_ENCODE();
}
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();
@@ -1985,7 +1941,7 @@ namespace SoF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1995,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)
@@ -2069,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;
@@ -2091,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;
@@ -2135,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;
@@ -2693,7 +2667,7 @@ namespace SoF
default:
emu->command = eq->command;
}
IN(target);
OUT(unknown);
FINISH_DIRECT_DECODE();
}
@@ -2834,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;
+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;
}
+113 -132
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] this appears unrelated to the stuff the other clients do here?
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -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 {
@@ -3677,19 +3655,16 @@ struct SendAA_Struct {
/*0049*/ uint32 spellid;
/*0053*/ uint32 spell_type;
/*0057*/ uint32 spell_refresh;
/*0061*/ uint32 classes;
/*0061*/ uint16 classes;
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
/*0065*/ uint32 max_level;
/*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];
};
@@ -3701,10 +3676,16 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*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;
@@ -3722,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 {
@@ -3965,7 +3946,7 @@ struct ClickEffectStruct
struct ProcEffectStruct
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -3980,7 +3961,7 @@ struct ProcEffectStruct
struct WornEffectStruct //worn, focus and scroll effect
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
+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; \
}
+99 -199
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);
@@ -299,23 +299,6 @@ namespace Titanium
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_Damage)
{
ENCODE_LENGTH_EXACT(CombatDamage_Struct);
SETUP_DIRECT_ENCODE(CombatDamage_Struct, structs::CombatDamage_Struct);
OUT(target);
OUT(source);
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
FINISH_ENCODE();
}
ENCODE(OP_DeleteCharge) { ENCODE_FORWARD(OP_MoveItem); }
ENCODE(OP_DeleteItem)
@@ -343,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)
@@ -882,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++) {
@@ -939,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);
@@ -1087,7 +1048,7 @@ namespace Titanium
ENCODE(OP_ReadBook)
{
// no apparent slot translation needed
// no apparent slot translation needed -U
EQApplicationPacket *in = *p;
*p = nullptr;
@@ -1115,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();
@@ -1124,148 +1085,87 @@ namespace Titanium
ENCODE(OP_SendAATable)
{
EQApplicationPacket *inapp = *p;
*p = nullptr;
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
SETUP_VAR_ENCODE(SendAA_Struct);
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
eq->id = emu->id;
eq->unknown004 = 1;
eq->id = emu->id;
eq->hotkey_sid = emu->upper_hotkey_sid;
eq->hotkey_sid2 = emu->lower_hotkey_sid;
eq->desc_sid = emu->desc_sid;
eq->title_sid = emu->title_sid;
eq->class_type = emu->level_req;
eq->cost = emu->cost;
eq->seq = emu->seq;
eq->current_level = emu->current_level;
eq->type = emu->type;
eq->spellid = emu->spell;
eq->spell_type = emu->spell_type;
eq->spell_refresh = emu->spell_refresh;
eq->classes = emu->classes;
eq->max_level = emu->max_level;
eq->last_id = emu->prev_id;
eq->next_id = emu->next_id;
eq->cost2 = emu->total_cost;
eq->total_abilities = emu->total_effects;
for(auto i = 0; i < eq->total_abilities; ++i) {
eq->abilities[i].skill_id = inapp->ReadUInt32();
eq->abilities[i].base1 = inapp->ReadUInt32();
eq->abilities[i].base2 = inapp->ReadUInt32();
eq->abilities[i].slot = inapp->ReadUInt32();
// Check clientver field to verify this AA should be sent for Titanium
// clientver 1 is for all clients and 3 is for Titanium
if (emu->clientver <= 3)
{
OUT(id);
eq->unknown004 = 1;
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
eq->title_sid = emu->id - emu->current_level + 1;
eq->desc_sid = emu->id - emu->current_level + 1;
OUT(class_type);
OUT(cost);
OUT(seq);
OUT(current_level);
OUT(prereq_skill);
OUT(prereq_minpoints);
OUT(type);
OUT(spellid);
OUT(spell_type);
OUT(spell_refresh);
OUT(classes);
OUT(berserker);
OUT(max_level);
OUT(last_id);
OUT(next_id);
OUT(cost2);
OUT(unknown80[0]);
OUT(unknown80[1]);
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
OUT(abilities[r].skill_id);
OUT(abilities[r].base1);
OUT(abilities[r].base2);
OUT(abilities[r].slot);
}
}
if(emu->total_prereqs > 0) {
eq->prereq_skill = inapp->ReadUInt32();
eq->prereq_minpoints = inapp->ReadUInt32();
}
dest->FastQueuePacket(&outapp);
delete inapp;
FINISH_ENCODE();
}
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();
@@ -1327,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);
}
@@ -1370,7 +1270,7 @@ namespace Titanium
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1483,7 +1383,7 @@ namespace Titanium
OUT(spawn_id);
OUT(material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1568,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;
@@ -1640,7 +1540,7 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_ApplyPoison)
{
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
@@ -1961,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);
@@ -2052,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;
@@ -2170,7 +2070,7 @@ namespace Titanium
return serverSlot; // deprecated
}
static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot)
{
//int16 TitaniumCorpse;
@@ -2185,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;
}
-1
View File
@@ -6,7 +6,6 @@ E(OP_BazaarSearch)
E(OP_BecomeTrader)
E(OP_ChannelMessage)
E(OP_CharInventory)
E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
+92 -104
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 */
};
@@ -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 {
@@ -3157,7 +3139,8 @@ struct SendAA_Struct {
/*0052*/ uint32 spellid;
/*0056*/ uint32 spell_type;
/*0060*/ uint32 spell_refresh;
/*0064*/ uint32 classes;
/*0064*/ uint16 classes;
/*0066*/ uint16 berserker; //seems to be 1 if its a berserker ability
/*0068*/ uint32 max_level;
/*0072*/ uint32 last_id;
/*0076*/ uint32 next_id;
@@ -3174,10 +3157,15 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*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;
@@ -3195,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 {
+185 -235
View File
@@ -365,7 +365,7 @@ namespace UF
memset(__packet->pBuffer, 0, sz);
__packet->WriteUInt32(emu->entity_id);
__packet->WriteUInt32(emu->tic_timer);
__packet->WriteUInt32(0);
__packet->WriteUInt8(emu->all_buffs); // 1 = all buffs, 0 = 1 buff
__packet->WriteUInt16(emu->count);
@@ -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();
/*
@@ -581,10 +581,7 @@ namespace UF
OUT(type);
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(special);
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);
@@ -1794,25 +1791,22 @@ 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
//only supports 240..
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
eq->aa_array[r].AA = emu->aa_array[r].AA;
eq->aa_array[r].value = emu->aa_array[r].value;
eq->aa_array[r].charges = emu->aa_array[r].charges;
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
}
// OUT(unknown02220[4]);
OUT(mana);
OUT(cur_hp);
OUT(STR);
@@ -1874,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);
@@ -1942,8 +1916,8 @@ namespace UF
OUT(copper_bank);
OUT(platinum_shared);
// OUT(unknown13156[84]);
OUT(expansions);
//eq->expansions = 0x1ffff;
//OUT(expansions);
eq->expansions = 0xffff;
// OUT(unknown13244[12]);
OUT(autosplit);
// OUT(unknown13260[16]);
@@ -2131,16 +2105,16 @@ namespace UF
eq->aa_spent = emu->aa_spent;
eq->aa_assigned = emu->aa_spent;
eq->aa_spent3 = 0;
eq->aa_spent3 = emu->aa_spent;
eq->unknown012 = 0;
eq->unknown016 = 0;
eq->unknown020 = 0;
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();
@@ -2148,158 +2122,129 @@ namespace UF
ENCODE(OP_SendAATable)
{
EQApplicationPacket *inapp = *p;
*p = nullptr;
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
SETUP_VAR_ENCODE(SendAA_Struct);
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
eq->id = emu->id;
eq->unknown004 = 1;
eq->id = emu->id;
eq->hotkey_sid = emu->upper_hotkey_sid;
eq->hotkey_sid2 = emu->lower_hotkey_sid;
eq->desc_sid = emu->desc_sid;
eq->title_sid = emu->title_sid;
eq->class_type = emu->level_req;
eq->cost = emu->cost;
eq->seq = emu->seq;
eq->current_level = emu->current_level;
eq->type = emu->type;
eq->spellid = emu->spell;
eq->spell_type = emu->spell_type;
eq->spell_refresh = emu->spell_refresh;
eq->classes = emu->classes;
eq->max_level = emu->max_level;
eq->last_id = emu->prev_id;
eq->next_id = emu->next_id;
eq->cost2 = emu->total_cost;
eq->grant_only = emu->grant_only;
eq->expendable_charges = emu->charges;
eq->aa_expansion = emu->expansion;
eq->special_category = emu->category;
eq->total_abilities = emu->total_effects;
for(auto i = 0; i < eq->total_abilities; ++i) {
eq->abilities[i].skill_id = inapp->ReadUInt32();
eq->abilities[i].base1 = inapp->ReadUInt32();
eq->abilities[i].base2 = inapp->ReadUInt32();
eq->abilities[i].slot = inapp->ReadUInt32();
// Check clientver field to verify this AA should be sent for SoF
// clientver 1 is for all clients and 6 is for Underfoot
if (emu->clientver <= 6)
{
OUT(id);
eq->unknown004 = 1;
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
//eq->title_sid = emu->id - emu->current_level + 1;
//eq->desc_sid = emu->id - emu->current_level + 1;
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
eq->title_sid = emu->sof_next_skill;
eq->desc_sid = emu->sof_next_skill;
OUT(class_type);
OUT(cost);
OUT(seq);
OUT(current_level);
OUT(prereq_skill);
OUT(prereq_minpoints);
eq->type = emu->sof_type;
OUT(spellid);
OUT(spell_type);
OUT(spell_refresh);
OUT(classes);
OUT(berserker);
//eq->max_level = emu->sof_max_level;
OUT(max_level);
OUT(last_id);
OUT(next_id);
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
OUT(abilities[r].skill_id);
OUT(abilities[r].base1);
OUT(abilities[r].base2);
OUT(abilities[r].slot);
}
}
if(emu->total_prereqs > 0) {
eq->prereq_skill = inapp->ReadUInt32();
eq->prereq_minpoints = inapp->ReadUInt32();
}
dest->FastQueuePacket(&outapp);
delete inapp;
FINISH_ENCODE();
}
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();
@@ -2676,7 +2621,7 @@ namespace UF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.Color);
OUT(color.color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2748,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)
@@ -3012,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
@@ -3038,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);
}
}
}
@@ -3048,21 +3012,11 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
if (emu->equipment[MaterialPrimary].Material > 99999) {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63);
} else {
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);
if (emu->equipment[MaterialSecondary].Material > 99999) {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63);
} else {
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);
}
@@ -3072,13 +3026,9 @@ namespace UF
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
for (k = 0; k < 9; k++) {
if (emu->equipment[k].Material > 99999) {
Equipment[k].Material = 63;
} else {
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);
@@ -3379,7 +3329,7 @@ namespace UF
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
emu->sequence = eq->sequence;
FINISH_DIRECT_DECODE();
}
@@ -3622,7 +3572,7 @@ namespace UF
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
IN(command);
IN(target);
IN(unknown);
FINISH_DIRECT_DECODE();
}
@@ -3778,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;
@@ -3849,19 +3799,19 @@ namespace UF
hdr.unknown044 = 0;
hdr.unknown048 = 0;
hdr.unknown052 = 0;
hdr.isEvolving = item->EvolvingItem;
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
ss.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader));
if (item->EvolvingItem > 0) {
if (item->EvolvingLevel > 0) {
UF::structs::EvolvingItem evotop;
evotop.unknown001 = 0;
evotop.unknown002 = 0;
evotop.unknown003 = 0;
evotop.unknown004 = 0;
evotop.evoLevel = item->EvolvingLevel;
evotop.progress = 0;
evotop.progress = 95.512;
evotop.Activated = 1;
evotop.evomaxlevel = item->EvolvingMax;
evotop.evomaxlevel = 7;
ss.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
}
//ORNAMENT IDFILE / ICON -
@@ -3884,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;
@@ -3961,7 +3911,7 @@ namespace UF
ibs.Races = item->Races;
ibs.Deity = item->Deity;
ibs.SkillModValue = item->SkillModValue;
ibs.SkillModMax = item->SkillModMax;
ibs.unknown5 = 0;
ibs.SkillModType = item->SkillModType;
ibs.BaneDmgRace = item->BaneDmgRace;
ibs.BaneDmgBody = item->BaneDmgBody;
+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;
}
+116 -138
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,11 +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; // was [9]
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 28 */
};
@@ -2189,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...
};
@@ -2442,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
@@ -2462,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
@@ -3775,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'
@@ -3887,21 +3865,16 @@ struct SendAA_Struct {
/*0049*/ uint32 spellid;
/*0053*/ uint32 spell_type;
/*0057*/ uint32 spell_refresh;
/*0061*/ uint32 classes;
/*0061*/ uint16 classes;
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
/*0065*/ uint32 max_level;
/*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];
};
@@ -3913,10 +3886,15 @@ struct AA_List {
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*08*/ uint32 unknown08;
/*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 {
@@ -4103,7 +4081,7 @@ struct ItemBodyStruct
uint32 Races;
uint32 Deity;
int32 SkillModValue;
uint32 SkillModMax;
uint32 unknown5;
uint32 SkillModType;
uint32 BaneDmgRace;
uint32 BaneDmgBody;
@@ -4206,7 +4184,7 @@ struct ClickEffectStruct
struct ProcEffectStruct
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
@@ -4221,7 +4199,7 @@ struct ProcEffectStruct
struct WornEffectStruct //worn, focus and scroll effect
{
int32 effect;
uint32 effect;
uint8 level2;
uint32 type;
uint8 level;
-363
View File
@@ -1,363 +0,0 @@
#include "pathfind.h"
#include "random.h"
#include <stdio.h>
#include <string.h>
#include <zlib.h>
namespace Pathfind
{
uint32_t InflateData(const char* buffer, uint32_t len, char* out_buffer, uint32_t out_len_max) {
z_stream zstream;
int zerror = 0;
int i;
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
zstream.avail_in = len;
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);;
zstream.avail_out = out_len_max;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
i = inflateInit2(&zstream, 15);
if (i != Z_OK) {
return 0;
}
zerror = inflate(&zstream, Z_FINISH);
if (zerror == Z_STREAM_END) {
inflateEnd(&zstream);
return zstream.total_out;
}
else {
if (zerror == -4 && zstream.msg == 0)
{
return 0;
}
zerror = inflateEnd(&zstream);
return 0;
}
}
}
const uint32_t nav_mesh_file_version = 2;
const float max_dest_drift = 10.0f;
const float at_waypoint_eps = 1.0f;
EQEmu::Random path_rng;
float vec_dist(const glm::vec3 &a, const glm::vec3 &b) {
float dist_x = a.x - b.x;
float dist_y = a.y - b.y;
float dist_z = a.z - b.z;
return sqrt((dist_x * dist_x) + (dist_y * dist_y) + (dist_z * dist_z));
}
PathfindingManager::PathfindingManager()
{
m_nav_mesh = nullptr;
m_nav_query = nullptr;
m_filter.setIncludeFlags(NavigationPolyFlagAll);
m_filter.setAreaCost(NavigationAreaFlagNormal, 1.0f);
m_filter.setAreaCost(NavigationAreaFlagWater, 2.5f);
m_filter.setAreaCost(NavigationAreaFlagLava, 2.5f);
m_filter.setAreaCost(NavigationAreaFlagPvP, 1.0f);
m_filter.setAreaCost(NavigationAreaFlagSlime, 1.0f);
m_filter.setAreaCost(NavigationAreaFlagIce, 1.0f);
m_filter.setAreaCost(NavigationAreaFlagVWater, 2.5f);
m_filter.setAreaCost(NavigationAreaFlagGeneralArea, 1.0f);
m_filter.setAreaCost(NavigationAreaFlagPortal, 1.0f);
}
PathfindingManager::~PathfindingManager()
{
Clear();
}
void PathfindingManager::Load(const std::string &zone_name)
{
Clear();
std::string filename = MAP_DIR + std::string("/") + zone_name + ".nav";
FILE *f = fopen(filename.c_str(), "rb");
if (f) {
char magic[9] = { 0 };
if (fread(magic, 9, 1, f) != 1) {
fclose(f);
return;
}
if (strncmp(magic, "EQNAVMESH", 9) != 0)
{
fclose(f);
return;
}
uint32_t version = 0;
if (fread(&version, sizeof(uint32_t), 1, f) != 1) {
fclose(f);
return;
}
if (version != nav_mesh_file_version) {
fclose(f);
return;
}
uint32_t data_size;
if (fread(&data_size, sizeof(data_size), 1, f) != 1) {
fclose(f);
return;
}
uint32_t buffer_size;
if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) {
fclose(f);
return;
}
std::vector<char> data;
data.resize(data_size);
if (fread(&data[0], data_size, 1, f) != 1) {
fclose(f);
return;
}
std::vector<char> buffer;
buffer.resize(buffer_size);
uint32_t v = Pathfind::InflateData(&data[0], data_size, &buffer[0], buffer_size);
fclose(f);
char *buf = &buffer[0];
m_nav_mesh = dtAllocNavMesh();
uint32_t number_of_tiles = *(uint32_t*)buf;
buf += sizeof(uint32_t);
dtNavMeshParams params = *(dtNavMeshParams*)buf;
buf += sizeof(dtNavMeshParams);
dtStatus status = m_nav_mesh->init(&params);
if (dtStatusFailed(status))
{
dtFreeNavMesh(m_nav_mesh);
m_nav_mesh = nullptr;
return;
}
for (unsigned int i = 0; i < number_of_tiles; ++i)
{
uint32_t tile_ref = *(uint32_t*)buf;
buf += sizeof(uint32_t);
int32_t data_size = *(uint32_t*)buf;
buf += sizeof(uint32_t);
if (!tile_ref || !data_size) {
dtFreeNavMesh(m_nav_mesh);
m_nav_mesh = nullptr;
return;
}
unsigned char* data = (unsigned char*)dtAlloc(data_size, DT_ALLOC_PERM);
memcpy(data, buf, data_size);
buf += data_size;
m_nav_mesh->addTile(data, data_size, DT_TILE_FREE_DATA, tile_ref, 0);
}
}
}
void PathfindingManager::Clear()
{
if (m_nav_mesh) {
dtFreeNavMesh(m_nav_mesh);
m_nav_mesh = nullptr;
}
if (m_nav_query) {
dtFreeNavMeshQuery(m_nav_query);
m_nav_query = nullptr;
}
}
PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const glm::vec3 &dest_loc)
{
glm::vec3 current_location(src_loc.x, src_loc.z, src_loc.y);
glm::vec3 dest_location(dest_loc.x, dest_loc.z, dest_loc.y);
PathfindingRoute ret;
ret.m_status = PathComplete;
ret.m_dest = dest_loc;
ret.m_current_node = 0;
ret.m_active = true;
if (!m_nav_mesh) {
PathfindingNode dest;
dest.flag = NavigationPolyFlagNormal;
dest.position = dest_loc;
ret.m_nodes.push_back(dest);
return ret;
}
if (!m_nav_query) {
m_nav_query = dtAllocNavMeshQuery();
m_nav_query->init(m_nav_mesh, 4092);
}
dtPolyRef start_ref;
dtPolyRef end_ref;
glm::vec3 ext(15.0f, 15.0f, 15.0f);
m_nav_query->findNearestPoly(&current_location[0], &ext[0], &m_filter, &start_ref, 0);
m_nav_query->findNearestPoly(&dest_location[0], &ext[0], &m_filter, &end_ref, 0);
if (!start_ref || !end_ref) {
PathfindingNode dest;
dest.flag = NavigationPolyFlagNormal;
dest.position = dest_loc;
ret.m_nodes.push_back(dest);
return ret;
}
int npoly = 0;
dtPolyRef path[256] = { 0 };
auto status = m_nav_query->findPath(start_ref, end_ref, &current_location[0], &dest_location[0], &m_filter, path, &npoly, 256);
if (status & DT_OUT_OF_NODES || status & DT_BUFFER_TOO_SMALL) {
ret.m_status = PathPartial;
}
else if (status & DT_PARTIAL_RESULT) {
ret.m_status = PathBroken;
}
if (npoly) {
glm::vec3 epos = dest_location;
if (path[npoly - 1] != end_ref)
m_nav_query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
float straight_path[512 * 3];
unsigned char straight_path_flags[512];
int n_straight_polys;
dtPolyRef straight_path_polys[512];
status = m_nav_query->findStraightPath(&current_location[0], &epos[0], path, npoly,
straight_path, straight_path_flags,
straight_path_polys, &n_straight_polys, 512, DT_STRAIGHTPATH_ALL_CROSSINGS);
if (ret.m_status == PathComplete && status & DT_OUT_OF_NODES || status & DT_BUFFER_TOO_SMALL) {
ret.m_status = PathPartial;
}
else if (ret.m_status == PathComplete && status & DT_PARTIAL_RESULT) {
ret.m_status = PathBroken;
}
if (n_straight_polys) {
ret.m_nodes.reserve(n_straight_polys);
for (int i = 0; i < n_straight_polys; ++i)
{
PathfindingNode node;
node.position.x = straight_path[i * 3];
node.position.z = straight_path[i * 3 + 1];
node.position.y = straight_path[i * 3 + 2];
if (!dtStatusSucceed(m_nav_mesh->getPolyFlags(straight_path_polys[i], &node.flag))) {
node.flag = 0;
}
ret.m_nodes.push_back(node);
}
}
}
else {
PathfindingNode dest;
dest.flag = NavigationPolyFlagNormal;
dest.position = dest_loc;
ret.m_nodes.push_back(dest);
}
return ret;
}
bool PathfindingManager::GetRandomPoint(const glm::vec3 &start, float radius, glm::vec3 &pos)
{
if(!m_nav_mesh)
return false;
if (!m_nav_query) {
m_nav_query = dtAllocNavMeshQuery();
m_nav_query->init(m_nav_mesh, 4092);
}
glm::vec3 ext(10.0f, 10.0f, 10.0f);
dtPolyRef start_ref;
m_nav_query->findNearestPoly(&start[0], &ext[0], &m_filter, &start_ref, 0);
if (!start_ref) {
return false;
}
dtPolyRef random_ref;
glm::vec3 pt;
dtStatus status = m_nav_query->findRandomPointAroundCircle(start_ref, &start[0], radius,
&m_filter, []() -> float { return (float)path_rng.Real(0.0, 1.0); }, &random_ref, &pt[0]);
if (dtStatusSucceed(status))
{
pos.x = pt.x;
pos.z = pt.y;
pos.y = pt.z;
return true;
}
return false;
}
PathfindingRoute::PathfindingRoute()
{
m_active = false;
}
PathfindingRoute::~PathfindingRoute()
{
}
bool PathfindingRoute::DestinationValid(const glm::vec3 &dest)
{
if (m_status == PathPartial && m_current_node + 1 == m_nodes.size()) {
return false;
}
auto dist = vec_dist(dest, m_dest);
if (dist <= max_dest_drift) {
return true;
}
return false;
}
void PathfindingRoute::CalcCurrentNode(const glm::vec3 &current_pos, bool &wp_changed)
{
wp_changed = false;
if (m_active) {
//if we're at last node then we dont need to do anything.
if (m_nodes.size() - 1 == m_current_node) {
return;
}
auto &current = GetCurrentNode();
auto dist = vec_dist(current.position, current_pos);
if (dist < at_waypoint_eps) {
m_current_node++;
wp_changed = true;
}
}
}
unsigned short PathfindingRoute::GetPreviousNodeFlag()
{
if(m_current_node == 0)
return 0;
return m_nodes[m_current_node - 1].flag;
}
-94
View File
@@ -1,94 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <DetourNavMesh.h>
#include <DetourNavMeshQuery.h>
#include <glm/vec3.hpp>
enum NavigationAreaFlags
{
NavigationAreaFlagNormal,
NavigationAreaFlagWater,
NavigationAreaFlagLava,
NavigationAreaFlagZoneLine,
NavigationAreaFlagPvP,
NavigationAreaFlagSlime,
NavigationAreaFlagIce,
NavigationAreaFlagVWater,
NavigationAreaFlagGeneralArea,
NavigationAreaFlagPortal,
NavigationAreaFlagDisabled,
};
enum NavigationPolyFlags
{
NavigationPolyFlagNormal = 1,
NavigationPolyFlagWater = 2,
NavigationPolyFlagLava = 4,
NavigationPolyFlagZoneLine = 8,
NavigationPolyFlagPvP = 16,
NavigationPolyFlagSlime = 32,
NavigationPolyFlagIce = 64,
NavigationPolyFlagVWater = 128,
NavigationPolyFlagGeneralArea = 256,
NavigationPolyFlagPortal = 512,
NavigationPolyFlagDisabled = 1024,
NavigationPolyFlagAll = 0xFFFF
};
struct PathfindingNode
{
glm::vec3 position;
unsigned short flag;
};
enum PathfindingRouteStatus
{
PathComplete,
PathPartial,
PathBroken
};
class PathfindingRoute
{
public:
PathfindingRoute();
~PathfindingRoute();
bool Active() const { return m_active; }
bool DestinationValid(const glm::vec3 &dest);
void CalcCurrentNode(const glm::vec3 &current_pos, bool &wp_changed);
const PathfindingNode& GetCurrentNode() { return m_nodes[m_current_node]; }
unsigned short GetPreviousNodeFlag();
const std::vector<PathfindingNode>& GetNodes() const { return m_nodes; }
std::vector<PathfindingNode>& GetNodesEdit() { return m_nodes; }
PathfindingRouteStatus GetStatus() { return m_status; }
private:
glm::vec3 m_dest;
std::vector<PathfindingNode> m_nodes;
int m_current_node;
bool m_active;
PathfindingRouteStatus m_status;
friend class PathfindingManager;
};
class PathfindingManager
{
public:
PathfindingManager();
~PathfindingManager();
void Load(const std::string &filename);
void Clear();
//Expects locations in EQEmu internal format eg what #loc returns not what /loc returns.
PathfindingRoute FindRoute(const glm::vec3 &current_location, const glm::vec3 &dest_location);
bool GetRandomPoint(const glm::vec3 &start, float radius, glm::vec3 &pos);
bool Loaded() const { return m_nav_mesh != nullptr; }
private:
dtNavMesh *m_nav_mesh;
dtNavMeshQuery *m_nav_query;
dtQueryFilter m_filter;
};
+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
+5 -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
@@ -139,4 +138,8 @@ protected:
std::map<pTimerType, PersistentTimer *> _list;
};
//code prettying macros
#define AA_Choose3(val, v1, v2, v3) (val==1?v1:(val==2?v2:v3))
#define AA_Choose5(val, v1, v2, v3, v4, v5) (val==1?v1:(val==2?v2:(val==3?v3:(val==4?v4:v5))))
#endif
-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
+172 -149
View File
@@ -17,14 +17,43 @@
*/
#include "rulesys.h"
#include "database.h"
#include "string_util.h"
#include <cstdlib>
#include <cstring>
/*
Commands:
#rules:
FatherNitwit: Added new rules subsystem to allow game rules to be changed
at runtime. more about this will come as time goes on.
FatherNitwit: Added #rules command to manage rules data from in game.
FatherNitwit: Renamed old #rules to #serverrules
FatherNitwit: Moved max level into the rules system (Character:MaxLevel)
Requred SQL:
CREATE TABLE rule_sets (
ruleset_id TINYINT UNSIGNED NOT NULL auto_increment,
name VARCHAR(255) NOT NULL,
PRIMARY KEY(ruleset_id)
);
INSERT INTO rule_sets VALUES(0, "default");
UPDATE rule_sets SET ruleset_id=0;
CREATE TABLE rule_values (
ruleset_id TINYINT UNSIGNED NOT NULL,
rule_name VARCHAR(64) NOT NULL,
rule_value VARCHAR(10) NOT NULL,
INDEX(ruleset_id),
PRIMARY KEY(ruleset_id,rule_name)
);
Commands:
#rules:
current -> lists current set name
switch (set name) -> change set in the DB, but dont reload
load (set name) -> load set into this zone without changing the world
@@ -65,28 +94,28 @@ RuleManager::RuleManager()
}
RuleManager::CategoryType RuleManager::FindCategory(const char *catname) {
int i;
for (i = 0; i < _CatCount; i++) {
if (strcasecmp(catname, s_categoryNames[i]) == 0)
return((CategoryType)i);
int r;
for(r = 0; r < _CatCount; r++) {
if(strcasecmp(catname, s_categoryNames[r]) == 0)
return((CategoryType) r);
}
return(InvalidCategory);
}
bool RuleManager::ListRules(const char *catname, std::vector<const char *> &into) {
CategoryType cat = InvalidCategory;
if (catname != nullptr) {
if(catname != nullptr) {
cat = FindCategory(catname);
if (cat == InvalidCategory) {
if(cat == InvalidCategory) {
Log.Out(Logs::Detail, Logs::Rules, "Unable to find category '%s'", catname);
return(false);
}
}
int i;
int rule_count = CountRules();
for (i = 0; i < rule_count; i++) {
const RuleInfo &rule = s_RuleInfo[i];
if (catname == nullptr || cat == rule.category) {
int r;
int rcount = CountRules();
for(r = 0; r < rcount; r++) {
const RuleInfo &rule = s_RuleInfo[r];
if(catname == nullptr || cat == rule.category) {
into.push_back(rule.name);
}
}
@@ -94,14 +123,15 @@ bool RuleManager::ListRules(const char *catname, std::vector<const char *> &into
}
bool RuleManager::ListCategories(std::vector<const char *> &into) {
int i;
for (i = 0; i < _CatCount; i++) {
into.push_back(s_categoryNames[i]);
int r;
for(r = 0; r < _CatCount; r++) {
into.push_back(s_categoryNames[r]);
}
return(true);
}
bool RuleManager::GetRule(const char *rule_name, std::string &return_value) {
bool RuleManager::GetRule(const char *rule_name, std::string &ret_val) {
RuleType type;
uint16 index;
if (!_FindRule(rule_name, type, index))
@@ -121,12 +151,12 @@ bool RuleManager::GetRule(const char *rule_name, std::string &return_value) {
break;
}
return_value = tmp;
ret_val = tmp;
return true;
}
bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *database, bool db_save) {
bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *db, bool db_save) {
if(rule_name == nullptr || rule_value == nullptr)
return(false);
@@ -136,26 +166,25 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas
return(false);
switch(type) {
case IntRule:
m_RuleIntValues[index] = atoi(rule_value);
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %d", rule_name, m_RuleIntValues[index]);
break;
case RealRule:
m_RuleRealValues[index] = atof(rule_value);
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %.13f", rule_name, m_RuleRealValues[index]);
break;
case BoolRule:
uint32 val = 0;
if (!strcasecmp(rule_value, "on") || !strcasecmp(rule_value, "true") || !strcasecmp(rule_value, "yes") || !strcasecmp(rule_value, "enabled") || !strcmp(rule_value, "1"))
val = 1;
m_RuleBoolValues[index] = val;
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %s", rule_name, m_RuleBoolValues[index] == 1 ? "true" : "false");
break;
case IntRule:
m_RuleIntValues [index] = atoi(rule_value);
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %d", rule_name, m_RuleIntValues[index]);
break;
case RealRule:
m_RuleRealValues[index] = atof(rule_value);
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %.13f", rule_name, m_RuleRealValues[index]);
break;
case BoolRule:
uint32 val = 0;
if(!strcasecmp(rule_value, "on") || !strcasecmp(rule_value, "true") || !strcasecmp(rule_value, "yes") || !strcasecmp(rule_value, "enabled") || !strcmp(rule_value, "1"))
val = 1;
m_RuleBoolValues[index] = val;
Log.Out(Logs::Detail, Logs::Rules, "Set rule %s to value %s", rule_name, m_RuleBoolValues[index] == 1 ?"true":"false");
break;
}
if(db_save)
_SaveRule(database, type, index);
_SaveRule(db, type, index);
return(true);
}
@@ -172,14 +201,14 @@ void RuleManager::ResetRules() {
}
bool RuleManager::_FindRule(const char *rule_name, RuleType &type_into, uint16 &index_into) {
if (rule_name == nullptr)
if(rule_name == nullptr)
return(false);
int i;
int rule_count = CountRules();
for (i = 0; i < rule_count; i++) {
const RuleInfo &rule = s_RuleInfo[i];
if (strcmp(rule_name, rule.name) == 0) {
int r;
int rcount = CountRules();
for(r = 0; r < rcount; r++) {
const RuleInfo &rule = s_RuleInfo[r];
if(strcmp(rule_name, rule.name) == 0) {
type_into = rule.type;
index_into = rule.rule_index;
return(true);
@@ -191,197 +220,191 @@ bool RuleManager::_FindRule(const char *rule_name, RuleType &type_into, uint16 &
//assumes index is valid!
const char *RuleManager::_GetRuleName(RuleType type, uint16 index) {
switch (type) {
case IntRule:
return(s_RuleInfo[index].name);
case RealRule:
return(s_RuleInfo[index + _IntRuleCount].name);
case BoolRule:
return(s_RuleInfo[index + _IntRuleCount + _RealRuleCount].name);
switch(type) {
case IntRule:
return(s_RuleInfo[index].name);
case RealRule:
return(s_RuleInfo[index+_IntRuleCount].name);
case BoolRule:
return(s_RuleInfo[index+_IntRuleCount+_RealRuleCount].name);
}
//should never happen
return("InvalidRule??");
}
void RuleManager::SaveRules(Database *database, const char *ruleset_name) {
void RuleManager::SaveRules(Database *db, const char *ruleset) {
if (ruleset_name != nullptr) {
if(ruleset != nullptr) {
//saving to a specific name
if (m_activeName != ruleset_name) {
if(m_activeName != ruleset) {
//a new name...
m_activeRuleset = _FindOrCreateRuleset(database, ruleset_name);
if (m_activeRuleset == -1) {
Log.Out(Logs::Detail, Logs::Rules, "Unable to find or create rule set %s", ruleset_name);
m_activeRuleset = _FindOrCreateRuleset(db, ruleset);
if(m_activeRuleset == -1) {
Log.Out(Logs::Detail, Logs::Rules, "Unable to find or create rule set %s", ruleset);
return;
}
m_activeName = ruleset_name;
m_activeName = ruleset;
}
Log.Out(Logs::Detail, Logs::Rules, "Saving running rules into rule set %s (%d)", ruleset_name, m_activeRuleset);
}
else {
Log.Out(Logs::Detail, Logs::Rules, "Saving running rules into rule set %s (%d)", ruleset, m_activeRuleset);
} else {
Log.Out(Logs::Detail, Logs::Rules, "Saving running rules into running rule set %s", m_activeName.c_str(), m_activeRuleset);
}
int i;
for (i = 0; i < _IntRuleCount; i++) {
_SaveRule(database, IntRule, i);
int r;
for(r = 0; r < _IntRuleCount; r++) {
_SaveRule(db, IntRule, r);
}
for (i = 0; i < _RealRuleCount; i++) {
_SaveRule(database, RealRule, i);
for(r = 0; r < _RealRuleCount; r++) {
_SaveRule(db, RealRule, r);
}
for (i = 0; i < _BoolRuleCount; i++) {
_SaveRule(database, BoolRule, i);
for(r = 0; r < _BoolRuleCount; r++) {
_SaveRule(db, BoolRule, r);
}
}
bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
int ruleset_id = GetRulesetID(database, ruleset_name);
if (ruleset_id < 0) {
Log.Out(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset_name);
bool RuleManager::LoadRules(Database *db, const char *ruleset) {
int rsid = GetRulesetID(db, ruleset);
if(rsid < 0) {
Log.Out(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset);
return(false);
}
Log.Out(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", ruleset_name, ruleset_id);
Log.Out(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", ruleset, rsid);
m_activeRuleset = ruleset_id;
m_activeName = ruleset_name;
m_activeRuleset = rsid;
m_activeName = ruleset;
/* Load default ruleset values first if we're loading something other than default */
if (strcasecmp(ruleset_name, "default") != 0){
std::string default_ruleset_name = "default";
int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str());
if (default_ruleset_id < 0) {
Log.Out(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.", default_ruleset_name.c_str());
return(false);
}
Log.Out(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", default_ruleset_name.c_str(), default_ruleset_id);
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d", default_ruleset_id);
auto results = database->QueryDatabase(query);
if (!results.Success())
return false;
for (auto row = results.begin(); row != results.end(); ++row)
if (!SetRule(row[0], row[1], nullptr, false))
Log.Out(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", rsid);
auto results = db->QueryDatabase(query);
if (!results.Success())
{
return false;
}
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id);
auto results = database->QueryDatabase(query);
if (!results.Success())
return false;
for (auto row = results.begin(); row != results.end(); ++row)
if (!SetRule(row[0], row[1], nullptr, false))
Log.Out(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
for(auto row = results.begin(); row != results.end(); ++row)
if(!SetRule(row[0], row[1], nullptr, false))
Log.Out(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
return true;
}
void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) {
char value_string[100];
void RuleManager::_SaveRule(Database *db, RuleType type, uint16 index) {
char vstr[100];
switch(type) {
case IntRule:
sprintf(value_string, "%d", m_RuleIntValues[index]);
break;
case RealRule:
sprintf(value_string, "%.13f", m_RuleRealValues[index]);
break;
case BoolRule:
sprintf(value_string, "%s", m_RuleBoolValues[index]?"true":"false");
break;
case IntRule:
sprintf(vstr, "%d", m_RuleIntValues[index]);
break;
case RealRule:
sprintf(vstr, "%.13f", m_RuleRealValues[index]);
break;
case BoolRule:
sprintf(vstr, "%s", m_RuleBoolValues[index]?"true":"false");
break;
}
std::string query = StringFormat("REPLACE INTO rule_values "
"(ruleset_id, rule_name, rule_value) "
" VALUES(%d, '%s', '%s')",
m_activeRuleset, _GetRuleName(type, index), value_string);
auto results = database->QueryDatabase(query);
m_activeRuleset, _GetRuleName(type, index), vstr);
auto results = db->QueryDatabase(query);
}
int RuleManager::GetRulesetID(Database *database, const char *ruleset_name) {
int RuleManager::GetRulesetID(Database *db, const char *rulesetname) {
uint32 len = strlen(ruleset_name);
char* rst = new char[2 * len + 1];
database->DoEscapeString(rst, ruleset_name, len);
uint32 len = strlen(rulesetname);
char* rst = new char[2*len+1];
db->DoEscapeString(rst, rulesetname, len);
std::string query = StringFormat("SELECT ruleset_id FROM rule_sets WHERE name='%s'", rst);
safe_delete_array(rst);
auto results = database->QueryDatabase(query);
if (!results.Success())
return -1;
std::string query = StringFormat("SELECT ruleset_id FROM rule_sets WHERE name='%s'", rst);
safe_delete_array(rst);
auto results = db->QueryDatabase(query);
if (!results.Success()) {
return -1;
}
if (results.RowCount() == 0)
return -1;
if (results.RowCount() == 0)
return -1;
auto row = results.begin();
auto row = results.begin();
return atoi(row[0]);
}
int RuleManager::_FindOrCreateRuleset(Database *database, const char *in_ruleset_name) {
int RuleManager::_FindOrCreateRuleset(Database *db, const char *ruleset) {
int ruleset_id = GetRulesetID(database, in_ruleset_name);
if (ruleset_id >= 0)
return ruleset_id; //found and existing one...
int res = GetRulesetID(db, ruleset);
if(res >= 0)
return res; //found and existing one...
uint32 len = strlen(in_ruleset_name);
char* ruleset_name = new char[2 * len + 1];
database->DoEscapeString(ruleset_name, in_ruleset_name, len);
uint32 len = strlen(ruleset);
char* rst = new char[2*len+1];
db->DoEscapeString(rst, ruleset, len);
std::string query = StringFormat("INSERT INTO rule_sets (ruleset_id, name) VALUES(0, '%s')", ruleset_name);
safe_delete_array(ruleset_name);
auto results = database->QueryDatabase(query);
std::string query = StringFormat("INSERT INTO rule_sets (ruleset_id, name) VALUES(0, '%s')", rst);
safe_delete_array(rst);
auto results = db->QueryDatabase(query);
if (!results.Success())
{
return -1;
}
return results.LastInsertedID();
return results.LastInsertedID();
}
std::string RuleManager::GetRulesetName(Database *database, int ruleset_id) {
std::string query = StringFormat("SELECT name FROM rule_sets WHERE ruleset_id=%d", ruleset_id);
auto results = database->QueryDatabase(query);
std::string RuleManager::GetRulesetName(Database *db, int id) {
std::string query = StringFormat("SELECT name FROM rule_sets WHERE ruleset_id=%d", id);
auto results = db->QueryDatabase(query);
if (!results.Success())
return "";
{
return "";
}
if (results.RowCount() == 0)
return "";
return "";
auto row = results.begin();
auto row = results.begin();
return row[0];
}
bool RuleManager::ListRulesets(Database *database, std::map<int, std::string> &into) {
bool RuleManager::ListRulesets(Database *db, std::map<int, std::string> &into) {
//start out with the default set which is always present.
into[0] = "default";
std::string query = "SELECT ruleset_id, name FROM rule_sets";
auto results = database->QueryDatabase(query);
std::string query = "SELECT ruleset_id, name FROM rule_sets";
auto results = db->QueryDatabase(query);
if (results.Success())
{
return false;
}
for (auto row = results.begin(); row != results.end(); ++row)
into[atoi(row[0])] = row[1];
into[ atoi(row[0]) ] = row[1];
return true;
}
int32 RuleManager::GetIntRule(RuleManager::IntType t) const{
int32 RuleManager::GetIntRule(RuleManager::IntType t) const
{
return(m_RuleIntValues[t]);
}
float RuleManager::GetRealRule(RuleManager::RealType t) const{
float RuleManager::GetRealRule(RuleManager::RealType t) const
{
return(m_RuleRealValues[t]);
}
bool RuleManager::GetBoolRule(RuleManager::BoolType t) const{
bool RuleManager::GetBoolRule(RuleManager::BoolType t) const
{
return (m_RuleBoolValues[t] == 1);
}
+497 -541
View File
File diff suppressed because it is too large Load Diff
+1 -6
View File
@@ -84,7 +84,6 @@
#define ServerOP_QGlobalDelete 0x0064
#define ServerOP_DepopPlayerCorpse 0x0065
#define ServerOP_RequestTellQueue 0x0066 // client asks for it's tell queues
#define ServerOP_ChangeSharedMem 0x0067
#define ServerOP_RaidAdd 0x0100 //in use
#define ServerOP_RaidRemove 0x0101 //in use
@@ -182,7 +181,6 @@
#define ServerOP_CZMessagePlayer 0x4008
#define ServerOP_ReloadWorld 0x4009
#define ServerOP_ReloadLogs 0x4010
#define ServerOP_ReloadPerlExportSettings 0x4011
/* Query Server OP Codes */
#define ServerOP_QSPlayerLogTrades 0x5010
#define ServerOP_QSPlayerLogHandins 0x5011
@@ -523,7 +521,7 @@ struct ServerLSPlayerZoneChange_Struct {
uint32 from; // 0 = world
uint32 to; // 0 = world
};
struct ClientAuth_Struct {
struct ServerLSClientAuth {
uint32 lsaccount_id; // ID# in login server's db
char name[30]; // username in login server's db
char key[30]; // the Key the client will present
@@ -547,9 +545,7 @@ struct ServerLSPeerConnect {
struct ServerConnectInfo {
char address[250];
char local_address[250];
uint16 port;
uint32 process_id;
};
struct ServerGMGoto_Struct {
@@ -764,7 +760,6 @@ typedef enum {
struct LauncherZoneRequest {
uint8 command;
char short_name[33];
uint16 port;
};
struct LauncherZoneStatus {
+393 -333
View File
File diff suppressed because it is too large Load Diff
+18 -24
View File
@@ -12,7 +12,6 @@
#include <list>
#include <map>
#include <memory>
class EvolveInfo;
class Inventory;
@@ -51,7 +50,9 @@ class SharedDatabase : public Database
int32 DeleteStalePlayerCorpses();
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message);
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message);
void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message);
bool GetCommandSettings(std::map<std::string, uint8> &commands);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
/*
@@ -91,7 +92,7 @@ class SharedDatabase : public Database
//items
void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
bool LoadItems(const std::string &prefix);
bool LoadItems();
const Item_Struct* IterateItems(uint32* id);
const Item_Struct* GetItem(uint32 id);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
@@ -100,50 +101,43 @@ class SharedDatabase : public Database
void GetFactionListInfo(uint32 &list_count, uint32 &max_lists);
const NPCFactionList* GetNPCFactionEntry(uint32 id);
void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists);
bool LoadNPCFactionLists(const std::string &prefix);
bool LoadNPCFactionLists();
//loot
void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries);
void GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries);
void LoadLootTables(void *data, uint32 size);
void LoadLootDrops(void *data, uint32 size);
bool LoadLoot(const std::string &prefix);
bool LoadLoot();
const LootTable_Struct* GetLootTable(uint32 loottable_id);
const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id);
void LoadSkillCaps(void *data);
bool LoadSkillCaps(const std::string &prefix);
bool LoadSkillCaps();
uint16 GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Level);
uint8 GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Level);
int GetMaxSpellID();
bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp);
void LoadSpells(void *data, int max_spells);
void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID);
int GetMaxBaseDataLevel();
bool LoadBaseData(const std::string &prefix);
bool LoadBaseData();
void LoadBaseData(void *data, int max_level);
const BaseDataStruct* GetBaseData(int lvl, int cl);
#ifdef BOTS
void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message);
void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message);
#endif
protected:
std::unique_ptr<EQEmu::MemoryMappedFile> skill_caps_mmf;
std::unique_ptr<EQEmu::MemoryMappedFile> items_mmf;
std::unique_ptr<EQEmu::FixedMemoryHashSet<Item_Struct>> items_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> faction_mmf;
std::unique_ptr<EQEmu::FixedMemoryHashSet<NPCFactionList>> faction_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> loot_table_mmf;
std::unique_ptr<EQEmu::FixedMemoryVariableHashSet<LootTable_Struct>> loot_table_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> loot_drop_mmf;
std::unique_ptr<EQEmu::FixedMemoryVariableHashSet<LootDrop_Struct>> loot_drop_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> base_data_mmf;
std::unique_ptr<EQEmu::MemoryMappedFile> spells_mmf;
EQEmu::MemoryMappedFile *skill_caps_mmf;
EQEmu::MemoryMappedFile *items_mmf;
EQEmu::FixedMemoryHashSet<Item_Struct> *items_hash;
EQEmu::MemoryMappedFile *faction_mmf;
EQEmu::FixedMemoryHashSet<NPCFactionList> *faction_hash;
EQEmu::MemoryMappedFile *loot_table_mmf;
EQEmu::FixedMemoryVariableHashSet<LootTable_Struct> *loot_table_hash;
EQEmu::MemoryMappedFile *loot_drop_mmf;
EQEmu::FixedMemoryVariableHashSet<LootDrop_Struct> *loot_drop_hash;
EQEmu::MemoryMappedFile *base_data_mmf;
};
#endif /*SHAREDDB_H_*/
-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 -9
View File
@@ -108,17 +108,16 @@ enum SkillUseTypes
/*13869*/ SkillBerserking,
/*13902*/ SkillTaunt,
/*05837*/ SkillFrenzy, // This appears to be the only listed one not grouped with the others
/*00000*/ _EmuSkillCount // move to last position of active enumeration labels
// SoF+ specific skills
/*03670*/ SkillRemoveTraps,
/*13049*/ SkillTripleAttack,
// /*03670*/ SkillRemoveTraps,
// /*13049*/ SkillTripleAttack,
// RoF2+ specific skills
// /*00789*/ Skill2HPiercing,
// /*01216*/ SkillNone, // This needs to move down as new skills are added
/*00000*/ _EmuSkillCount // move to last position of active enumeration labels
// Skill Counts
// /*-----*/ _SkillCount_62 = 75, // use for Ti and earlier max skill checks
// /*-----*/ _SkillCount_SoF = 77, // use for SoF thru RoF1 max skill checks
@@ -171,9 +170,7 @@ enum SkillUseTypes
};
// temporary until it can be sorted out...
#define HIGHEST_SKILL SkillTripleAttack
// Spell Effects use this value to determine if an effect applies to all skills.
#define ALL_SKILLS -1
#define HIGHEST_SKILL SkillFrenzy
// server profile does not reflect this yet..so, prefixed with 'PACKET_'
#define PACKET_SKILL_ARRAY_SIZE 100
@@ -271,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 -15
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] < 255 && !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;
@@ -1092,14 +1092,6 @@ bool DetrimentalSpellAllowsRest(uint16 spell_id)
return false;
}
bool NoDetrimentalSpellAggro(uint16 spell_id)
{
if (IsValidSpell(spell_id))
return spells[spell_id].no_detrimental_spell_aggro;
return false;
}
uint32 GetNimbusEffect(uint16 spell_id)
{
if (IsValidSpell(spell_id))
+48 -67
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?
@@ -381,47 +380,47 @@ typedef enum {
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance.
#define SE_TwoHandBash 226 // *not implemented as bonus
#define SE_ReduceSkillTimer 227 // implemented
#define SE_ReduceFallDamage 228 // implented - reduce the damage that you take from falling
//#define SE_ReduceFallDamage 228 // not implented as bonus - reduce the damage that you take from falling
#define SE_PersistantCasting 229 // implemented
#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
//#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
#define SE_StunBashChance 231 // implemented - increase chance to stun from bash.
#define SE_DivineSave 232 // implemented (base1 == % chance on death to insta-res) (base2 == spell cast on save)
#define SE_Metabolism 233 // implemented - Modifies food/drink consumption rates.
#define SE_ReduceApplyPoisonTime 234 // not implemented as bonus - reduces the time to apply poison
//#define SE_ReduceApplyPoisonTime 234 // not implemented as bonus - reduces the time to apply poison
#define SE_ChannelChanceSpells 235 // implemented[AA] - chance to channel from SPELLS *No longer used on live.
//#define SE_FreePet 236 // not used
#define SE_GivePetGroupTarget 237 // implemented[AA] - (Pet Affinity)
#define SE_IllusionPersistence 238 // implemented - lends persistence to your illusionary disguises, causing them to last until you die or the illusion is forcibly removed.
#define SE_FeignedCastOnChance 239 // implemented - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you.
//#define SE_FeignedCastOnChance 239 // *not implemented as bonus - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you.
//#define SE_StringUnbreakable 240 // not used [Likely related to above - you become immune to feign breaking on a resisted spell and have a good chance of feigning through a spell that successfully lands upon you.]
#define SE_ImprovedReclaimEnergy 241 // implemented - increase the amount of mana returned to you when reclaiming your pet.
#define SE_IncreaseChanceMemwipe 242 // implemented - increases the chance to wipe hate with memory blurr
#define SE_CharmBreakChance 243 // implemented - Total Domination
#define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break.
#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
//#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
#define SE_SetBreathLevel 246 // *not implemented as bonus
#define SE_RaiseSkillCap 247 // implemented[AA] - adds skill over the skill cap.
#define SE_SecondaryForte 248 // not implemented as bonus(gives you a 2nd specialize skill that can go past 50 to 100)
#define SE_RaiseSkillCap 247 // *not implemented[AA] - adds skill over the skill cap.
//#define SE_SecondaryForte 248 // not implemented as bonus(gives you a 2nd specialize skill that can go past 50 to 100)
#define SE_SecondaryDmgInc 249 // implemented[AA] Allows off hand weapon to recieve a damage bonus (Sinister Strikes)
#define SE_SpellProcChance 250 // implemented - Increase chance to proc from melee proc spells (ie Spirit of Panther)
#define SE_ConsumeProjectile 251 // implemented[AA] - chance to not consume an arrow (ConsumeProjectile = 100)
#define SE_FrontalBackstabChance 252 // implemented[AA] - chance to perform a full damage backstab from front.
#define SE_FrontalBackstabMinDmg 253 // implemented[AA] - allow a frontal backstab for mininum damage.
#define SE_Blank 254 // implemented
#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
#define SE_ShroudofStealth 256 // implemented
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
//#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
//#define SE_ShroudofStealth 256 // not implemented as bonus - rogue improved invs
//#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
#define SE_CombatStability 259 // implemented[AA] - damage mitigation
#define SE_AddSingingMod 260 // implemented[AA] - Instrument/Singing Mastery, base1 is the mod, base2 is the ItemType
#define SE_SongModCap 261 // implemented[AA] - Song Mod cap increase (no longer used on live)
#define SE_RaiseStatCap 262 // implemented
#define SE_TradeSkillMastery 263 // implemented - lets you raise more than one tradeskill above master.
#define SE_HastenedAASkill 264 // implemented
//#define SE_TradeSkillMastery 263 // not implemented - lets you raise more than one tradeskill above master.
//#define SE_HastenedAASkill 264 // not implemented as bonus - Use redux field in aa_actions table for this effect
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
#define SE_ExtraAttackChance 266 // implemented - increase chance to score an extra attack with a 2-Handed Weapon.
#define SE_PetDiscipline2 267 // *not implemented - /pet focus, /pet no cast
#define SE_ReduceTradeskillFail 268 // implemented - reduces chance to fail with given tradeskill by a percent chance
//#define SE_ReduceTradeskillFail 268 // *not implemented? - reduces chance to fail with given tradeskill by a percent chance
#define SE_MaxBindWound 269 // implemented[AA] - Increase max HP you can bind wound.
#define SE_BardSongRange 270 // implemented[AA] - increase range of beneficial bard songs (Sionachie's Crescendo)
#define SE_BaseMovementSpeed 271 // implemented[AA] - mods basemove speed, doesn't stack with other move mods
@@ -434,14 +433,14 @@ typedef enum {
#define SE_FinishingBlow 278 // implemented[AA] - chance to do massive damage under 10% HP (base1 = chance, base2 = damage)
#define SE_Flurry 279 // implemented
#define SE_PetFlurry 280 // implemented[AA]
#define SE_FeignedMinion 281 // *not implemented[AA] ability allows you to instruct your pet to feign death via the '/pet feign' command. value = succeed chance
//#define SE_FeignedMinion 281 // *not implemented[AA] ability allows you to instruct your pet to feign death via the '/pet feign' command. value = succeed chance
#define SE_ImprovedBindWound 282 // implemented[AA] - increase bind wound amount by percent.
#define SE_DoubleSpecialAttack 283 // implemented[AA] - Chance to perform second special attack as monk
//#define SE_LoHSetHeal 284 // not used
#define SE_NimbleEvasion 285 // *not implemented - base1 = 100 for max
//#define SE_NimbleEvasion 285 // *not implemented - base1 = 100 for max
#define SE_FcDamageAmt 286 // implemented - adds direct spell damage
#define SE_SpellDurationIncByTic 287 // implemented
#define SE_SkillAttackProc 288 // implemented[AA] - Chance to proc spell on skill attack usage (ex. Dragon Punch)
#define SE_SpecialAttackKBProc 288 // implemented[AA] - Chance to to do a knockback from special attacks [AA Dragon Punch].
#define SE_CastOnFadeEffect 289 // implemented - Triggers only if fades after natural duration.
#define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap
#define SE_Purify 291 // implemented - Removes determental effects
@@ -478,7 +477,7 @@ typedef enum {
#define SE_GateToHomeCity 322 // implemented
#define SE_DefensiveProc 323 // implemented
#define SE_HPToMana 324 // implemented
#define SE_NoBreakAESneak 325 // implemented[AA] - [AA Nerves of Steel] increasing chance to remain hidden when they are an indirect target of an AoE spell.
//#define SE_ChanceInvsBreakToAoE 325 // *not implemented[AA] - [AA Nerves of Steel] increasing chance to remain hidden when they are an indirect target of an AoE spell.
#define SE_SpellSlotIncrease 326 // *not implemented as bonus - increases your spell slot availability
#define SE_MysticalAttune 327 // implemented - increases amount of buffs that a player can have
#define SE_DelayDeath 328 // implemented - increases how far you can fall below 0 hp before you die
@@ -486,7 +485,7 @@ typedef enum {
#define SE_CriticalDamageMob 330 // implemented
#define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine
//#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
#define SE_CastOnRuneFadeEffect 333 // implemented
#define SE_CastOnRuneFadeEffect 333 // implemented
#define SE_BardAEDot 334 // implemented
#define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494)
//#define SE_IllusionaryTarget 336 // not used
@@ -515,8 +514,8 @@ typedef enum {
//#define SE_PassiveSenseTrap 359 // *not implemented - Invulnerability (Brell's Blessing)
#define SE_ProcOnKillShot 360 // implemented - a buff that has a base1 % to cast spell base2 when you kill a "challenging foe" base3 min level
#define SE_SpellOnDeath 361 // implemented - casts spell on death of buffed
#define SE_PotionBeltSlots 362 // *not implemented[AA] 'Quick Draw' expands the potion belt by one additional available item slot per rank.
#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
//#define SE_PotionBeltSlots 362 // *not implemented[AA] 'Quick Draw' expands the potion belt by one additional available item slot per rank.
//#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
#define SE_TripleAttackChance 364 // implemented
#define SE_ProcOnSpellKillShot 365 // implemented - chance to trigger a spell on kill when the kill is caused by a specific spell with this effect in it (10470 Venin)
#define SE_ShieldEquipDmgMod 366 // implemented[AA] Damage modifier to melee if shield equiped. (base1 = dmg mod , base2 = ?) ie Shield Specialist AA
@@ -525,11 +524,11 @@ typedef enum {
#define SE_CorruptionCounter 369 // implemented
#define SE_ResistCorruption 370 // implemented
#define SE_AttackSpeed4 371 // implemented - stackable slow effect 'Inhibit Melee'
#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not.
//#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not.
#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
@@ -544,7 +543,7 @@ typedef enum {
//#define SE_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA)
#define SE_FcTimerRefresh 389 // implemented - Refresh spell icons
//#define SE_FcTimerLockout 390 // *not implemented - Sets recast timers to specific value, focus limited.
#define SE_LimitManaMax 391 // implemented
#define SE_MeleeVulnerability 391 // implemented [Live SPA has this as LimitManaMax however that is clearly not the effect used]
#define SE_FcHealAmt 392 // implemented - Adds or removes healing from spells
#define SE_FcHealPctIncoming 393 // implemented - HealRate with focus restrictions.
#define SE_FcHealAmtIncoming 394 // implemented - Adds/Removes amount of healing on target by X value with foucs restrictions.
@@ -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,10 +575,10 @@ 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
//#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
#define SE_SkillProc 427 // implemented - chance to proc when using a skill(ie taunt)
#define SE_LimitToSkill 428 // implemented - limits what skills will effect a skill proc
#define SE_SkillProcSuccess 429 // implemented - chance to proc when tje skill in use successfully fires.
@@ -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
@@ -613,25 +612,11 @@ typedef enum {
#define SE_ResourceTap 457 // implemented Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end.
#define SE_FactionModPct 458 // implemented Modifies faction gains and losses by percent.
#define SE_DamageModifier2 459 // implemented - Modifies melee damage by skill type
//#define SE_Ff_Override_NotFocusable 460 //
#define SE_ImprovedDamage2 461 // implemented - Increase spell damage by percent (SE_Fc_Damage_%2)
#define SE_FcDamageAmt2 462 // implemented - Increase spell damage by flat amount (SE_Fc_Damage_Amt2)
//#define SE_Shield_Target 463 //
#define SE_PC_Pet_Rampage 464 // implemented - Base1 % chance to do rampage for base2 % of damage each melee round
//#define SE_PC_Pet_AE_Rampage 465 // Would assume as above but need to confirm.
#define SE_PC_Pet_Flurry_Chance 466 // implemented - Base1 % chance to do flurry from double attack hit.
//#define SE_DS_Mitigation_Amount 467 //
//#define SE_DS_Mitigation_Percentage 468 //
//#define SE_Chance_Best_in_Spell_Grp 469 //
//#define SE_Trigger_Best_in_Spell Grp 470 //
//#define SE_Double_Melee_Round 471 //
// LAST
#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
@@ -744,38 +729,35 @@ struct SPDat_Spell_Struct
/* 194 */ float directional_start; //Cone Start Angle:
/* 195 */ float directional_end; // Cone End Angle:
/* 196 */ bool sneak; // effect can only be used if sneaking (rogue 'Daggerfall' ect)
/* 197 */ bool not_focusable; //prevents focus effects from being applied to spell
/* 198 */ bool no_detrimental_spell_aggro;
/* 199 */
/* 197 */ bool not_extendable;
/* 198- 199 */
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
/* 201 */ int viral_range;
/* 202 */ int songcap; // individual song cap
/* 203 */
/* 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 no_resist; //makes spells unresistable, which makes charms unbreakable as well.
/* 210 */ // bool DurationFrozen; ???
/* 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; ???
/* 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 - 216 */
/* 217 */ int override_crit_chance; //Places a cap on the max chance to critical
/* 218 */ int aemaxtargets; //Is used for various AE effects
/* 219 */ int no_heal_damage_item_mod;
/* 220 - 223 */
/* 215 - 217 */
/* 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 */
/* 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
/* 232 */ bool no_remove; //prevents buff from being removed by click
/* 233 - 236 */
/* 231 */ float min_range; //Min casting range
/* 232 - 236 */
uint8 DamageShieldType; // This field does not exist in spells_us.txt
};
@@ -881,7 +863,6 @@ uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
uint32 GetPartialMagicRuneAmount(uint32 spell_id);
bool NoDetrimentalSpellAggro(uint16 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75);
const char *GetRandPetName();
+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;
+1 -3
View File
@@ -23,9 +23,7 @@
*/
#ifdef _WINDOWS
#if (!defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1900))
#define snprintf _snprintf
#endif
#define snprintf _snprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
+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)
+2 -19
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;
@@ -43,9 +44,7 @@ typedef unsigned char uchar;
typedef const char Const_char; //for perl XS
#ifdef _WINDOWS
#if (!defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1900))
#define snprintf _snprintf
#endif
#define snprintf _snprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
typedef void ThreadReturnType;
@@ -85,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
+29 -41
View File
@@ -1,56 +1,44 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_ZONE_AA_RANK_H
#define EQEMU_ZONE_AA_RANK_H
namespace AA
{
class Ability;
class Rank
{
public:
Rank() { }
~Rank() { }
int id;
int upper_hotkey_sid;
int lower_hotkey_sid;
int title_sid;
int desc_sid;
int cost;
int level_req;
int spell;
int spell_type;
int recast_time;
int prev_id;
Rank *prev;
int next_id;
Rank *next;
int current_value;
int expansion;
int total_cost;
Ability *base_ability;
std::vector<RankEffect> effects;
std::map<int, int> prereqs;
};
}
#include "uuid.h"
#ifdef WIN32
#include <rpc.h>
#else
#include <uuid/uuid.h>
#endif
std::string CreateUUID() {
#ifdef WIN32
UUID uuid;
UuidCreate(&uuid);
unsigned char *str = nullptr;
UuidToStringA(&uuid, &str);
std::string s((char*)str);
RpcStringFreeA(&str);
return s;
#else
char str[64] = { 0 };
uuid_t uuid;
uuid_generate_random(uuid);
uuid_unparse(uuid, str);
return str;
#endif
}
+9 -21
View File
@@ -1,38 +1,26 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_UUID_H
#define COMMON_UUID_H
#ifndef EQEMU_ZONE_AA_RANK_EFFECTS_H
#define EQEMU_ZONE_AA_RANK_EFFECTS_H
#include "../common/global_define.h"
#include <string>
namespace AA
{
struct RankEffect
{
int slot;
int effect_id;
int base1;
int base2;
};
}
std::string CreateUUID();
#endif
+4 -9
View File
@@ -24,18 +24,13 @@
#define CURRENT_VERSION "1.1.3"
/*
Everytime a Database SQL is added to Github,
/*
Everytime a Database SQL is added to Github,
increment CURRENT_BINARY_DATABASE_VERSION number and make sure you update the manifest
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9095
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
#else
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
#endif
#define CURRENT_BINARY_DATABASE_VERSION 9076
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32
+8
View File
@@ -28,21 +28,25 @@
WorldConnection::WorldConnection(EmuTCPConnection::ePacketMode mode, const char *password)
: m_password(password)
{
_eqp
tcpc.SetPacketMode(mode);
pTryReconnect = true;
pConnected = false;
}
WorldConnection::~WorldConnection() {
_eqp
}
bool WorldConnection::SendPacket(ServerPacket* pack) {
_eqp
if (!Connected())
return false;
return tcpc.SendPacket(pack);
}
void WorldConnection::OnConnected() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
Log.Out(Logs::General, Logs::Netcode, "[WORLD] Connected to World: %s:%d", Config->WorldIP.c_str(), Config->WorldTCPPort);
@@ -53,6 +57,7 @@ void WorldConnection::OnConnected() {
}
void WorldConnection::Process() {
_eqp
//persistent connection....
if (!Connected()) {
pConnected = tcpc.Connected();
@@ -66,11 +71,13 @@ void WorldConnection::Process() {
}
void WorldConnection::AsyncConnect() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
tcpc.AsyncConnect(Config->WorldIP.c_str(), Config->WorldTCPPort);
}
bool WorldConnection::Connect() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
char errbuf[TCPConnection_ErrorBufferSize];
if (tcpc.Connect(Config->WorldIP.c_str(), Config->WorldTCPPort, errbuf)) {
@@ -82,6 +89,7 @@ bool WorldConnection::Connect() {
}
void WorldConnection::Disconnect() {
_eqp
tcpc.Disconnect();
}
+3
View File
@@ -23,6 +23,7 @@ XMLParser::XMLParser() {
}
bool XMLParser::ParseFile(const char *file, const char *root_ele) {
_eqp
std::map<std::string,ElementHandler>::iterator handler;
TiXmlDocument doc( file );
if(!doc.LoadFile()) {
@@ -70,6 +71,7 @@ bool XMLParser::ParseFile(const char *file, const char *root_ele) {
}
const char *XMLParser::ParseTextBlock(TiXmlNode *within, const char *name, bool optional) {
_eqp
TiXmlElement * txt = within->FirstChildElement(name);
if(txt == nullptr) {
if(!optional) {
@@ -88,6 +90,7 @@ const char *XMLParser::ParseTextBlock(TiXmlNode *within, const char *name, bool
}
const char *XMLParser::GetText(TiXmlNode *within, bool optional) {
_eqp
TiXmlNode *contents = within->FirstChild();
if(contents == nullptr || contents->Type() != TiXmlNode::TEXT) {
if(!optional) {

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