Compare commits

..

1 Commits

Author SHA1 Message Date
KimLS 296d48993e Convert zone points from old style linked list to std 2022-02-14 00:53:56 -08:00
1051 changed files with 88650 additions and 101368 deletions
+2 -13
View File
@@ -7,21 +7,10 @@ name: EQEmulator Server Linux CI
concurrency:
limit: 1
volumes:
- name: cache
host:
path: /var/lib/cache
steps:
- name: server-build
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
image: akkadius/eqemu-server:v11
image: akkadius/eqemu-server:latest
commands:
- sudo chown eqemu:eqemu /drone/src/ * -R
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O0 -g -DNDEBUG" -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
- curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
- ./bin/tests
volumes:
- name: cache
path: /home/eqemu/.ccache/
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
+19
View File
@@ -0,0 +1,19 @@
language: cpp
compiler: gcc
dist: bionic
addons:
apt:
packages:
- libmysqlclient-dev
- libperl-dev
- libboost-dev
- liblua5.1-0-dev
- zlib1g-dev
- uuid-dev
- libssl-dev
script:
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
- make -j2
- ./bin/tests
+9 -9
View File
@@ -12,7 +12,7 @@ IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD 14)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
@@ -20,7 +20,6 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ELSE(MSVC)
@@ -122,6 +121,7 @@ ENDIF()
MESSAGE(STATUS "**************************************************")
#options
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
@@ -186,7 +186,7 @@ IF(MySQL_FOUND AND MariaDB_FOUND)
MySQL
MariaDB"
)
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
@@ -217,7 +217,7 @@ IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
OpenSSL
mbedTLS"
)
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
@@ -357,12 +357,12 @@ ENDIF()
IF(LUA_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
SET(ZONE_LIBS ${LUA_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
@@ -373,7 +373,7 @@ ENDIF()
IF(PERL_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
IF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
@@ -410,13 +410,13 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_H
ADD_SUBDIRECTORY(libs)
ADD_SUBDIRECTORY(submodules/fmt)
ADD_SUBDIRECTORY(submodules/libuv)
IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
ADD_SUBDIRECTORY(libs/zlibng)
ENDIF()
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
+5 -16
View File
@@ -25,15 +25,11 @@
#include "../../common/platform.h"
#include "../../common/crash.h"
#include "../../common/rulesys.h"
#include "../../common/strings.h"
#include "../../common/string_util.h"
#include "../../common/content/world_content_service.h"
#include "../../common/zone_store.h"
#include "../../common/path_manager.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db);
@@ -46,8 +42,6 @@ int main(int argc, char **argv)
LogSys.LoadLogSettingsDefaults();
set_exception_handler();
path.LoadPaths();
LogInfo("Client Files Export Utility");
if (!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file");
@@ -90,7 +84,6 @@ int main(int argc, char **argv)
}
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->StartFileLogs();
@@ -131,8 +124,7 @@ void ExportSpells(SharedDatabase *db)
{
LogInfo("Exporting Spells");
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "w");
FILE *f = fopen("export/spells_us.txt", "w");
if (!f) {
LogError("Unable to open export/spells_us.txt to write, skipping.");
return;
@@ -214,8 +206,7 @@ void ExportSkillCaps(SharedDatabase *db)
{
LogInfo("Exporting Skill Caps");
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "w");
FILE *f = fopen("export/SkillCaps.txt", "w");
if (!f) {
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
return;
@@ -245,8 +236,7 @@ void ExportBaseData(SharedDatabase *db)
{
LogInfo("Exporting Base Data");
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "w");
FILE *f = fopen("export/BaseData.txt", "w");
if (!f) {
LogError("Unable to open export/BaseData.txt to write, skipping.");
return;
@@ -279,8 +269,7 @@ void ExportDBStrings(SharedDatabase *db)
{
LogInfo("Exporting DB Strings");
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "w");
FILE *f = fopen("export/dbstr_us.txt", "w");
if (!f) {
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
return;
+15 -26
View File
@@ -23,15 +23,11 @@
#include "../../common/platform.h"
#include "../../common/crash.h"
#include "../../common/rulesys.h"
#include "../../common/strings.h"
#include "../../common/string_util.h"
#include "../../common/content/world_content_service.h"
#include "../../common/zone_store.h"
#include "../../common/path_manager.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
@@ -43,8 +39,6 @@ int main(int argc, char **argv) {
LogSys.LoadLogSettingsDefaults();
set_exception_handler();
path.LoadPaths();
LogInfo("Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file.");
@@ -87,7 +81,6 @@ int main(int argc, char **argv) {
}
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->StartFileLogs();
@@ -132,10 +125,9 @@ bool IsStringField(int i) {
void ImportSpells(SharedDatabase *db) {
LogInfo("Importing Spells");
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/spells_us.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/spells_us.txt to read, skipping.");
return;
}
@@ -154,8 +146,8 @@ void ImportSpells(SharedDatabase *db) {
}
}
std::string escaped = ::Strings::Escape(buffer);
auto split = Strings::Split(escaped, '^');
std::string escaped = ::EscapeString(buffer);
auto split = SplitString(escaped, '^');
int line_columns = (int)split.size();
std::string sql;
@@ -222,10 +214,9 @@ void ImportSpells(SharedDatabase *db) {
void ImportSkillCaps(SharedDatabase *db) {
LogInfo("Importing Skill Caps");
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/SkillCaps.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
return;
}
@@ -234,7 +225,7 @@ void ImportSkillCaps(SharedDatabase *db) {
char buffer[2048];
while(fgets(buffer, 2048, f)) {
auto split = Strings::Split(buffer, '^');
auto split = SplitString(buffer, '^');
if(split.size() < 4) {
continue;
@@ -258,10 +249,9 @@ void ImportSkillCaps(SharedDatabase *db) {
void ImportBaseData(SharedDatabase *db) {
LogInfo("Importing Base Data");
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/BaseData.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/BaseData.txt to read, skipping.");
return;
}
@@ -270,7 +260,7 @@ void ImportBaseData(SharedDatabase *db) {
char buffer[2048];
while(fgets(buffer, 2048, f)) {
auto split = Strings::Split(buffer, '^');
auto split = SplitString(buffer, '^');
if(split.size() < 10) {
continue;
@@ -304,10 +294,9 @@ void ImportBaseData(SharedDatabase *db) {
void ImportDBStrings(SharedDatabase *db) {
LogInfo("Importing DB Strings");
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
return;
}
@@ -329,7 +318,7 @@ void ImportDBStrings(SharedDatabase *db) {
}
}
auto split = Strings::Split(buffer, '^');
auto split = SplitString(buffer, '^');
if(split.size() < 2) {
continue;
@@ -343,7 +332,7 @@ void ImportDBStrings(SharedDatabase *db) {
type = atoi(split[1].c_str());
if(split.size() >= 3) {
value = ::Strings::Escape(split[2]);
value = ::EscapeString(split[2]);
}
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
+730 -745
View File
File diff suppressed because it is too large Load Diff
+190
View File
@@ -0,0 +1,190 @@
/*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
// EQ::Any is a modified version of Boost::Any and as such retains the Boost licensing.
#ifndef EQEMU_COMMON_ANY_H
#define EQEMU_COMMON_ANY_H
#include <algorithm>
#include <typeinfo>
namespace EQ
{
class Any
{
public:
Any()
: content(nullptr)
{
}
template<typename ValueType>
Any(const ValueType &value)
: content(new Holder<ValueType>(value))
{
}
Any(const Any &other)
: content(other.content ? other.content->clone() : 0)
{
}
~Any()
{
if(content)
delete content;
}
Any& swap(Any &rhs)
{
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType>
Any& operator=(const ValueType &rhs)
{
Any(rhs).swap(*this);
return *this;
}
Any& operator=(Any rhs)
{
rhs.swap(*this);
return *this;
}
bool empty() const
{
return !content;
}
const std::type_info& type() const
{
return content ? content->type() : typeid(void);
}
class Placeholder
{
public:
virtual ~Placeholder()
{
}
virtual const std::type_info& type() const = 0;
virtual Placeholder* clone() const = 0;
};
template<typename ValueType>
class Holder : public Placeholder
{
public:
Holder(const ValueType &value)
: held(value)
{
}
virtual const std::type_info& type() const
{
return typeid(ValueType);
}
virtual Placeholder* clone() const
{
return new Holder(held);
}
ValueType held;
private:
Holder& operator=(const Holder&);
};
private:
template<typename ValueType>
friend ValueType* any_cast(Any*);
template<typename ValueType>
friend ValueType* unsafe_any_cast(Any*);
Placeholder* content;
};
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
}
};
template<typename ValueType>
ValueType* any_cast(Any* operand)
{
return operand &&
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
}
template<typename ValueType>
inline const ValueType* any_cast(const Any* operand)
{
return any_cast<ValueType>(const_cast<Any*>(operand));
}
template<typename ValueType>
ValueType any_cast(Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
nonref* result = any_cast<nonref>(&operand);
if(!result)
throw bad_any_cast();
return *result;
}
template<typename ValueType>
inline ValueType any_cast(const Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
return any_cast<const nonref&>(const_cast<Any&>(operand));
}
template<typename ValueType>
inline ValueType* unsafe_any_cast(Any* operand)
{
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
}
template<typename ValueType>
inline const ValueType* unsafe_any_cast(const Any* operand)
{
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
}
}
#endif
+8 -8
View File
@@ -23,18 +23,18 @@
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
{
pBuffer=nullptr;
size=0;
_wpos = 0;
_rpos = 0;
timestamp.tv_sec = 0;
this->pBuffer=nullptr;
this->size=0;
this->_wpos = 0;
this->_rpos = 0;
this->timestamp.tv_sec = 0;
if (len>0) {
size=len;
this->size=len;
pBuffer= new unsigned char[len];
if (buf) {
memcpy(pBuffer,buf,len);
memcpy(this->pBuffer,buf,len);
} else {
memset(pBuffer,0,len);
memset(this->pBuffer,0,len);
}
}
}
+5 -5
View File
@@ -380,12 +380,12 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Merchant";
case DISCORD_MERCHANT:
return "Discord Merchant";
case ADVENTURE_RECRUITER:
case ADVENTURERECRUITER:
return "Adventure Recruiter";
case ADVENTURE_MERCHANT:
case ADVENTUREMERCHANT:
return "Adventure Merchant";
case LDON_TREASURE:
return "LDoN Treasure";
case CORPSE_CLASS:
return "Corpse Class";
case TRIBUTE_MASTER:
return "Tribute Master";
case GUILD_TRIBUTE_MASTER:
@@ -400,7 +400,7 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Fellowship Master";
case ALT_CURRENCY_MERCHANT:
return "Alternate Currency Merchant";
case MERCENARY_MASTER:
case MERCERNARY_MASTER:
return "Mercenary Liaison";
default:
return "Unknown";
+5 -4
View File
@@ -55,9 +55,10 @@
#define BANKER 40
#define MERCHANT 41
#define DISCORD_MERCHANT 59
#define ADVENTURE_RECRUITER 60
#define ADVENTURE_MERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
#define ADVENTURERECRUITER 60
#define ADVENTUREMERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
#define TRIBUTE_MASTER 63
#define GUILD_TRIBUTE_MASTER 64 // not sure
#define GUILD_BANKER 66
@@ -65,7 +66,7 @@
#define DARK_REIGN_MERCHANT 68
#define FELLOWSHIP_MASTER 69
#define ALT_CURRENCY_MERCHANT 70
#define MERCENARY_MASTER 71
#define MERCERNARY_MASTER 71
// player class values
-45
View File
@@ -22,7 +22,6 @@
#include "../database.h"
#include "../rulesys.h"
#include "../eqemu_logsys.h"
#include "../loottable.h"
#include "../repositories/content_flags_repository.h"
@@ -140,50 +139,6 @@ bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
return false;
}
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
{
for (auto &f: GetContentFlags()) {
if (f.flag_name == content_flag && f.enabled == false) {
return true;
}
}
return false;
}
bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
{
// if we're not set to (-1 All) then fail when we aren't within minimum expansion
if (f.min_expansion > Expansion::EXPANSION_ALL && current_expansion < f.min_expansion && current_expansion != -1) {
return false;
}
// if we're not set to (-1 All) then fail when we aren't within max expansion
if (f.max_expansion > Expansion::EXPANSION_ALL && current_expansion > f.max_expansion && current_expansion != -1) {
return false;
}
// if we don't have any enabled flag in enabled flags, we fail
for (const auto& flag: Strings::Split(f.content_flags)) {
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
return false;
}
}
// if we don't have any disabled flag in disabled flags, we fail
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
return false;
}
}
return true;
}
void WorldContentService::ReloadContentFlags()
{
std::vector<ContentFlagsRepository::ContentFlags> set_content_flags;
+3 -7
View File
@@ -23,7 +23,6 @@
#include <string>
#include <vector>
#include "../loottable.h"
#include "../repositories/content_flags_repository.h"
class Database;
@@ -54,7 +53,7 @@ namespace Expansion {
VeilOfAlaris,
RainOfFear,
CallOfTheForsaken,
TheDarkenedSea,
TheDarkendSea,
TheBrokenMirror,
EmpiresOfKunark,
RingOfScale,
@@ -127,7 +126,7 @@ public:
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheDarkenedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkenedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheDarkendSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkendSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
@@ -155,7 +154,7 @@ public:
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
bool IsCurrentExpansionTheDarkendSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkendSea; }
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
@@ -166,13 +165,10 @@ public:
std::vector<std::string> GetContentFlagsEnabled();
std::vector<std::string> GetContentFlagsDisabled();
bool IsContentFlagEnabled(const std::string& content_flag);
bool IsContentFlagDisabled(const std::string& content_flag);
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
void ReloadContentFlags();
WorldContentService * SetExpansionContext();
bool DoesPassContentFiltering(const ContentFlags& f);
WorldContentService * SetDatabase(Database *database);
Database *GetDatabase() const;
+2 -61
View File
@@ -2,48 +2,6 @@
#include "eqemu_logsys.h"
#include "crash.h"
inline std::string random_string(size_t length)
{
auto randchar = []() -> char {
const char charset[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[static_cast<size_t>(std::rand()) % max_index];
};
std::string str(length, 0);
std::generate_n(str.begin(), length, randchar);
return str;
}
std::string execute(const std::string &cmd, bool return_result = true)
{
std::string random = "/tmp/" + random_string(25);
const char *file_name = random.c_str();
if (return_result) {
#ifdef _WINDOWS
std::system((cmd + " > " + file_name + " 2>&1").c_str());
#else
std::system((cmd + " > " + file_name + " 2>&1").c_str());
#endif
}
else {
std::system((cmd).c_str());
}
std::string result;
if (return_result) {
std::ifstream file(file_name);
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
std::remove(file_name);
}
return result;
}
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
#include "StackWalker.h"
@@ -167,28 +125,10 @@ void set_exception_handler() {
void print_trace()
{
bool does_gdb_exist = execute("gdb -v").find("GNU") != std::string::npos;
if (!does_gdb_exist) {
LogCrash(
"[Error] GDB is not installed, if you want crash dumps on Linux to work properly you will need GDB installed"
);
std::exit(1);
}
auto uid = geteuid();
auto uid = geteuid();
std::string temp_output_file = "/tmp/dump-output";
// check for passwordless sudo if not root
if (uid != 0) {
bool has_passwordless_sudo = execute("sudo -n true").find("a password is required") == std::string::npos;
if (!has_passwordless_sudo) {
LogCrash(
"[Error] Current user does not have passwordless sudo installed. It is required to automatically process crash dumps with GDB as non-root."
);
std::exit(1);
}
}
char pid_buf[30];
sprintf(pid_buf, "%d", getpid());
char name_buf[512];
@@ -196,6 +136,7 @@ void print_trace()
int child_pid = fork();
if (!child_pid) {
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // redirect output to stderr
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
if (uid == 0) {
+349 -258
View File
@@ -45,14 +45,11 @@
#include "database.h"
#include "eq_packet_structs.h"
#include "extprofile.h"
#include "strings.h"
#include "string_util.h"
#include "database_schema.h"
#include "http/httplib.h"
#include "http/uri.h"
#include "repositories/zone_repository.h"
#include "zone_store.h"
extern Client client;
Database::Database () {
@@ -95,123 +92,112 @@ Database::~Database()
*/
uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
if (strlen(name) >= 50 || strlen(password) >= 50)
if(strlen(name) >= 50 || strlen(password) >= 50)
return(0);
char temporary_username[100];
char temporary_password[100];
char tmpUN[100];
char tmpPW[100];
DoEscapeString(temporary_username, name, strlen(name));
DoEscapeString(temporary_password, password, strlen(password));
DoEscapeString(tmpUN, name, strlen(name));
DoEscapeString(tmpPW, password, strlen(password));
std::string query = fmt::format(
"SELECT id, status FROM account WHERE `name` = '{}' AND ls_id = '{}' AND password is NOT NULL "
"AND length(password) > 0 AND (password = '{}' OR password = MD5('{}'))",
temporary_username,
Strings::Escape(loginserver),
temporary_password,
temporary_password
);
std::string query = StringFormat("SELECT id, status FROM account WHERE `name`='%s' AND ls_id='%s' AND password is not null "
"and length(password) > 0 and (password='%s' or password=MD5('%s'))",
tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
if (!results.Success())
{
return 0;
}
if(results.RowCount() == 0)
return 0;
auto row = results.begin();
auto id = std::stoul(row[0]);
uint32 id = atoi(row[0]);
if (oStatus) {
*oStatus = std::stoi(row[1]);
}
if (oStatus)
*oStatus = atoi(row[1]);
return id;
}
//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(std::string login_ip)
bool Database::CheckBannedIPs(const char* loginIP)
{
auto query = fmt::format(
"SELECT ip_address FROM banned_ips WHERE ip_address = '{}'",
login_ip
);
std::string query = StringFormat("SELECT ip_address FROM banned_ips WHERE ip_address='%s'", loginIP);
auto results = QueryDatabase(query);
if (!results.Success() || results.RowCount() != 0) {
if (!results.Success())
{
return true;
}
if (results.RowCount() != 0)
return true;
return false;
}
bool Database::AddBannedIP(std::string banned_ip, std::string notes) {
auto query = fmt::format(
"INSERT into banned_ips SET ip_address = '{}', notes = '{}'",
Strings::Escape(banned_ip),
Strings::Escape(notes)
);
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
std::string query = StringFormat("INSERT into banned_ips SET ip_address='%s', notes='%s'", bannedIP, notes);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
return true;
}
bool Database::CheckGMIPs(std::string login_ip, uint32 account_id) {
auto query = fmt::format(
"SELECT * FROM `gm_ips` WHERE `ip_address` = '{}' AND `account_id` = {}",
login_ip,
account_id
);
bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) {
std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success())
return false;
}
if (results.RowCount() == 1) {
if (results.RowCount() == 1)
return true;
}
return false;
}
void Database::LoginIP(uint32 account_id, std::string login_ip) {
auto query = fmt::format(
"INSERT INTO account_ip SET accid = {}, ip = '{}' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()",
account_id,
login_ip
);
bool Database::AddGMIP(char* ip_address, char* name) {
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) {
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)
{
auto query = fmt::format(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = {}",
account_id
);
auto results = QueryDatabase(query);
std::string query = StringFormat(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i",
account_id);
if (!results.Success() || results.RowCount() != 1) {
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() != 1)
return 0;
}
auto row = results.begin();
int16 status = std::stoi(row[0]);
int16 status = atoi(row[0]);
int32 date_diff = 0;
if (row[1]) {
date_diff = std::stoi(row[1]);
}
if (row[1] != nullptr)
date_diff = atoi(row[1]);
if (date_diff > 0) {
if (date_diff > 0)
return -1;
}
return status;
}
@@ -281,7 +267,7 @@ bool Database::DeleteAccount(const char* name, const char *loginserver) {
}
bool Database::SetLocalPassword(uint32 accid, const char* password) {
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", Strings::Escape(password).c_str(), accid);
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", EscapeString(password).c_str(), accid);
auto results = QueryDatabase(query);
@@ -321,7 +307,9 @@ bool Database::SetAccountStatus(const std::string& account_name, int16 status)
LogInfo("Account [{}] is attempting to be set to status [{}]", account_name, status);
std::string query = fmt::format(
"UPDATE account SET status = {} WHERE name = '{}'",
SQL(
UPDATE account SET status = {} WHERE name = '{}'
),
status,
account_name
);
@@ -376,10 +364,9 @@ bool Database::ReserveName(uint32 account_id, char* name) {
* @param character_name
* @return
*/
bool Database::DeleteCharacter(char *character_name)
{
bool Database::DeleteCharacter(char *character_name) {
uint32 character_id = 0;
if (!character_name || !strlen(character_name)) {
if(!character_name || !strlen(character_name)) {
LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
return false;
}
@@ -391,60 +378,45 @@ bool Database::DeleteCharacter(char *character_name)
}
if (character_id <= 0) {
LogError("[DeleteCharacter] Invalid Character ID [{}]", character_name);
LogError("DeleteCharacter | Invalid Character ID [{}]", character_name);
return false;
}
std::string delete_type = "hard-deleted";
if (RuleB(Character, SoftDeletes)) {
delete_type = "soft-deleted";
std::string query = fmt::format(
SQL(
UPDATE
character_data
SET
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64),
deleted_at = NOW()
WHERE
id = '{}'
),
character_id
);
QueryDatabase(query);
return true;
}
LogInfo("DeleteCharacter | Character [{}] ({}) is being [{}]", character_name, character_id, delete_type);
for (const auto& iter : DatabaseSchema::GetCharacterTables()) {
std::string table_name = iter.first;
std::string character_id_column_name = iter.second;
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
}
#ifdef BOTS
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", character_id); // note: only use of GetMobTypeById()
QueryDatabase(query);
#endif
std::string delete_type = "hard-deleted";
if (RuleB(Character, SoftDeletes)) {
delete_type = "soft-deleted";
query = fmt::format(
SQL(
UPDATE
character_data
SET
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64),
deleted_at = NOW()
WHERE
id = '{}'
),
character_id
);
QueryDatabase(query);
#ifdef BOTS
query = fmt::format(
SQL(
UPDATE
bot_data
SET
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64)
WHERE
owner_id = '{}'
),
character_id
);
QueryDatabase(query);
LogInfo("[DeleteCharacter] character_name [{}] ({}) bots are being [{}]", character_name, character_id, delete_type);
#endif
return true;
}
for (const auto &iter: DatabaseSchema::GetCharacterTables()) {
std::string table_name = iter.first;
std::string character_id_column_name = iter.second;
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
}
LogInfo("[DeleteCharacter] character_name [{}] ({}) is being [{}]", character_name, character_id, delete_type);
return true;
}
@@ -636,8 +608,8 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
")",
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
Strings::Escape(pp->last_name).c_str(), // " last_name, "
EscapeString(pp->name).c_str(), // " `name`, "
EscapeString(pp->last_name).c_str(), // " last_name, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
@@ -661,8 +633,8 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
Strings::Escape(pp->title).c_str(), // " title, "
Strings::Escape(pp->suffix).c_str(), // " suffix, "
EscapeString(pp->title).c_str(), // " title, "
EscapeString(pp->suffix).c_str(), // " suffix, "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
@@ -798,7 +770,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) {
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", Strings::Escape(charname).c_str());
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", EscapeString(charname).c_str());
auto results = QueryDatabase(query);
@@ -835,34 +807,36 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
return atoi(row[0]);
}
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
if (!isAlphaNumeric(account_name.c_str())) {
uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) {
if (!isAlphaNumeric(accname))
return 0;
}
auto query = fmt::format(
"SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '{}' AND `ls_id` = '{}' LIMIT 1",
Strings::Escape(account_name),
Strings::Escape(loginserver)
);
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1",
EscapeString(accname).c_str(), EscapeString(loginserver).c_str());
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
if (!results.Success()) {
return 0;
}
auto row = results.begin();
auto account_id = std::stoul(row[0]);
if (results.RowCount() != 1)
return 0;
if (status) {
*status = static_cast<int16>(std::stoi(row[1]));
}
auto row = results.begin();
uint32 id = atoi(row[0]);
if (status)
*status = atoi(row[1]);
if (lsid) {
*lsid = row[2] ? std::stoul(row[2]) : 0;
if (row[2])
*lsid = atoi(row[2]);
else
*lsid = 0;
}
return account_id;
return id;
}
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
@@ -999,8 +973,8 @@ bool Database::GetVariable(std::string varname, std::string &varvalue)
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
{
std::string escaped_name = Strings::Escape(varname);
std::string escaped_value = Strings::Escape(varvalue);
std::string escaped_name = EscapeString(varname);
std::string escaped_value = EscapeString(varvalue);
std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", escaped_value.c_str(), escaped_name.c_str());
auto results = QueryDatabase(query);
@@ -1023,16 +997,110 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
return true;
}
void Database::SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum)
{
QueryDatabase(
fmt::format(
"UPDATE `account` SET `{}` = '{}' WHERE `id` = {}",
field_name,
checksum,
account_id
)
// Get zone starting points from DB
bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) {
if (zone_short_name == nullptr)
return false;
std::string query = fmt::format(
SQL(
SELECT
`safe_x`, `safe_y`, `safe_z`, `safe_heading`, `min_status`, `min_level`, `flag_needed`
FROM
zone
WHERE
`short_name` = '{}'
AND
(`version` = {} OR `version` = 0)
ORDER BY `version` DESC
), zone_short_name, instance_version
);
auto results = QueryDatabase(query);
if (!results.Success())
return false;
if (results.RowCount() == 0)
return false;
auto row = results.begin();
if (safe_x != nullptr)
*safe_x = atof(row[0]);
if (safe_y != nullptr)
*safe_y = atof(row[1]);
if (safe_z != nullptr)
*safe_z = atof(row[2]);
if (safe_heading != nullptr)
*safe_heading = atof(row[3]);
if (min_status != nullptr)
*min_status = atoi(row[4]);
if (min_level != nullptr)
*min_level = atoi(row[5]);
if (flag_needed != nullptr)
strcpy(flag_needed, row[6]);
return true;
}
bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) {
std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
if (results.RowCount() == 0)
return false;
auto row = results.begin();
if (long_name != nullptr)
*long_name = strcpy(new char[strlen(row[0])+1], row[0]);
if (file_name != nullptr) {
if (row[1] == nullptr)
strcpy(file_name, short_name);
else
strcpy(file_name, row[1]);
}
if (safe_x != nullptr)
*safe_x = atof(row[2]);
if (safe_y != nullptr)
*safe_y = atof(row[3]);
if (safe_z != nullptr)
*safe_z = atof(row[4]);
if (graveyard_id != nullptr)
*graveyard_id = atoi(row[5]);
if (maxclients != nullptr)
*maxclients = atoi(row[6]);
return true;
}
uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
std::string query = StringFormat("SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
@@ -1063,74 +1131,108 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
return true;
}
uint8 Database::GetPEQZone(uint32 zone_id, uint32 version){
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
auto z = GetZoneVersionWithFallback(zone_id, version);
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);
return z ? z->peqzone : 0;
if (!results.Success()) {
return 0;
}
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
bool Database::CheckNameFilter(std::string name, bool surname)
bool Database::CheckNameFilter(const char* name, bool surname)
{
name = Strings::ToLower(name);
std::string str_name = name;
// the minimum 4 is enforced by the client too
if (name.empty() || name.size() < 4) {
if (!name || strlen(name) < 4)
{
return false;
}
// Given name length is enforced by the client too
if (!surname && name.size() > 15) {
if (!surname && strlen(name) > 15)
{
return false;
}
for (size_t i = 0; i < name.size(); i++) {
if (!isalpha(name[i])) {
for (size_t i = 0; i < str_name.size(); i++)
{
if(!isalpha(str_name[i]))
{
return false;
}
}
for(size_t x = 0; x < str_name.size(); ++x)
{
str_name[x] = tolower(str_name[x]);
}
char c = '\0';
uint8 num_c = 0;
for (size_t x = 0; x < name.size(); ++x) {
if (name[x] == c) {
for(size_t x = 0; x < str_name.size(); ++x)
{
if(str_name[x] == c)
{
num_c++;
} else {
num_c = 1;
c = name[x];
}
if (num_c > 2) {
else
{
num_c = 1;
c = str_name[x];
}
if(num_c > 2)
{
return false;
}
}
std::string query = "SELECT name FROM name_filter";
std::string query("SELECT name FROM name_filter");
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success())
{
// false through to true? shouldn't it be falls through to false?
return true;
}
for (auto row : results) {
std::string current_row = Strings::ToLower(row[0]);
if (name.find(current_row) != std::string::npos) {
for (auto row = results.begin();row != results.end();++row)
{
std::string current_row = row[0];
for(size_t x = 0; x < current_row.size(); ++x)
current_row[x] = tolower(current_row[x]);
if(str_name.find(current_row) != std::string::npos)
return false;
}
}
return true;
}
bool Database::AddToNameFilter(std::string name) {
auto query = fmt::format(
"INSERT INTO name_filter (name) values ('{}')",
name
);
bool Database::AddToNameFilter(const char* name) {
std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowsAffected()) {
if (!results.Success())
{
return false;
}
if (results.RowsAffected() == 0)
return false;
return true;
}
@@ -1218,16 +1320,16 @@ 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(std::string name) {
auto query = fmt::format(
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
name
);
bool Database::CheckUsedName(const char* name) {
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
if (!results.Success() || results.RowCount()) {
if (!results.Success()) {
return false;
}
if (results.RowCount() > 0)
return false;
return true;
}
@@ -1385,25 +1487,41 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
return base_cap;
}
uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id)
uint32 Database::GetCharacterInfo(
const char *iName,
uint32 *oAccID,
uint32 *oZoneID,
uint32 *oInstanceID,
float *oX,
float *oY,
float *oZ
)
{
auto query = fmt::format(
"SELECT `id`, `account_id`, `zone_id`, `zone_instance` FROM `character_data` WHERE `name` = '{}'",
Strings::Escape(character_name)
std::string query = StringFormat(
"SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'",
EscapeString(iName).c_str()
);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
if (!results.Success()) {
return 0;
}
auto row = results.begin();
auto character_id = std::stoul(row[0]);
*account_id = std::stoul(row[1]);
*zone_id = std::stoul(row[2]);
*instance_id = std::stoul(row[3]);
if (results.RowCount() != 1) {
return 0;
}
return character_id;
auto row = results.begin();
uint32 charid = atoi(row[0]);
if (oAccID) { *oAccID = atoi(row[1]); }
if (oZoneID) { *oZoneID = atoi(row[2]); }
if (oInstanceID) { *oInstanceID = atoi(row[3]); }
if (oX) { *oX = atof(row[4]); }
if (oY) { *oY = atof(row[5]); }
if (oZ) { *oZ = atof(row[6]); }
return charid;
}
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
@@ -1462,7 +1580,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
auto 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')", Strings::Escape(who).c_str(), Strings::Escape(against).c_str(), escape_str);
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);
QueryDatabase(query);
safe_delete_array(escape_str);
}
@@ -1527,40 +1645,33 @@ uint32 Database::GetGroupID(const char* name){
return atoi(row[0]);
}
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
/* Is this really getting used properly... A half implementation ? Akkadius */
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
strcpy(leaderbuf, "");
uint32 group_id = 0;
auto query = fmt::format(
"SELECT `groupid` FROM `group_id` WHERE `name` = '{}'",
character_name
);
std::string query = StringFormat("SELECT `groupid` FROM `group_id` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
if (results.Success() && results.RowCount()) {
auto row = results.begin();
group_id = std::stoul(row[0]);
}
for (auto row = results.begin(); row != results.end(); ++row)
if (row[0])
group_id = atoi(row[0]);
if (!group_id) {
return std::string();
}
if (group_id == 0)
return leaderbuf;
query = fmt::format(
"SELECT `leadername` FROM `group_leaders` WHERE `gid` = {} LIMIT 1",
group_id
);
query = StringFormat("SELECT `leadername` FROM `group_leaders` WHERE `gid` = '%u' LIMIT 1", group_id);
results = QueryDatabase(query);
if (results.Success() && results.RowCount()) {
auto row = results.begin();
return row[0];
}
for (auto row = results.begin(); row != results.end(); ++row)
if (row[0])
strcpy(leaderbuf, row[0]);
return std::string();
return leaderbuf;
}
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", Strings::Escape(name).c_str(), gid);
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", EscapeString(name).c_str(), gid);
auto result = QueryDatabase(query);
if(result.RowsAffected() != 0) {
@@ -1568,7 +1679,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
}
query = StringFormat("REPLACE INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')",
gid, Strings::Escape(name).c_str());
gid, EscapeString(name).c_str());
result = QueryDatabase(query);
if(!result.Success()) {
@@ -2151,48 +2262,43 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year
}
int Database::GetIPExemption(std::string account_ip) {
auto query = fmt::format(
"SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
account_ip
);
std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str());
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return RuleI(World, MaxClientsPerIP);
if (results.Success() && results.RowCount() > 0) {
auto row = results.begin();
return atoi(row[0]);
}
auto row = results.begin();
return std::stoi(row[0]);
return RuleI(World, MaxClientsPerIP);
}
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
auto query = fmt::format(
std::string query = fmt::format(
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
account_ip
);
uint32 exemption_id = 0;
auto results = QueryDatabase(query);
if (results.Success() && results.RowCount()) {
uint32 exemption_id = 0;
if (results.Success() && results.RowCount() > 0) {
auto row = results.begin();
exemption_id = std::stoul(row[0]);
exemption_id = atoi(row[0]);
}
query = fmt::format(
"INSERT INTO `ip_exemptions` (`exemption_ip`, `exemption_amount`) VALUES ('{}', {})",
account_ip,
exemption_amount
);
if (exemption_id) {
if (exemption_id != 0) {
query = fmt::format(
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
exemption_amount,
account_ip
);
}
QueryDatabase(query);
}
@@ -2215,9 +2321,9 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
* @return
*/
bool Database::CopyCharacter(
const std::string& source_character_name,
const std::string& destination_character_name,
const std::string& destination_account_name
std::string source_character_name,
std::string destination_character_name,
std::string destination_account_name
)
{
auto results = QueryDatabase(
@@ -2229,7 +2335,6 @@ bool Database::CopyCharacter(
if (results.RowCount() == 0) {
LogError("No character found with name [{}]", source_character_name);
return false;
}
auto row = results.begin();
@@ -2244,7 +2349,6 @@ bool Database::CopyCharacter(
if (results.RowCount() == 0) {
LogError("No account found with name [{}]", destination_account_name);
return false;
}
row = results.begin();
@@ -2276,7 +2380,7 @@ bool Database::CopyCharacter(
results = QueryDatabase(
fmt::format(
"SELECT {} FROM {} WHERE {} = {}",
Strings::Implode(",", Strings::Wrap(columns, "`")),
implode(",", wrap(columns, "`")),
table_name,
character_id_column_name,
source_character_id
@@ -2312,7 +2416,7 @@ bool Database::CopyCharacter(
std::vector<std::string> insert_rows;
for (auto &r: new_rows) {
std::string insert_row = "(" + Strings::Implode(",", Strings::Wrap(r, "'")) + ")";
std::string insert_row = "(" + implode(",", wrap(r, "'")) + ")";
insert_rows.emplace_back(insert_row);
}
@@ -2330,8 +2434,8 @@ bool Database::CopyCharacter(
fmt::format(
"INSERT INTO {} ({}) VALUES {}",
table_name,
Strings::Implode(",", Strings::Wrap(columns, "`")),
Strings::Implode(",", insert_rows)
implode(",", wrap(columns, "`")),
implode(",", insert_rows)
)
);
@@ -2383,8 +2487,8 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
if (auto res = cli.Get(request_uri.get_path().c_str())) {
if (res->status == 200) {
for (auto &s: Strings::Split(res->body, ';')) {
if (!Strings::Trim(s).empty()) {
for (auto &s: SplitString(res->body, ';')) {
if (!trim(s).empty()) {
auto results = QueryDatabase(s);
if (!results.ErrorMessage().empty()) {
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
@@ -2412,16 +2516,3 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
}
}
uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
{
auto zones = ZoneRepository::GetWhere(
*this,
fmt::format(
"zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1",
zone_id,
instance_version
)
);
return !zones.empty() ? zones[0].min_status : 0;
}
+20 -18
View File
@@ -88,6 +88,7 @@ public:
/* Character Creation */
bool AddToNameFilter(const char *name);
bool CreateCharacter(
uint32 account_id,
char *name,
@@ -113,25 +114,25 @@ public:
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
bool UpdateName(const char *oldname, const char *newname);
bool CopyCharacter(
const std::string& source_character_name,
const std::string& destination_character_name,
const std::string& destination_account_name
std::string source_character_name,
std::string destination_character_name,
std::string destination_account_name
);
/* General Information Queries */
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
bool AddToNameFilter(std::string name);
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
bool CheckGMIPs(std::string login_ip, uint32 account_id);
bool CheckNameFilter(std::string name, bool surname = false);
bool CheckUsedName(std::string name);
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
bool AddGMIP(char* ip_address, char* name);
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
bool CheckGMIPs(const char* loginIP, uint32 account_id);
bool CheckNameFilter(const char* name, bool surname = false);
bool CheckUsedName(const char* name);
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const char *name);
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
uint32 GetGuildIDByCharID(uint32 char_id);
uint32 GetGroupIDByCharID(uint32 char_id);
uint32 GetRaidIDByCharID(uint32 char_id);
@@ -141,7 +142,7 @@ public:
std::string GetCharNameByID(uint32 char_id);
std::string GetNPCNameByID(uint32 npc_id);
std::string GetCleanNPCNameByID(uint32 npc_id);
void LoginIP(uint32 account_id, std::string login_ip);
void LoginIP(uint32 AccountID, const char* LoginIP);
/* Instancing */
@@ -189,8 +190,6 @@ public:
int16 CheckStatus(uint32 account_id);
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
@@ -207,8 +206,8 @@ public:
/* Groups */
std::string GetGroupLeaderForLogin(std::string character_name);
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
uint32 GetGroupID(const char* name);
@@ -246,11 +245,14 @@ public:
/* General Queries */
bool GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, float* safe_heading = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr);
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0);
bool LoadPTimers(uint32 charid, PTimerList &into);
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
uint8 GetPEQZone(uint32 zoneID, uint32 version);
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
uint8 GetServerType();
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
+12 -42
View File
@@ -23,10 +23,10 @@
#include <iterator>
#include "database_dump_service.h"
#include "../eqemu_logsys.h"
#include "../strings.h"
#include "../string_util.h"
#include "../eqemu_config.h"
#include "../database_schema.h"
#include "../file.h"
#include "../file_util.h"
#include <ctime>
@@ -119,7 +119,7 @@ std::string DatabaseDumpService::GetMySQLVersion()
{
std::string version_output = execute("mysql --version");
return Strings::Trim(version_output);
return trim(version_output);
}
/**
@@ -160,21 +160,7 @@ std::string DatabaseDumpService::GetPlayerTablesList()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
}
/**
* @return
*/
std::string DatabaseDumpService::GetBotTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetBotTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
@@ -188,7 +174,7 @@ std::string DatabaseDumpService::GetLoginTableList()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
@@ -202,7 +188,7 @@ std::string DatabaseDumpService::GetQueryServTables()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
@@ -222,7 +208,7 @@ std::string DatabaseDumpService::GetSystemTablesList()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
* @return
@@ -236,7 +222,7 @@ std::string DatabaseDumpService::GetStateTablesList()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
@@ -251,7 +237,7 @@ std::string DatabaseDumpService::GetContentTablesList()
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return trim(tables_list);
}
/**
@@ -332,11 +318,6 @@ void DatabaseDumpService::Dump()
dump_descriptor += "-player";
}
if (IsDumpBotTables()) {
tables_to_dump += GetBotTablesList() + " ";
dump_descriptor += "-bots";
}
if (IsDumpSystemTables()) {
tables_to_dump += GetSystemTablesList() + " ";
dump_descriptor += "-system";
@@ -383,12 +364,12 @@ void DatabaseDumpService::Dump()
pipe_file
);
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
File::Makedir(GetSetDumpPath());
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
FileUtil::mkdir(GetSetDumpPath());
}
if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
std::vector<std::string> tables = SplitString(tables_to_dump, ' ');
for (auto &table : tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
@@ -455,7 +436,6 @@ void DatabaseDumpService::Dump()
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
}
bool DatabaseDumpService::IsDumpSystemTables() const
@@ -597,13 +577,3 @@ void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
{
DatabaseDumpService::dump_state_tables = dump_state_tables;
}
bool DatabaseDumpService::IsDumpBotTables() const
{
return dump_bot_tables;
}
void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
{
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
}
-4
View File
@@ -53,8 +53,6 @@ public:
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
bool IsDumpStateTables() const;
void SetDumpStateTables(bool dump_state_tables);
bool IsDumpBotTables() const;
void SetDumpBotTables(bool dump_bot_tables);
private:
bool dump_all_tables = false;
@@ -69,7 +67,6 @@ private:
bool dump_with_compression = false;
bool dump_output_to_console = false;
bool dump_drop_table_syntax_only = false;
bool dump_bot_tables = false;
std::string dump_path;
std::string dump_file_name;
@@ -78,7 +75,6 @@ private:
std::string GetMySQLVersion();
std::string GetBaseMySQLDumpCommand();
std::string GetPlayerTablesList();
std::string GetBotTablesList();
std::string GetSystemTablesList();
std::string GetStateTablesList();
std::string GetContentTablesList();
+96 -99
View File
@@ -18,12 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/global_define.h"
#include "../common/rulesys.h"
#include "../common/strings.h"
#include "../common/string_util.h"
#include "../common/timer.h"
#include "database.h"
#include "extprofile.h"
#include "path_manager.h"
#include <iomanip>
#include <iostream>
@@ -477,9 +476,7 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertCorpseDeblob();
/* Run EQEmu Server script (Checks for database updates) */
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
system(fmt::format("perl {} ran_from_world", file).c_str());
system("perl eqemu_server.pl ran_from_world");
return true;
}
@@ -964,7 +961,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)"
"VALUES (%u, '%s')",
character_id,
Strings::Escape(inspectmessage).c_str()
EscapeString(inspectmessage).c_str()
);
auto results = QueryDatabase(rquery);
}
@@ -1100,95 +1097,95 @@ bool Database::CheckDatabaseConvertPPDeblob(){
"e_expended_aa_spent"
")"
"VALUES ("
"%u," // id
"%u," // account_id
"'%s'," // `name`
"'%s'," // last_name
"%u," // gender
"%u," // race
"%u," // class
"%u," // `level`
"%u," // deity
"%u," // birthday
"%u," // last_login
"%u," // time_played
"%u," // pvp_status
"%u," // level2
"%u," // anon
"%u," // gm
"%u," // intoxication
"%u," // hair_color
"%u," // beard_color
"%u," // eye_color_1
"%u," // eye_color_2
"%u," // hair_style
"%u," // beard
"%u," // ability_time_seconds
"%u," // ability_number
"%u," // ability_time_minutes
"%u," // ability_time_hours
"'%s'," // title
"'%s'," // suffix
"%u," // exp
"%u," // points
"%u," // mana
"%u," // cur_hp
"%u," // str
"%u," // sta
"%u," // cha
"%u," // dex
"%u," // `int`
"%u," // agi
"%u," // wis
"%u," // face
"%f," // y
"%f," // x
"%f," // z
"%f," // heading
"%u," // pvp2
"%u," // pvp_type
"%u," // autosplit_enabled
"%u," // zone_change_count
"%u," // drakkin_heritage
"%u," // drakkin_tattoo
"%u," // drakkin_details
"%i," // toxicity
"%u," // hunger_level
"%u," // thirst_level
"%u," // ability_up
"%u," // zone_id
"%u," // zone_instance
"%u," // leadership_exp_on
"%u," // ldon_points_guk
"%u," // ldon_points_mir
"%u," // ldon_points_mmc
"%u," // ldon_points_ruj
"%u," // ldon_points_tak
"%u," // ldon_points_available
"%u," // tribute_time_remaining
"%u," // show_helm
"%u," // career_tribute_points
"%u," // tribute_points
"%u," // tribute_active
"%u," // endurance
"%u," // group_leadership_exp
"%u," // raid_leadership_exp
"%u," // group_leadership_points
"%u," // raid_leadership_points
"%u," // air_remaining
"%u," // pvp_kills
"%u," // pvp_deaths
"%u," // pvp_current_points
"%u," // pvp_career_points
"%u," // pvp_best_kill_streak
"%u," // pvp_worst_death_streak
"%u," // pvp_current_kill_streak
"%u," // aa_points_spent
"%u," // aa_exp
"%u," // aa_points
"%u," // group_auto_consent
"%u," // raid_auto_consent
"%u," // guild_auto_consent
"%u," // id
"%u," // account_id
"'%s'," // `name`
"'%s'," // last_name
"%u," // gender
"%u," // race
"%u," // class
"%u," // `level`
"%u," // deity
"%u," // birthday
"%u," // last_login
"%u," // time_played
"%u," // pvp_status
"%u," // level2
"%u," // anon
"%u," // gm
"%u," // intoxication
"%u," // hair_color
"%u," // beard_color
"%u," // eye_color_1
"%u," // eye_color_2
"%u," // hair_style
"%u," // beard
"%u," // ability_time_seconds
"%u," // ability_number
"%u," // ability_time_minutes
"%u," // ability_time_hours
"'%s'," // title
"'%s'," // suffix
"%u," // exp
"%u," // points
"%u," // mana
"%u," // cur_hp
"%u," // str
"%u," // sta
"%u," // cha
"%u," // dex
"%u," // `int`
"%u," // agi
"%u," // wis
"%u," // face
"%f," // y
"%f," // x
"%f," // z
"%f," // heading
"%u," // pvp2
"%u," // pvp_type
"%u," // autosplit_enabled
"%u," // zone_change_count
"%u," // drakkin_heritage
"%u," // drakkin_tattoo
"%u," // drakkin_details
"%i," // toxicity
"%u," // hunger_level
"%u," // thirst_level
"%u," // ability_up
"%u," // zone_id
"%u," // zone_instance
"%u," // leadership_exp_on
"%u," // ldon_points_guk
"%u," // ldon_points_mir
"%u," // ldon_points_mmc
"%u," // ldon_points_ruj
"%u," // ldon_points_tak
"%u," // ldon_points_available
"%u," // tribute_time_remaining
"%u," // show_helm
"%u," // career_tribute_points
"%u," // tribute_points
"%u," // tribute_active
"%u," // endurance
"%u," // group_leadership_exp
"%u," // raid_leadership_exp
"%u," // group_leadership_points
"%u," // raid_leadership_points
"%u," // air_remaining
"%u," // pvp_kills
"%u," // pvp_deaths
"%u," // pvp_current_points
"%u," // pvp_career_points
"%u," // pvp_best_kill_streak
"%u," // pvp_worst_death_streak
"%u," // pvp_current_kill_streak
"%u," // aa_points_spent
"%u," // aa_exp
"%u," // aa_points
"%u," // group_auto_consent
"%u," // raid_auto_consent
"%u," // guild_auto_consent
"%u," // RestTimer
"%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt
"%u," // Looking for Group
@@ -1201,8 +1198,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
")",
character_id,
account_id,
Strings::Escape(pp->name).c_str(),
Strings::Escape(pp->last_name).c_str(),
EscapeString(pp->name).c_str(),
EscapeString(pp->last_name).c_str(),
pp->gender,
pp->race,
pp->class_,
@@ -1226,8 +1223,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
pp->ability_number,
pp->ability_time_minutes,
pp->ability_time_hours,
Strings::Escape(pp->title).c_str(),
Strings::Escape(pp->suffix).c_str(),
EscapeString(pp->title).c_str(),
EscapeString(pp->suffix).c_str(),
pp->exp,
pp->points,
pp->mana,
+3 -3
View File
@@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/global_define.h"
#include "../common/rulesys.h"
#include "../common/strings.h"
#include "../common/string_util.h"
#include "../common/timer.h"
#include "../common/repositories/dynamic_zone_members_repository.h"
#include "../common/repositories/dynamic_zones_repository.h"
@@ -485,7 +485,7 @@ void Database::BuryCorpsesInInstance(uint16 instance_id) {
void Database::DeleteInstance(uint16 instance_id)
{
std::string query;
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
QueryDatabase(query);
@@ -580,7 +580,7 @@ void Database::PurgeExpiredInstances()
instance_ids.emplace_back(row[0]);
}
std::string imploded_instance_ids = Strings::Implode(",", instance_ids);
std::string imploded_instance_ids = implode(",", instance_ids);
QueryDatabase(fmt::format("DELETE FROM instance_list WHERE id IN ({})", imploded_instance_ids));
QueryDatabase(fmt::format("DELETE FROM instance_list_player WHERE id IN ({})", imploded_instance_ids));
+2 -39
View File
@@ -62,7 +62,6 @@ namespace DatabaseSchema {
{"character_pet_buffs", "char_id"},
{"character_pet_info", "char_id"},
{"character_pet_inventory", "char_id"},
{"character_peqzone_flags", "id"},
{"character_potionbelt", "id"},
{"character_skills", "id"},
{"character_spells", "id"},
@@ -130,7 +129,6 @@ namespace DatabaseSchema {
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_peqzone_flags",
"character_potionbelt",
"character_skills",
"character_spells",
@@ -189,14 +187,13 @@ namespace DatabaseSchema {
"char_create_point_allocations",
"damageshieldtypes",
"doors",
"dynamic_zone_templates",
"faction_association",
"faction_base_data",
"faction_list",
"faction_list_mod",
"fishing",
"forage",
"global_loot",
"goallists",
"graveyard",
"grid",
"grid_entries",
@@ -225,6 +222,7 @@ namespace DatabaseSchema {
"pets_beastlord_data",
"pets_equipmentset",
"pets_equipmentset_entries",
"proximities",
"skill_caps",
"spawn2",
"spawn_conditions",
@@ -318,7 +316,6 @@ namespace DatabaseSchema {
"completed_shared_task_activity_state",
"completed_shared_task_members",
"completed_shared_tasks",
"discord_webhooks",
"dynamic_zone_members",
"dynamic_zones",
"eventlog",
@@ -377,40 +374,6 @@ namespace DatabaseSchema {
};
}
/**
* @description Gets all player bot tables
* @note These tables have no content in the PEQ daily dump
*
* @return
*/
static std::vector<std::string> GetBotTables()
{
return {
"bot_buffs",
"bot_command_settings",
"bot_create_combinations",
"bot_data",
"bot_group_members",
"bot_groups",
"bot_guild_members",
"bot_heal_rotation_members",
"bot_heal_rotation_targets",
"bot_heal_rotations",
"bot_inspect_messages",
"bot_inventories",
"bot_owner_options",
"bot_pet_buffs",
"bot_pet_inventories",
"bot_pets",
"bot_spell_casting_chances",
"bot_spells_entries",
"bot_stances",
"bot_timers",
"vw_bot_character_mobs",
"vw_bot_groups"
};
}
}
#endif //EQEMU_DATABASE_SCHEMA_H
+2 -2
View File
@@ -167,7 +167,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) {
LogMySQLQuery(
"{0}; -- ({1} row{2} returned) ({3}s)",
"{0} ({1} row{2} returned) ({3}s)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
@@ -176,7 +176,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
}
else {
LogMySQLQuery(
"{0}; -- ({1} row{2} affected) ({3}s)",
"{0} ({1} row{2} affected) ({3}s)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
-91
View File
@@ -1,91 +0,0 @@
#include "discord.h"
#include "../http/httplib.h"
#include "../json/json.h"
#include "../strings.h"
#include "../eqemu_logsys.h"
constexpr int MAX_RETRIES = 10;
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return;
}
// validate
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
return;
}
// split
auto s = Strings::Split(webhook_url, '/');
// url
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
// client
httplib::Client cli(base_url.c_str());
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// payload
Json::Value p;
p["content"] = message;
std::stringstream payload;
payload << p;
bool retry = true;
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
}
if (res->status == 429) {
if (!res->body.empty()) {
std::stringstream ss(res->body);
Json::Value response;
try {
ss >> response;
}
catch (std::exception const &ex) {
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
}
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
}
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
}
if (res->status == 204) {
retry = false;
}
if (retries > MAX_RETRIES) {
LogDiscord("Retries exceeded for message [{}]", message);
retry = false;
}
retries++;
}
}
}
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
{
if (category_id == Logs::LogCategory::MySQLQuery) {
return fmt::format("```sql\n{}\n```", message);
}
return message + "\n";
}
-15
View File
@@ -1,15 +0,0 @@
#ifndef EQEMU_DISCORD_H
#define EQEMU_DISCORD_H
#include <string>
#include "../types.h"
class Discord {
public:
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
};
#endif //EQEMU_DISCORD_H
-69
View File
@@ -1,69 +0,0 @@
#include "discord_manager.h"
#include "../common/discord/discord.h"
#include "../common/eqemu_logsys.h"
#include "../common/strings.h"
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
{
webhook_queue_lock.lock();
webhook_message_queue[webhook_id].emplace_back(message);
webhook_queue_lock.unlock();
}
constexpr int MAX_MESSAGE_LENGTH = 1900;
void DiscordManager::ProcessMessageQueue()
{
if (webhook_message_queue.empty()) {
return;
}
webhook_queue_lock.lock();
for (auto &q: webhook_message_queue) {
LogDiscord("Processing [{}] messages in queue for webhook ID [{}]...", q.second.size(), q.first);
if (q.first >= MAX_DISCORD_WEBHOOK_ID) {
LogDiscord("Out of bounds webhook ID [{}] max [{}]", q.first, MAX_DISCORD_WEBHOOK_ID);
continue;
}
auto webhook = LogSys.GetDiscordWebhooks()[q.first];
std::string message;
for (auto &m: q.second) {
// next message would become too large
bool next_message_too_large = ((int) m.length() + (int) message.length()) > MAX_MESSAGE_LENGTH;
if (next_message_too_large) {
Discord::SendWebhookMessage(
message,
webhook.webhook_url
);
message = "";
}
message += m;
// one single message was too large
// this should rarely happen but the message will need to be split
if ((int) message.length() > MAX_MESSAGE_LENGTH) {
for (unsigned mi = 0; mi < message.length(); mi += MAX_MESSAGE_LENGTH) {
Discord::SendWebhookMessage(
message.substr(mi, MAX_MESSAGE_LENGTH),
webhook.webhook_url
);
}
message = "";
}
}
// final flush
if (!message.empty()) {
Discord::SendWebhookMessage(
message,
webhook.webhook_url
);
}
}
webhook_message_queue.clear();
webhook_queue_lock.unlock();
}
-19
View File
@@ -1,19 +0,0 @@
#ifndef EQEMU_DISCORD_MANAGER_H
#define EQEMU_DISCORD_MANAGER_H
#include <mutex>
#include <map>
#include <vector>
#include "../common/types.h"
class DiscordManager {
public:
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
void ProcessMessageQueue();
private:
std::mutex webhook_queue_lock{};
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
};
#endif
-49
View File
@@ -79,7 +79,6 @@ void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneIn
m_max_players = dz_entry.max_players;
m_instance_id = dz_entry.instance_id;
m_type = static_cast<DynamicZoneType>(dz_entry.type);
m_dz_switch_id = dz_entry.dz_switch_id;
m_compass.zone_id = dz_entry.compass_zone_id;
m_compass.x = dz_entry.compass_x;
m_compass.y = dz_entry.compass_y;
@@ -130,7 +129,6 @@ uint32_t DynamicZoneBase::SaveToDatabase()
insert_dz.max_players = m_max_players;
insert_dz.instance_id = m_instance_id,
insert_dz.type = static_cast<int>(m_type);
insert_dz.dz_switch_id = m_dz_switch_id;
insert_dz.compass_zone_id = m_compass.zone_id;
insert_dz.compass_x = m_compass.x;
insert_dz.compass_y = m_compass.y;
@@ -318,17 +316,6 @@ void DynamicZoneBase::SetZoneInLocation(float x, float y, float z, float heading
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
}
void DynamicZoneBase::SetSwitchID(int dz_switch_id, bool update_db)
{
m_dz_switch_id = dz_switch_id;
if (update_db)
{
DynamicZonesRepository::UpdateSwitchID(GetDatabase(), m_id, dz_switch_id);
SendServerPacket(CreateServerDzSwitchIDPacket().get());
}
}
void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update_db)
{
m_leader = new_leader;
@@ -416,17 +403,6 @@ std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzLocationPacket(
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzSwitchIDPacket()
{
constexpr uint32_t pack_size = sizeof(ServerDzSwitchID_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSetSwitchID, pack_size);
auto buf = reinterpret_cast<ServerDzSwitchID_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->dz_switch_id = GetSwitchID();
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberStatusPacket(
uint32_t character_id, DynamicZoneMemberStatus status)
{
@@ -622,28 +598,3 @@ void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_
cereal::BinaryInputArchive archive(ss);
archive(*this);
}
void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template)
{
m_zone_id = dz_template.zone_id;
m_zone_version = dz_template.zone_version;
m_name = dz_template.name;
m_min_players = dz_template.min_players;
m_max_players = dz_template.max_players;
m_duration = std::chrono::seconds(dz_template.duration_seconds);
m_dz_switch_id = dz_template.dz_switch_id;
m_compass.zone_id = dz_template.compass_zone_id;
m_compass.x = dz_template.compass_x;
m_compass.y = dz_template.compass_y;
m_compass.z = dz_template.compass_z;
m_safereturn.zone_id = dz_template.return_zone_id;
m_safereturn.x = dz_template.return_x;
m_safereturn.y = dz_template.return_y;
m_safereturn.z = dz_template.return_z;
m_safereturn.heading = dz_template.return_h;
m_has_zonein = dz_template.override_zone_in;
m_zonein.x = dz_template.zone_in_x;
m_zonein.y = dz_template.zone_in_y;
m_zonein.z = dz_template.zone_in_z;
m_zonein.heading = dz_template.zone_in_h;
}
-9
View File
@@ -5,7 +5,6 @@
#include "net/packet.h"
#include "repositories/dynamic_zones_repository.h"
#include "repositories/dynamic_zone_members_repository.h"
#include "repositories/dynamic_zone_templates_repository.h"
#include <algorithm>
#include <chrono>
#include <cstdint>
@@ -75,7 +74,6 @@ public:
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
int GetDuration() const { return static_cast<int>(m_duration.count()); }
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
uint32_t GetID() const { return m_id; }
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
@@ -87,7 +85,6 @@ public:
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
uint32_t GetZoneVersion() const { return m_zone_version; }
int GetSwitchID() const { return m_dz_switch_id; }
DynamicZoneType GetType() const { return m_type; }
const std::string& GetLeaderName() const { return m_leader.name; }
const std::string& GetName() const { return m_name; }
@@ -115,7 +112,6 @@ public:
bool IsValid() const { return m_instance_id != 0; }
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
void RemoveAllMembers();
bool RemoveMember(uint32_t character_id);
bool RemoveMember(const std::string& character_name);
@@ -131,7 +127,6 @@ public:
void SetName(const std::string& name) { m_name = name; }
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
void SetSwitchID(int dz_switch_id, bool update_db = false);
void SetType(DynamicZoneType type) { m_type = type; }
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
@@ -146,7 +141,6 @@ protected:
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
virtual void ProcessSetSwitchID(int dz_switch_id) { m_dz_switch_id = dz_switch_id; }
virtual bool SendServerPacket(ServerPacket* packet) = 0;
void AddInternalMember(const DynamicZoneMember& member);
@@ -159,7 +153,6 @@ protected:
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
std::unique_ptr<ServerPacket> CreateServerDzSwitchIDPacket();
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
@@ -171,7 +164,6 @@ protected:
uint32_t m_zone_version = 0;
uint32_t m_min_players = 0;
uint32_t m_max_players = 0;
int m_dz_switch_id = 0;
bool m_never_expires = false;
bool m_has_zonein = false;
bool m_has_member_statuses = false;
@@ -198,7 +190,6 @@ public:
m_zone_version,
m_min_players,
m_max_players,
m_dz_switch_id,
m_never_expires,
m_has_zonein,
m_has_member_statuses,
+30 -227
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -18,12 +18,10 @@
*/
#include "emu_constants.h"
#include "bodytypes.h"
#include "data_verification.h"
#include "eqemu_logsys.h"
#include "eqemu_logsys_log_aliases.h"
#include "languages.h"
#include "rulesys.h"
#include "data_verification.h"
#include "bodytypes.h"
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
static const int16 local_array[] = {
@@ -120,7 +118,7 @@ EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name)
return catLoNTCG;
if (!strcmp(category_name, "Mercenaries"))
return catMercenaries;
return catOther;
}
@@ -191,16 +189,15 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
{ LANG_HADAL, "Hadal" },
{ LANG_UNKNOWN, "Unknown" }
};
return language_map;
}
std::string EQ::constants::GetLanguageName(int language_id)
{
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return EQ::constants::GetLanguageMap().find(language_id)->second;
auto languages = EQ::constants::GetLanguageMap();
return languages[language_id];
}
return std::string();
}
@@ -214,22 +211,21 @@ const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
{ LDoNThemes::RUJ, "Rujarkian Hills" },
{ LDoNThemes::TAK, "Takish-Hiz" },
};
return ldon_theme_map;
}
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
{
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
auto ldon_themes = EQ::constants::GetLDoNThemeMap();
return ldon_themes[theme_id];
}
return std::string();
return std::string();
}
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
const std::map<uint8, std::string>& EQ::constants::GetFlyModeMap()
{
static const std::map<int8, std::string> flymode_map = {
static const std::map<uint8, std::string> flymode_map = {
{ GravityBehavior::Ground, "Ground" },
{ GravityBehavior::Flying, "Flying" },
{ GravityBehavior::Levitating, "Levitating" },
@@ -237,16 +233,15 @@ const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
{ GravityBehavior::Floating, "Floating" },
{ GravityBehavior::LevitateWhileRunning, "Levitating While Running" },
};
return flymode_map;
}
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
std::string EQ::constants::GetFlyModeName(uint8 flymode_id)
{
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
auto flymodes = EQ::constants::GetFlyModeMap();
return flymodes[flymode_id];
}
return std::string();
}
@@ -293,16 +288,15 @@ const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
{ BT_InvisMan, "Invisible Man" },
{ BT_Special, "Special" },
};
return bodytype_map;
}
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
{
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
auto bodytypes = EQ::constants::GetBodyTypeMap();
if (!bodytypes[bodytype_id].empty()) {
return bodytypes[bodytype_id];
}
return std::string();
}
@@ -324,26 +318,24 @@ const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
{ AccountStatus::GMAreas, "GM Areas" },
{ AccountStatus::GMCoder, "GM Coder" },
{ AccountStatus::GMMgmt, "GM Mgmt" },
{ AccountStatus::GMImpossible, "GM Impossible" },
{ AccountStatus::GMImpossible, "GM Impossible" },
{ AccountStatus::Max, "GM Max" }
};
return account_status_map;
}
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
{
for (
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
status_level != EQ::constants::GetAccountStatusMap().rend();
++status_level
) {
auto account_statuses = EQ::constants::GetAccountStatusMap();
std::string status_name;
for (auto status_level = account_statuses.rbegin(); status_level != account_statuses.rend(); ++status_level) {
if (account_status >= status_level->first) {
return status_level->second;
status_name = status_level->second;
break;
}
}
return std::string();
return status_name;
}
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
@@ -359,16 +351,15 @@ const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
{ ConsiderLevel::Threateningly, "Threateningly" },
{ ConsiderLevel::Scowls, "Scowls" }
};
return consider_level_map;
}
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
{
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
auto consider_levels = EQ::constants::GetConsiderLevelMap();
if (!consider_levels[faction_consider_level].empty()) {
return consider_levels[faction_consider_level];
}
return std::string();
}
@@ -380,202 +371,14 @@ const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
{ EnvironmentalDamage::Falling, "Falling" },
{ EnvironmentalDamage::Trap, "Trap" }
};
return damage_type_map;
}
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
{
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
auto damage_types = EQ::constants::GetEnvironmentalDamageMap();
return damage_types[damage_type];
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
{
static const std::map<uint8, std::string> stuck_behavior_map = {
{ StuckBehavior::RunToTarget, "Run To Target" },
{ StuckBehavior::WarpToTarget, "Warp To Target" },
{ StuckBehavior::TakeNoAction, "Take No Action" },
{ StuckBehavior::EvadeCombat, "Evade Combat" }
};
return stuck_behavior_map;
}
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
{
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
{
static const std::map<uint8, std::string> spawn_animation_map = {
{ SpawnAnimations::Standing, "Standing" },
{ SpawnAnimations::Sitting, "Sitting" },
{ SpawnAnimations::Crouching, "Crouching" },
{ SpawnAnimations::Laying, "Laying" },
{ SpawnAnimations::Looting, "Looting" }
};
return spawn_animation_map;
}
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
{
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
}
return std::string();
}
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
{
static const std::map<int, std::string> object_type_map = {
{ ObjectTypes::SmallBag, "Small Bag" },
{ ObjectTypes::LargeBag, "Large Bag" },
{ ObjectTypes::Quiver, "Quiver" },
{ ObjectTypes::BeltPouch, "Belt Pouch" },
{ ObjectTypes::WristPouch, "Wrist Pouch" },
{ ObjectTypes::Backpack, "Backpack" },
{ ObjectTypes::SmallChest, "Small Chest" },
{ ObjectTypes::LargeChest, "Large Chest" },
{ ObjectTypes::Bandolier, "Bandolier" },
{ ObjectTypes::Medicine, "Medicine" },
{ ObjectTypes::Tinkering, "Tinkering" },
{ ObjectTypes::Lexicon, "Lexicon" },
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
{ ObjectTypes::Quest, "Quest" },
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
{ ObjectTypes::Baking, "Baking" },
{ ObjectTypes::Tailoring, "Tailoring" },
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
{ ObjectTypes::Fletching, "Fletching" },
{ ObjectTypes::Brewing, "Brewing" },
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
{ ObjectTypes::Pottery, "Pottery" },
{ ObjectTypes::Kiln, "Kiln" },
{ ObjectTypes::KeyMaker, "Key Maker" },
{ ObjectTypes::ResearchWIZ, "Lexicon" },
{ ObjectTypes::ResearchMAG, "Lexicon" },
{ ObjectTypes::ResearchNEC, "Lexicon" },
{ ObjectTypes::ResearchENC, "Lexicon" },
{ ObjectTypes::Unknown, "Unknown" },
{ ObjectTypes::ResearchPractice, "Lexicon" },
{ ObjectTypes::Alchemy, "Alchemy" },
{ ObjectTypes::HighElfForge, "High Elf Forge" },
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
{ ObjectTypes::OgreForge, "Ogre Forge" },
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
{ ObjectTypes::GnomeForge, "Gnome Forge" },
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
{ ObjectTypes::IksarForge, "Iksar Forge" },
{ ObjectTypes::HumanForgeOne, "Human Forge" },
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
{ ObjectTypes::Fishing, "Fishing" },
{ ObjectTypes::TrollForge, "Troll Forge" },
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
{ ObjectTypes::HalflingForge, "Halfling Forge" },
{ ObjectTypes::EruditeForge, "Erudite Forge" },
{ ObjectTypes::Merchant, "Merchant" },
{ ObjectTypes::FroglokForge, "Froglok Forge" },
{ ObjectTypes::Augmenter, "Augmenter" },
{ ObjectTypes::Churn, "Churn" },
{ ObjectTypes::TransformationMold, "Transformation Mold" },
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
{ ObjectTypes::Unattuner, "Unattuner" },
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
{ ObjectTypes::NoDeposit, "No Deposit" }
};
return object_type_map;
}
std::string EQ::constants::GetObjectTypeName(int object_type)
{
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
}
return std::string();
}
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
{
static const std::map<uint8, std::string> weather_type_map = {
{WeatherTypes::None, "None"},
{WeatherTypes::Raining, "Raining"},
{WeatherTypes::Snowing, "Snowing"}
};
return weather_type_map;
}
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
{
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
}
return std::string();
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
{
static const std::map<uint8, std::string> emote_event_type_map = {
{ EmoteEventTypes::LeaveCombat, "Leave Combat" },
{ EmoteEventTypes::EnterCombat, "Enter Combat" },
{ EmoteEventTypes::OnDeath, "On Death" },
{ EmoteEventTypes::AfterDeath, "After Death" },
{ EmoteEventTypes::Hailed, "Hailed" },
{ EmoteEventTypes::KilledPC, "Killed PC" },
{ EmoteEventTypes::KilledNPC, "Killed NPC" },
{ EmoteEventTypes::OnSpawn, "On Spawn" },
{ EmoteEventTypes::OnDespawn, "On Despawn" }
};
return emote_event_type_map;
}
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
{
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
}
return std::string();
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
{
static const std::map<uint8, std::string> emote_type_map = {
{ EmoteTypes::Emote, "Emote" },
{ EmoteTypes::Shout, "Shout" },
{ EmoteTypes::Proximity, "Proximity" }
};
return emote_type_map;
}
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
{
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
}
return std::string();
}
+11 -175
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -32,6 +32,10 @@ namespace EQ
{
using RoF2::IINVALID;
using RoF2::INULL;
namespace inventory {
} /*inventory*/
namespace invtype {
using namespace RoF2::invtype::enum_;
@@ -197,7 +201,7 @@ namespace EQ
using RoF2::constants::EXPANSIONS_MASK;
using RoF2::constants::CHARACTER_CREATION_LIMIT;
const size_t SAY_LINK_OPENER_SIZE = 1;
using RoF2::constants::SAY_LINK_BODY_SIZE;
const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant
@@ -217,26 +221,7 @@ namespace EQ
stanceBurnAE
};
enum BotSpellIDs : int {
Warrior = 3001,
Cleric,
Paladin,
Ranger,
Shadowknight,
Druid,
Monk,
Bard,
Rogue,
Shaman,
Necromancer,
Wizard,
Magician,
Enchanter,
Beastlord,
Berserker
};
enum GravityBehavior : int8 {
enum GravityBehavior : uint8 {
Ground,
Flying,
Levitating,
@@ -252,109 +237,6 @@ namespace EQ
Trap
};
enum StuckBehavior : uint8 {
RunToTarget,
WarpToTarget,
TakeNoAction,
EvadeCombat
};
enum SpawnAnimations : uint8 {
Standing,
Sitting,
Crouching,
Laying,
Looting
};
enum ObjectTypes : int {
SmallBag,
LargeBag,
Quiver,
BeltPouch,
WristPouch,
Backpack,
SmallChest,
LargeChest,
Bandolier,
Medicine,
Tinkering,
Lexicon,
PoisonMaking,
Quest,
MixingBowl,
Baking,
Tailoring,
Blacksmithing,
Fletching,
Brewing,
JewelryMaking,
Pottery,
Kiln,
KeyMaker,
ResearchWIZ,
ResearchMAG,
ResearchNEC,
ResearchENC,
Unknown,
ResearchPractice,
Alchemy,
HighElfForge,
DarkElfForge,
OgreForge,
DwarfForge,
GnomeForge,
BarbarianForge,
IksarForge,
HumanForgeOne,
HumanForgeTwo,
HalflingTailoringOne,
HalflingTailoringTwo,
EruditeTailoring,
WoodElfTailoring,
WoodElfFletching,
IksarPottery,
Fishing,
TrollForge,
WoodElfForge,
HalflingForge,
EruditeForge,
Merchant,
FroglokForge,
Augmenter,
Churn,
TransformationMold,
DetransformationMold,
Unattuner,
TradeskillBag,
CollectibleBag,
NoDeposit
};
enum WeatherTypes : uint8 {
None,
Raining,
Snowing
};
enum EmoteEventTypes : uint8 {
LeaveCombat,
EnterCombat,
OnDeath,
AfterDeath,
Hailed,
KilledPC,
KilledNPC,
OnSpawn,
OnDespawn
};
enum EmoteTypes : uint8 {
Emote,
Shout,
Proximity
};
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
@@ -363,9 +245,9 @@ namespace EQ
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
std::string GetLDoNThemeName(uint32 theme_id);
extern const std::map<int8, std::string>& GetFlyModeMap();
std::string GetFlyModeName(int8 flymode_id);
extern const std::map<uint8, std::string>& GetFlyModeMap();
std::string GetFlyModeName(uint8 flymode_id);
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
std::string GetBodyTypeName(bodyType bodytype_id);
@@ -379,24 +261,6 @@ namespace EQ
extern const std::map<uint8, std::string>& GetEnvironmentalDamageMap();
std::string GetEnvironmentalDamageName(uint8 damage_type);
extern const std::map<uint8, std::string>& GetStuckBehaviorMap();
std::string GetStuckBehaviorName(uint8 behavior_id);
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
std::string GetSpawnAnimationName(uint8 animation_id);
extern const std::map<int, std::string>& GetObjectTypeMap();
std::string GetObjectTypeName(int object_type);
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
std::string GetWeatherTypeName(uint8 weather_type);
extern const std::map<uint8, std::string>& GetEmoteEventTypeMap();
std::string GetEmoteEventTypeName(uint8 emote_event_type);
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
std::string GetEmoteTypeName(uint8 emote_type);
const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE;
@@ -406,7 +270,7 @@ namespace EQ
namespace profile {
using RoF2::profile::BANDOLIERS_SIZE;
using RoF2::profile::BANDOLIER_ITEM_COUNT;
using RoF2::profile::POTION_BELT_SIZE;
using RoF2::profile::SKILL_ARRAY_SIZE;
@@ -552,32 +416,4 @@ enum ConsiderLevel : uint8 {
Scowls
};
enum TargetDescriptionType : uint8 {
LCSelf,
UCSelf,
LCYou,
UCYou,
LCYour,
UCYour
};
enum ReloadWorld : uint8 {
NoRepop = 0,
Repop,
ForceRepop
};
enum MerchantBucketComparison : uint8 {
BucketEqualTo = 0,
BucketNotEqualTo,
BucketGreaterThanOrEqualTo,
BucketLesserThanOrEqualTo,
BucketGreaterThan,
BucketLesserThan,
BucketIsAny,
BucketIsNotAny,
BucketIsBetween,
BucketIsNotBetween
};
#endif /*COMMON_EMU_CONSTANTS_H*/
-4
View File
@@ -71,7 +71,6 @@ N(OP_Camp),
N(OP_CancelSneakHide),
N(OP_CancelTask),
N(OP_CancelTrade),
N(OP_CashReward),
N(OP_CastSpell),
N(OP_ChangeSize),
N(OP_ChannelMessage),
@@ -304,7 +303,6 @@ N(OP_LockoutTimerInfo),
N(OP_Login),
N(OP_LoginAccepted),
N(OP_LoginComplete),
N(OP_LoginExpansionPacketData), //added for Rof2 client to send expansion data packet. Requires login_opcodes_sod.conf to be updated.
N(OP_LoginUnknown1),
N(OP_LoginUnknown2),
N(OP_Logout),
@@ -457,7 +455,6 @@ N(OP_ServerListResponse),
N(OP_SessionReady),
N(OP_SetChatServer),
N(OP_SetChatServer2),
N(OP_SetFace),
N(OP_SetGroupTarget),
N(OP_SetGuildMOTD),
N(OP_SetGuildRank),
@@ -561,7 +558,6 @@ N(OP_WhoAllRequest),
N(OP_WhoAllResponse),
N(OP_World_Client_CRC1),
N(OP_World_Client_CRC2),
N(OP_World_Client_CRC3),
N(OP_WorldClientReady),
N(OP_WorldComplete),
N(OP_WorldLogout),
+1 -8
View File
@@ -718,7 +718,7 @@ typedef enum {
FilterPetMisses = 21, //0=show, 1=hide
FilterFocusEffects = 22, //0=show, 1=hide
FilterPetSpells = 23, //0=show, 1=hide
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
FilterHealOverTime = 24, //0=show, 1=hide
FilterUnknown25 = 25,
FilterUnknown26 = 26,
FilterUnknown27 = 27,
@@ -1009,11 +1009,4 @@ enum StartZoneIndex {
SharVahl
};
enum FVNoDropFlagRule
{
Disabled = 0,
Enabled = 1,
AdminOnly = 2
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+16 -16
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,7 @@
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
@@ -26,7 +26,7 @@
static bool global_dictionary_init = false;
void EQ::InitializeDynamicLookups() {
if (global_dictionary_init)
if (global_dictionary_init == true)
return;
constants::InitializeDynamicLookups();
@@ -167,7 +167,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL
),
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL,
@@ -175,7 +175,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL,
false,
false,
false,
@@ -194,7 +194,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL
),
Client62::INULL,
Client62::INULL,
Client62::INULL,
@@ -202,7 +202,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Client62::INULL,
Client62::INULL,
Client62::INULL,
false,
false,
false,
@@ -221,7 +221,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::INULL, Titanium::INULL, Titanium::INULL,
Titanium::invtype::OTHER_SIZE
),
Titanium::invslot::EQUIPMENT_BITMASK,
Titanium::invslot::GENERAL_BITMASK,
Titanium::invslot::CURSOR_BITMASK,
@@ -229,7 +229,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::invslot::CORPSE_BITMASK,
Titanium::invbag::SLOT_COUNT,
Titanium::invaug::SOCKET_COUNT,
Titanium::inventory::AllowEmptyBagInBag,
Titanium::inventory::AllowClickCastFromBag,
Titanium::inventory::ConcatenateInvTypeLimbo,
@@ -248,7 +248,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::INULL, SoF::INULL, SoF::INULL,
SoF::invtype::OTHER_SIZE
),
SoF::invslot::EQUIPMENT_BITMASK,
SoF::invslot::GENERAL_BITMASK,
SoF::invslot::CURSOR_BITMASK,
@@ -256,7 +256,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::invslot::CORPSE_BITMASK,
SoF::invbag::SLOT_COUNT,
SoF::invaug::SOCKET_COUNT,
SoF::inventory::AllowEmptyBagInBag,
SoF::inventory::AllowClickCastFromBag,
SoF::inventory::ConcatenateInvTypeLimbo,
@@ -763,7 +763,7 @@ void EQ::inventory::InitializeDynamicLookups() {
// Notes:
// - Currently, there are only 3 known expansions that affect inventory-related settings in the clients..
// -- Expansion::PoR "Prophecy of Ro" - toggles between 24 (set) and 16 (clear) bank slots
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
// -- Expansion::HoT "House of Thule" - toggles slotGeneral9/slotGeneral10 activated (set) and deactivated (clear)
// - Corspe size does not appear to reflect loss of active possessions slots
// - Inspect size does not appear to reflect loss of active equipment slots
@@ -772,7 +772,7 @@ void EQ::inventory::InitializeDynamicLookups() {
// - General9 and General10 slots are activated by GM flag when expansion bit is (clear)
// - Obviously, the client must support the expansion to allow any (set) or override condition
const uint32 dynamic_check_mask =
const uint32 dynamic_check_mask =
(
EQ::expansions::bitPoR |
EQ::expansions::bitTBS |
@@ -1210,10 +1210,10 @@ void EQ::spells::InitializeDynamicLookups() {
if (spells_dictionary_init == true)
return;
spells_dictionary_init = true;
if (RuleB(World, UseClientBasedExpansionSettings))
return;
// use static references for now
}
@@ -1239,7 +1239,7 @@ const EQ::spells::LookupEntry* EQ::spells::DynamicGMLookup(versions::ClientVersi
client_version = versions::ValidateClientVersion(client_version);
if (spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)])
return spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)].get();
return &spells_static_lookup_entries[static_cast<int>(client_version)];
}
+23 -42
View File
@@ -374,18 +374,18 @@ struct NewZone_Struct {
/*0684*/ uint16 zone_id;
/*0686*/ uint16 zone_instance;
/*0688*/ uint32 unknown688;
/*0692*/ uint8 unknown692[8];
/*0692*/ uint8 unknown692[8];
// Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows
// Just wastes some bandwidth sending to tit clients /shrug
/*0700*/ float fog_density;
/*0704*/ uint32 suspend_buffs;
/*0708*/ uint32 fast_regen_hp;
/*0712*/ uint32 fast_regen_mana;
/*0716*/ uint32 fast_regen_endurance;
/*0720*/ uint32 npc_aggro_max_dist;
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
/*0728*/ uint32 lava_damage; // Seen 50
/*0732*/ uint32 min_lava_damage; // Seen 10
/*0700*/ float fog_density;
/*0704*/ uint32 SuspendBuffs;
/*0708*/ uint32 FastRegenHP;
/*0712*/ uint32 FastRegenMana;
/*0716*/ uint32 FastRegenEndurance;
/*0720*/ uint32 NPCAggroMaxDist;
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
/*0728*/ uint32 LavaDamage; // Seen 50
/*0732*/ uint32 MinLavaDamage; // Seen 10
/*0736*/
};
@@ -2192,19 +2192,11 @@ struct QuestReward_Struct
/*068*/
};
struct CashReward_Struct
{
/*000*/ uint32 copper;
/*004*/ uint32 silver;
/*008*/ uint32 gold;
/*012*/ uint32 platinum;
};
// Size: 8
struct Camera_Struct
{
uint32 duration; // Duration in ms
float intensity;
uint32 intensity; // Between 1023410176 and 1090519040
};
struct ZonePoint_Entry {
@@ -2324,12 +2316,9 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*024*/
/*007*/ uint32 drakkin_heritage;
/*011*/ uint32 drakkin_tattoo;
/*015*/ uint32 drakkin_details;
//there are only 10 faces for barbs changing woad just
//increase the face value by ten so if there were 8 woad
//designs then there would be 80 barb faces
@@ -3632,17 +3621,14 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
};
struct MerchantList {
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
std::string bucket_name;
std::string bucket_value;
uint8 bucket_comparison;
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
};
struct TempMerchantList {
@@ -5006,7 +4992,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
@@ -5596,11 +5582,6 @@ struct SayLinkBodyFrame_Struct {
/*056*/
};
struct Checksum_Struct {
uint64 checksum;
uint8 data[2048];
};
struct UpdateMovementEntry {
/* 00 */ float Y;
/* 04 */ float X;
+7 -7
View File
@@ -23,7 +23,7 @@
#include "op_codes.h"
#include "crc16.h"
#include "platform.h"
#include "strings.h"
#include "string_util.h"
#include <string>
#include <iomanip>
@@ -406,7 +406,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L,
@@ -453,7 +453,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
(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));
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
@@ -951,7 +951,7 @@ EQRawApplicationPacket *p=nullptr;
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
if (emu_op == OP_Unknown) {
// Log(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str());
}
}
p->SetOpcode(emu_op);
}
}
@@ -1359,11 +1359,11 @@ void EQStream::AdjustRates(uint32 average_delta)
DecayRate=DECAYBASE/average_delta;
if (BytesWritten > RateThreshold)
BytesWritten = RateThreshold + DecayRate;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
} else {
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
average_delta, AVERAGE_DELTA_MAX);
AverageDelta = AVERAGE_DELTA_MAX;
}
@@ -1374,7 +1374,7 @@ void EQStream::AdjustRates(uint32 average_delta)
BytesWritten = 0;
RateThreshold=RATEBASE/average_delta;
DecayRate=DECAYBASE/average_delta;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
}
+6 -11
View File
@@ -218,13 +218,13 @@ class EQStream : public EQStreamInterface {
void init(bool resetSession=true);
public:
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
streamactive = false; }
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
create_time = Timer::GetTimeSeconds(); }
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
void SetMaxLen(uint32 length) { MaxLen=length; }
@@ -243,11 +243,6 @@ class EQStream : public EQStreamInterface {
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
virtual OpcodeManager* GetOpcodeManager() const
{
return (*OpMgr);
};
void CheckTimeout(uint32 now, uint32 timeout=30);
bool HasOutgoingData();
void Process(const unsigned char *data, const uint32 length);
+1 -2
View File
@@ -30,7 +30,7 @@ struct EQStreamManagerInterfaceOptions
//World seems to support both compression and xor zone supports one or the others.
//Enforce one or the other in the convienence construct
//Login I had trouble getting to recognize compression at all
//Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that.
if (compressed) {
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
@@ -100,7 +100,6 @@ public:
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
virtual EQStreamState GetState() = 0;
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
virtual OpcodeManager* GetOpcodeManager() const = 0;
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
virtual Stats GetStats() const = 0;
virtual void ResetStats() = 0;
+5 -6
View File
@@ -38,8 +38,12 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
}
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
if (p == nullptr) {
if(p == nullptr)
return;
if (p->GetOpcode() != OP_SpecialMesg) {
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
}
EQApplicationPacket *newp = p->Copy();
@@ -108,8 +112,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
return false;
}
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
{
return (*m_opcodes);
}
+1 -3
View File
@@ -34,15 +34,13 @@ public:
virtual Stats GetStats() const;
virtual void ResetStats();
virtual EQStreamManagerInterface* GetManager() const;
virtual OpcodeManager* GetOpcodeManager() const;
protected:
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
const StructStrategy *const m_structs; //we do not own this object.
//this is a pointer to a pointer to make it less likely that a packet will
//reference an invalid opcode manager when they are being reloaded.
OpcodeManager **const m_opcodes;
//we do not own this object.
OpcodeManager **const m_opcodes; //we do not own this object.
};
#endif /*EQSTREAMPROXY_H_*/
-9
View File
@@ -86,7 +86,6 @@ void EQEmuConfig::parse_config()
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
WorldUDPPort = atoi(_root["server"]["world"]["udp"].get("port", "9000").asString().c_str());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
@@ -101,10 +100,6 @@ void EQEmuConfig::parse_config()
WorldHTTPEnabled = true;
}
if (_root["server"].get("disable_config_checks", "false").asString() == "true") {
DisableConfigChecks = true;
}
/**
* UCS
*/
@@ -218,9 +213,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "WorldTCPPort") {
return (itoa(WorldTCPPort));
}
if (var_name == "WorldUDPPort") {
return (itoa(WorldUDPPort));
}
if (var_name == "WorldIP") {
return (WorldIP);
}
@@ -352,7 +344,6 @@ void EQEmuConfig::Dump() const
std::cout << "LoginLegacy = " << LoginLegacy << std::endl;
std::cout << "Locked = " << Locked << std::endl;
std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl;
std::cout << "WorldUDPPort = " << WorldUDPPort << std::endl;
std::cout << "WorldIP = " << WorldIP << std::endl;
std::cout << "TelnetTCPPort = " << TelnetTCPPort << std::endl;
std::cout << "TelnetIP = " << TelnetIP << std::endl;
+7 -19
View File
@@ -20,9 +20,7 @@
#include "json/json.h"
#include "linked_list.h"
#include "path_manager.h"
#include <fstream>
#include <fmt/format.h>
struct LoginConfig {
std::string LoginHost;
@@ -51,7 +49,6 @@ class EQEmuConfig
LinkedList<LoginConfig*> loginlist;
bool Locked;
uint16 WorldTCPPort;
uint16 WorldUDPPort;
std::string WorldIP;
uint16 TelnetTCPPort;
std::string TelnetIP;
@@ -61,7 +58,6 @@ class EQEmuConfig
uint16 WorldHTTPPort;
std::string WorldHTTPMimeFile;
std::string SharedKey;
bool DisableConfigChecks;
// From <chatserver/>
std::string ChatHost;
@@ -134,7 +130,7 @@ class EQEmuConfig
void parse_config();
EQEmuConfig()
{
{
}
virtual ~EQEmuConfig() {}
@@ -155,38 +151,30 @@ class EQEmuConfig
}
// Load the config
static bool LoadConfig(const std::string& path = "")
static bool LoadConfig()
{
if (_config != nullptr) {
return true;
}
_config = new EQEmuConfig;
return parseFile(path);
return parseFile();
}
// Load config file and parse data
static bool parseFile(const std::string& file_path = ".")
{
static bool parseFile() {
if (_config == nullptr) {
return LoadConfig(file_path);
return LoadConfig();
}
std::string file = fmt::format(
"{}/{}",
(file_path.empty() ? path.GetServerPath() : file_path),
EQEmuConfig::ConfigFile
);
std::ifstream fconfig(file, std::ifstream::binary);
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
try {
fconfig >> _config->_root;
_config->parse_config();
}
catch (std::exception &) {
return false;
}
}
return true;
}
+146 -225
View File
@@ -21,10 +21,8 @@
#include "eqemu_logsys.h"
#include "rulesys.h"
#include "platform.h"
#include "strings.h"
#include "string_util.h"
#include "misc.h"
#include "discord/discord.h"
#include "repositories/discord_webhooks_repository.h"
#include "repositories/logsys_categories_repository.h"
#include <iostream>
@@ -48,7 +46,6 @@ std::ofstream process_log;
#include <unistd.h>
#include <sys/stat.h>
#include <thread>
#endif
@@ -91,8 +88,8 @@ namespace Console {
*/
EQEmuLogSys::EQEmuLogSys()
{
m_on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
m_on_log_console_hook = [](uint16 log_type, const std::string &) {};
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
}
/**
@@ -105,41 +102,36 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* Get Executable platform currently running this code (Zone/World/etc)
*/
m_log_platform = GetExecutablePlatformInt();
log_platform = GetExecutablePlatformInt();
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
log_settings[log_category_id].log_to_console = 0;
log_settings[log_category_id].log_to_file = 0;
log_settings[log_category_id].log_to_gmsay = 0;
log_settings[log_category_id].log_to_discord = 0;
log_settings[log_category_id].is_category_enabled = 0;
}
m_file_logs_enabled = false;
file_logs_enabled = false;
/**
* Set Defaults
*/
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::CombatRecord].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
/**
* RFC 5424
@@ -159,8 +151,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
const bool log_to_discord = log_settings[log_category_id].log_to_discord > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
if (is_category_enabled) {
log_settings[log_category_id].is_category_enabled = 1;
}
@@ -169,26 +160,26 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* Declare process file names for log writing=
*/
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld) {
m_platform_file_name = "world";
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) {
platform_file_name = "world";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
m_platform_file_name = "query_server";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
platform_file_name = "query_server";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
m_platform_file_name = "zone";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
platform_file_name = "zone";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformUCS) {
m_platform_file_name = "ucs";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) {
platform_file_name = "ucs";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLogin) {
m_platform_file_name = "login";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) {
platform_file_name = "login";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLaunch) {
m_platform_file_name = "launcher";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) {
platform_file_name = "launcher";
}
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformHC) {
m_platform_file_name = "hc";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) {
platform_file_name = "hc";
}
return this;
@@ -212,12 +203,56 @@ bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
);
}
/**
* @param log_category
* @param in_message
* @return
*/
std::string EQEmuLogSys::FormatOutMessageString(
uint16 log_category,
const std::string &in_message
)
{
std::string return_string = "[" + GetPlatformName() + "] ";
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessGMSay(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
{
/**
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
*/
if (log_category == Logs::LogCategory::Netcode) {
return;
}
/**
* Processes that actually support hooks
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld
) {
on_log_gmsay_hook(log_category, message);
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessLogWrite(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
@@ -228,16 +263,17 @@ void EQEmuLogSys::ProcessLogWrite(
std::ofstream crash_log;
EQEmuLogSys::MakeDirectory("logs/crashes");
crash_log.open(
StringFormat("logs/crashes/crash_%s_%i.log", m_platform_file_name.c_str(), getpid()),
StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
crash_log << time_stamp << " " << message << "\n";
crash_log.close();
}
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
if (process_log) {
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
process_log << time_stamp << " " << message << std::endl;
}
}
@@ -333,7 +369,7 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessConsoleMessage(uint16 log_category, const std::string &message)
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
{
#ifdef _WINDOWS
HANDLE console_handle;
@@ -351,7 +387,7 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 log_category, const std::string &
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
m_on_log_console_hook(log_category, message);
on_log_console_hook(debug_level, log_category, message);
}
/**
@@ -408,52 +444,47 @@ void EQEmuLogSys::Out(
...
)
{
auto l = GetLogsEnabled(debug_level, log_category);
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
}
// bail out if nothing to log
if (!l.log_enabled) {
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;
}
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log) {
return;
}
std::string prefix;
if (RuleB(Logging, PrintFileFunctionAndLine)) {
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
}
// remove this when we remove all legacy logs
bool ignore_log_legacy_format = (
log_category == Logs::Netcode ||
log_category == Logs::PacketServerClient ||
log_category == Logs::PacketClientServer ||
log_category == Logs::PacketServerToServer
);
va_list args;
va_start(args, message);
std::string output_message = vStringFormat(message, args);
va_end(args);
// remove this when we remove all legacy logs
std::string output_message = message;
if (!ignore_log_legacy_format) {
va_list args;
va_start(args, message);
output_message = vStringFormat(message, args);
va_end(args);
}
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
if (l.log_to_console_enabled) {
EQEmuLogSys::ProcessConsoleMessage(
log_category,
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
);
if (log_to_console) {
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
}
if (l.log_to_gmsay_enabled) {
m_on_log_gmsay_hook(log_category, output_message);
if (log_to_gmsay) {
EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
}
if (l.log_to_file_enabled) {
EQEmuLogSys::ProcessLogWrite(
log_category,
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
);
}
if (l.log_to_discord_enabled && m_on_log_discord_hook) {
m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
if (log_to_file) {
EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
}
}
@@ -466,7 +497,7 @@ void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
struct tm *time_info;
time(&raw_time);
time_info = localtime(&raw_time);
strftime(time_stamp, 80, "[%m-%d-%Y %H:%M:%S]", time_info);
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
}
/**
@@ -505,45 +536,53 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
/**
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
*/
if (!m_file_logs_enabled) {
if (!file_logs_enabled) {
return;
}
/**
* Zone
*/
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
if (!log_name.empty()) {
m_platform_file_name = log_name;
platform_file_name = log_name;
}
if (m_platform_file_name.empty()) {
if (platform_file_name.empty()) {
return;
}
LogInfo("Starting File Log [{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
// Make directory if not exists
EQEmuLogSys::MakeDirectory(fmt::format("{}/zone", GetLogPath()));
/**
* Make directory if not exists
*/
EQEmuLogSys::MakeDirectory("logs/zone");
// Open file pointer
/**
* Open file pointer
*/
process_log.open(
fmt::format("{}/zone/{}_{}.log", GetLogPath(), m_platform_file_name, getpid()),
StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
else {
// All other processes
if (m_platform_file_name.empty()) {
/**
* All other processes
*/
if (platform_file_name.empty()) {
return;
}
LogInfo("Starting File Log [{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
// Open file pointer
/**
* Open file pointer
*/
process_log.open(
fmt::format("{}/{}_{}.log", GetLogPath(), m_platform_file_name.c_str(), getpid()),
StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
@@ -573,8 +612,6 @@ void EQEmuLogSys::EnableConsoleLogging()
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
{
InjectTablesIfNotExist();
auto categories = LogsysCategoriesRepository::GetWhere(
*m_database,
"TRUE ORDER BY log_category_id"
@@ -590,20 +627,16 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
continue;
}
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
log_settings[c.log_category_id].log_to_discord = static_cast<uint8>(c.log_to_discord);
log_settings[c.log_category_id].discord_webhook_id = c.discord_webhook_id;
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
// Determine if any output method is enabled for the category
// and set it to 1 so it can used to check if category is enabled
const bool log_to_console = log_settings[c.log_category_id].log_to_console > 0;
const bool log_to_file = log_settings[c.log_category_id].log_to_file > 0;
const bool log_to_gmsay = log_settings[c.log_category_id].log_to_gmsay > 0;
const bool log_to_discord = log_settings[c.log_category_id].log_to_discord > 0 &&
log_settings[c.log_category_id].discord_webhook_id > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
if (is_category_enabled) {
log_settings[c.log_category_id].is_category_enabled = 1;
@@ -613,7 +646,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
// If we go through this whole loop and nothing is set to any debug level, there
// is no point to create a file or keep anything open
if (log_settings[c.log_category_id].log_to_file > 0) {
LogSys.m_file_logs_enabled = true;
LogSys.file_logs_enabled = true;
}
db_categories.emplace_back(c.log_category_id);
@@ -621,28 +654,18 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
// Auto inject categories that don't exist in the database...
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[i]), "Deprecated");
if (!is_missing_in_database && is_deprecated_category) {
LogInfo("Logging category [{}] ({}) is now deprecated, deleting from database", Logs::LogCategoryName[i], i);
LogsysCategoriesRepository::DeleteOne(*m_database, i);
}
if (is_missing_in_database && !is_deprecated_category) {
if (std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end()) {
LogInfo(
"Automatically adding new log category [{}] ({})",
Logs::LogCategoryName[i],
i
"Automatically adding new log category [{0}]",
Logs::LogCategoryName[i]
);
auto new_category = LogsysCategoriesRepository::NewEntity();
new_category.log_category_id = i;
new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
new_category.log_category_description = EscapeString(Logs::LogCategoryName[i]);
new_category.log_to_console = log_settings[i].log_to_console;
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
new_category.log_to_file = log_settings[i].log_to_file;
new_category.log_to_discord = log_settings[i].log_to_discord;
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
}
@@ -650,14 +673,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
LogInfo("Loaded [{}] log categories", categories.size());
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
if (!webhooks.empty()) {
for (auto &w: webhooks) {
m_discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url};
}
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
}
return this;
}
@@ -667,97 +682,3 @@ EQEmuLogSys *EQEmuLogSys::SetDatabase(Database *db)
return this;
}
void EQEmuLogSys::InjectTablesIfNotExist()
{
// do not run injections for zone as its unnecessary hits every time a zone boots
// other processes less frequently ran can pick up injection
if (m_log_platform == EQEmuExePlatform::ExePlatformZone) {
return;
}
// inject discord_webhooks
if (!m_database->DoesTableExist("discord_webhooks")) {
LogInfo("Creating table [discord_webhooks]");
m_database->QueryDatabase(
SQL(
CREATE TABLE discord_webhooks
(
id INT auto_increment primary key NULL,
webhook_name varchar(100) NULL,
webhook_url varchar(255) NULL,
created_at DATETIME NULL,
deleted_at DATETIME NULL
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci;
)
);
}
// inject logsys_categories
if (!m_database->DoesTableExist("logsys_categories")) {
LogInfo("Creating table [logsys_categories]");
m_database->QueryDatabase(
SQL(
CREATE TABLE `logsys_categories` (
`log_category_id` int(11) NOT NULL,
`log_category_description` varchar(150) DEFAULT NULL,
`log_to_console` smallint(11) DEFAULT 0,
`log_to_file` smallint(11) DEFAULT 0,
`log_to_gmsay` smallint(11) DEFAULT 0,
`log_to_discord` smallint(11) DEFAULT 0,
`discord_webhook_id` int(11) DEFAULT 0,
PRIMARY KEY (`log_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
)
);
}
}
const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const
{
return m_discord_webhooks;
}
EQEmuLogSys::LogEnabled EQEmuLogSys::GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
{
auto e = LogEnabled{};
e.log_to_console_enabled = log_settings[log_category].log_to_console > 0 &&
log_settings[log_category].log_to_console >= debug_level;
e.log_to_file_enabled = log_settings[log_category].log_to_file > 0 &&
log_settings[log_category].log_to_file >= debug_level;
e.log_to_gmsay_enabled = log_settings[log_category].log_to_gmsay > 0 &&
log_settings[log_category].log_to_gmsay >= debug_level &&
log_category != Logs::LogCategory::Netcode &&
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
e.log_to_discord_enabled = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
log_settings[log_category].log_to_discord > 0 &&
log_settings[log_category].log_to_discord >= debug_level &&
log_settings[log_category].discord_webhook_id > 0 &&
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
e.log_enabled =
e.log_to_console_enabled || e.log_to_file_enabled || e.log_to_gmsay_enabled || e.log_to_discord_enabled;
return e;
}
bool EQEmuLogSys::IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
{
return GetLogsEnabled(debug_level, log_category).log_enabled;
}
const std::string &EQEmuLogSys::GetLogPath() const
{
return m_log_path;
}
EQEmuLogSys * EQEmuLogSys::SetLogPath(const std::string &log_path)
{
EQEmuLogSys::m_log_path = log_path;
return this;
}
+25 -79
View File
@@ -54,7 +54,7 @@ namespace Logs {
AI,
Aggro,
Attack,
DeprecatedCS,
PacketClientServer,
Combat,
Commands,
Crash,
@@ -88,10 +88,10 @@ namespace Logs {
MySQLQuery,
Mercenaries,
QuestDebug,
DeprecatedSC,
DeprecatedCSU,
DeprecatedSCD,
DeprecatedCSD,
PacketServerClient,
PacketClientServerUnhandled,
PacketServerClientWithDump,
PacketClientServerWithDump,
Loginserver,
ClientLogin,
HeadlessClient,
@@ -127,14 +127,6 @@ namespace Logs {
DiaWind,
HTTP,
Saylink,
ChecksumVerification,
CombatRecord,
Hate,
Discord,
Faction,
PacketServerClient,
PacketClientServer,
PacketServerToServer,
MaxCategoryID /* Don't Remove this */
};
@@ -147,7 +139,7 @@ namespace Logs {
"AI",
"Aggro",
"Attack",
"Deprecated",
"Packet :: Client -> Server",
"Combat",
"Commands",
"Crash",
@@ -181,10 +173,10 @@ namespace Logs {
"MySQL Query",
"Mercenaries",
"Quest Debug",
"Deprecated",
"Deprecated",
"Deprecated",
"Deprecated",
"Packet :: Server -> Client",
"Packet :: Client -> Server Unhandled",
"Packet :: Server -> Client (Dump)",
"Packet :: Client -> Server (Dump)",
"Login Server",
"Client Login",
"Headless Client",
@@ -220,14 +212,6 @@ namespace Logs {
"DialogueWindow",
"HTTP",
"Saylink",
"ChecksumVerification",
"CombatRecord",
"Hate",
"Discord",
"Faction",
"Packet-S->C",
"Packet-C->S",
"Packet-S->S"
};
}
@@ -235,8 +219,6 @@ namespace Logs {
class Database;
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
class EQEmuLogSys {
public:
EQEmuLogSys();
@@ -299,19 +281,9 @@ public:
uint8 log_to_file;
uint8 log_to_console;
uint8 log_to_gmsay;
uint8 log_to_discord;
int discord_webhook_id;
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
};
struct OriginationInfo {
std::string zone_short_name;
std::string zone_long_name;
int instance_id;
};
OriginationInfo origination_info{};
/**
* Internally used memory reference for all log settings per category
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
@@ -319,76 +291,50 @@ public:
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
struct LogEnabled {
bool log_to_file_enabled;
bool log_to_console_enabled;
bool log_to_gmsay_enabled;
bool log_to_discord_enabled;
bool log_enabled;
};
bool file_logs_enabled = false;
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
int log_platform = 0;
std::string platform_file_name;
struct DiscordWebhooks {
int id;
std::string webhook_name;
std::string webhook_url;
};
const DiscordWebhooks *GetDiscordWebhooks() const;
// gmsay
uint16 GetGMSayColorFromCategory(uint16 log_category);
EQEmuLogSys *SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f)
{
m_on_log_gmsay_hook = f;
return this;
}
EQEmuLogSys *SetDiscordHandler(std::function<void(uint16 log_category, int webhook_id, const std::string &)> f)
{
m_on_log_discord_hook = f;
EQEmuLogSys * SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f) {
on_log_gmsay_hook = f;
return this;
}
// console
void SetConsoleHandler(
std::function<void(
uint16 debug_level,
uint16 log_type,
const std::string &
)> f
) { m_on_log_console_hook = f; }
) { on_log_console_hook = f; }
void SilenceConsoleLogging();
void EnableConsoleLogging();
// database
EQEmuLogSys *SetDatabase(Database *db);
[[nodiscard]] const std::string &GetLogPath() const;
EQEmuLogSys * SetLogPath(const std::string &log_path);
private:
// reference to database
Database *m_database;
std::function<void(uint16 log_category, const std::string &)> m_on_log_gmsay_hook;
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
bool m_file_logs_enabled = false;
int m_log_platform = 0;
std::string m_platform_file_name;
std::string m_log_path;
Database *m_database;
std::function<void(uint16 log_category, const std::string &)> on_log_gmsay_hook;
std::function<void(uint16 debug_level, uint16 log_category, const std::string &)> on_log_console_hook;
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
void ProcessConsoleMessage(uint16 log_category, const std::string &message);
void ProcessLogWrite(uint16 log_category, const std::string &message);
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
bool IsRfc5424LogCategory(uint16 log_category);
void InjectTablesIfNotExist();
};
extern EQEmuLogSys LogSys;
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,14 +1,14 @@
#pragma once
#include <any>
#include <functional>
#include <exception>
#include "event_loop.h"
#include "../any.h"
namespace EQ {
class Task
{
public:
typedef std::function<void(const std::any&)> ResolveFn;
typedef std::function<void(const EQ::Any&)> ResolveFn;
typedef std::function<void(const std::exception&)> RejectFn;
typedef std::function<void()> FinallyFn;
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
@@ -19,7 +19,7 @@ namespace EQ {
RejectFn on_catch;
FinallyFn on_finally;
bool has_result;
std::any result;
EQ::Any result;
bool has_error;
std::exception error;
};
@@ -63,7 +63,7 @@ namespace EQ {
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
TaskBaton *baton = (TaskBaton*)req->data;
baton->fn([baton](const std::any& result) {
baton->fn([baton](const EQ::Any& result) {
baton->has_error = false;
baton->has_result = true;
baton->result = result;
+2 -2
View File
@@ -60,8 +60,8 @@ namespace EQ
}
template<typename Fn, typename... Args>
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type> {
using return_type = typename std::invoke_result<Fn, Args...>::type;
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
using return_type = typename std::result_of<Fn(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()>>(
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
+1 -1
View File
@@ -19,7 +19,7 @@
*/
#include "expedition_lockout_timer.h"
#include "../common/strings.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "../common/util/uuid.h"
#include <fmt/format.h>
-17
View File
@@ -75,23 +75,6 @@ struct NPCFaction
uint8 temp;
};
// Faction Associations give a much more live like faction system
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
#define MAX_FACTION_ASSOC 10
// this is the ID of a faction association and it's multiplier
struct FactionAssociationHit {
int id;
float multiplier;
};
struct FactionAssociations {
// maybe there should be more data here, fine for now
FactionAssociationHit hits[MAX_FACTION_ASSOC];
};
const char *FactionValueToString(FACTION_VALUE faction_value);
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
#endif
+22 -32
View File
@@ -19,7 +19,7 @@
*/
#include <fstream>
#include "file.h"
#include "file_util.h"
#ifdef _WINDOWS
#include <direct.h>
@@ -35,48 +35,38 @@
#endif
#include <fmt/format.h>
#include <filesystem>
namespace fs = std::filesystem;
/**
* @param name
* @return
*/
bool File::Exists(const std::string &name)
bool FileUtil::exists(const std::string &name)
{
return fs::exists(fs::path{name});
std::ifstream f(name.c_str());
return f.good();
}
/**
* @param directory_name
*/
void File::Makedir(const std::string &directory_name)
void FileUtil::mkdir(const std::string& directory_name)
{
fs::create_directory(directory_name);
fs::permissions(directory_name, fs::perms::owner_all);
#ifdef _WINDOWS
struct _stat st;
if (_stat(directory_name.c_str(), &st) == 0) // exists
return;
_mkdir(directory_name.c_str());
#else
struct stat st{};
if (stat(directory_name.c_str(), &st) == 0) { // exists
return;
}
::mkdir(directory_name.c_str(), 0755);
#endif
}
std::string File::FindEqemuConfigPath()
{
if (File::Exists(fs::path{File::GetCwd() + "/eqemu_config.json"}.string())) {
return File::GetCwd();
}
else if (File::Exists(fs::path{File::GetCwd() + "/../eqemu_config.json"}.string())) {
return canonical(fs::path{File::GetCwd() + "/../"}).string();
}
else if (File::Exists(fs::path{File::GetCwd() + "/login.json"}.string())) {
return File::GetCwd();
}
else if (File::Exists(fs::path{File::GetCwd() + "/../login.json"}.string())) {
return canonical(fs::path{File::GetCwd() + "/../"}).string();
}
return {};
}
std::string File::GetCwd()
{
return fs::current_path().string();
bool file_exists(const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
+7 -12
View File
@@ -18,21 +18,16 @@
*
*/
#ifndef EQEMU_FILE_H
#define EQEMU_FILE_H
#ifndef EQEMU_FILE_UTIL_H
#define EQEMU_FILE_UTIL_H
#include <filesystem>
namespace fs = std::filesystem;
class File {
class FileUtil {
public:
static bool Exists(const std::string &name);
static void Makedir(const std::string& directory_name);
static std::string FindEqemuConfigPath();
static std::string GetCwd();
static bool exists(const std::string &name);
static void mkdir(const std::string& directory_name);
};
bool Exists(const std::string& name);
bool file_exists(const std::string& name);
#endif //EQEMU_FILE_H
#endif //EQEMU_FILE_UTIL_H
+3 -3
View File
@@ -20,7 +20,7 @@
#include "database.h"
//#include "misc_functions.h"
#include "strings.h"
#include "string_util.h"
#include <cstdlib>
#include <cstring>
@@ -1281,10 +1281,10 @@ bool BaseGuildManager::IsCharacterInGuild(uint32 character_id, uint32 guild_id)
if (current_guild_id == GUILD_NONE) {
return false;
}
if (guild_id && current_guild_id != guild_id) {
return false;
}
return true;
}
}
+2114 -2837
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -25,7 +25,7 @@
//#include "races.h"
//#include "rulesys.h"
//#include "shareddb.h"
#include "strings.h"
#include "string_util.h"
#include "../common/light_source.h"
@@ -245,7 +245,7 @@ int16 EQ::InventoryProfile::PutItem(int16 slot_id, const ItemInstance& inst)
if (temp_slot >= m_lookup->InventoryTypeSize.Bank)
return EQ::invslot::SLOT_INVALID;
}
// Clean up item already in slot (if exists)
DeleteItem(slot_id);
@@ -617,7 +617,7 @@ int EQ::InventoryProfile::CountAugmentEquippedByID(uint32 item_id)
quantity += item->CountAugmentByID(item_id);
}
}
return quantity;
}
@@ -648,7 +648,7 @@ int EQ::InventoryProfile::CountItemEquippedByID(uint32 item_id)
quantity += item->IsStackable() ? item->GetCharges() : 1;
}
}
return quantity;
}
@@ -993,7 +993,7 @@ int16 EQ::InventoryProfile::CalcSlotId(int16 slot_id) {
//else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END)
// parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
//else if (slot_id >= 3100 && slot_id <= 3179) should be {3031..3110}..where did this range come from!!? (verified db save range)
if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) {
parent_slot_id = invslot::GENERAL_BEGIN + (slot_id - invbag::GENERAL_BAGS_BEGIN) / invbag::SLOT_COUNT;
}
@@ -1231,7 +1231,7 @@ uint8 EQ::InventoryProfile::FindBrightestLightType()
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
if ((iter->first < invslot::EQUIPMENT_BEGIN || iter->first > invslot::EQUIPMENT_END))
continue;
if (iter->first == invslot::slotAmmo)
continue;
@@ -1369,7 +1369,7 @@ EQ::ItemInstance* EQ::InventoryProfile::_GetItem(const std::map<int16, ItemInsta
if (slot_id - EQ::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize.Bank)
return nullptr;
}
auto it = bucket.find(slot_id);
if (it != bucket.end()) {
return it->second;
@@ -1441,7 +1441,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
result = slot_id;
}
}
if (result == INVALID_INDEX) {
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
@@ -1478,7 +1478,7 @@ int16 EQ::InventoryProfile::_HasItem(std::map<int16, ItemInstance*>& bucket, uin
if (inst->GetAugmentItemID(index) == item_id && quantity <= 1)
return invslot::SLOT_AUGMENT_GENERIC_RETURN;
}
if (!inst->IsClassBag()) { continue; }
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
@@ -1509,7 +1509,7 @@ int16 EQ::InventoryProfile::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint
// 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
uint32 quantity_found = 0;
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
@@ -1715,6 +1715,6 @@ int16 EQ::InventoryProfile::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 lo
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
break;
}
return EQ::invslot::SLOT_INVALID;
}
+5 -5
View File
@@ -19,7 +19,7 @@
#include "inventory_slot.h"
#include "textures.h"
#include "strings.h"
#include "string_util.h"
int8 EQ::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
@@ -86,7 +86,7 @@ bool EQ::InventorySlot::IsValidSlot() const
{
if (_typeless)
return false;
int16 slot_count = invtype::GetInvTypeSize(_type_index);
if (!slot_count || _slot_index < invslot::SLOT_BEGIN || _slot_index >= slot_count)
return false;
@@ -136,7 +136,7 @@ bool EQ::InventorySlot::IsWeaponIndex(int16 slot_index)
{
if (slot_index == invslot::slotPrimary || slot_index == invslot::slotSecondary || slot_index == invslot::slotRange)
return true;
return false;
}
@@ -364,7 +364,7 @@ bool EQ::InventorySlot::operator<(const InventorySlot& rhs) const
{
if (Typeless() || rhs.Typeless())
return inventory_slot_typeless_lessthan(*this, rhs);
if (TypeIndex() < rhs.TypeIndex())
return true;
@@ -384,6 +384,6 @@ bool EQ::operator==(const InventorySlot& lhs, const InventorySlot& rhs)
{
if (lhs.Typeless() || rhs.Typeless())
return ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
return ((lhs.TypeIndex() == rhs.TypeIndex()) && (lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
}
-155
View File
@@ -18,17 +18,7 @@
*
*/
#include <cstring>
#include <fmt/format.h>
#include <csignal>
#include <vector>
#include "ip_util.h"
#include "http/httplib.h"
#include "http/uri.h"
#include "eqemu_logsys.h"
#include "event/event_loop.h"
#include "net/dns.h"
#include "event/task_scheduler.h"
/**
* @param ip
@@ -80,148 +70,3 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
);
}
/**
* Gets local address - pings google to inspect what interface was used locally
* @return
*/
std::string IpUtil::GetLocalIPAddress()
{
char my_ip_address[16];
unsigned int my_port;
struct sockaddr_in server_address{};
struct sockaddr_in my_address{};
int sockfd;
// Connect to server
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return "";
}
// Set server_addr
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
server_address.sin_port = htons(80);
// Connect to server
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
close(sockfd);
return "";
}
// Get my ip address and port
memset(&my_address, 0, sizeof(my_address));
socklen_t len = sizeof(my_address);
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
my_port = ntohs(my_address.sin_port);
return fmt::format("{}", my_ip_address);
}
/**
* Gets public address
* Uses various websites as options to return raw public IP back to the client
* @return
*/
std::string IpUtil::GetPublicIPAddress()
{
std::vector<std::string> endpoints = {
"http://ifconfig.me",
"http://api.ipify.org",
"http://ipinfo.io/ip",
"http://ipecho.net/plain",
};
for (auto &s: endpoints) {
// http get request
uri u(s);
httplib::Client r(
fmt::format(
"{}://{}",
u.get_scheme(),
u.get_host()
).c_str()
);
httplib::Headers headers = {
{"Content-type", "text/plain; charset=utf-8"},
{"User-Agent", "curl/7.81.0"}
};
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
if (auto res = r.Get(fmt::format("/{}", u.get_path()).c_str(), headers)) {
if (res->status == 200) {
if (res->body.find('.') != std::string::npos) {
return res->body;
}
}
}
}
return {};
}
std::string IpUtil::DNSLookupSync(const std::string &addr, int port)
{
auto task_runner = new EQ::Event::TaskScheduler();
auto res = task_runner->Enqueue(
[&]() -> std::string {
bool running = true;
std::string ret;
EQ::Net::DNSLookup(
addr, port, false, [&](const std::string &addr) {
ret = addr;
if (addr.empty()) {
ret = "";
running = false;
}
return ret;
}
);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
auto &loop = EQ::EventLoop::Get();
while (running) {
if (!ret.empty()) {
running = false;
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
LogInfo(
"[DNSLookupSync] Deadline exceeded [{}]",
1500
);
running = false;
}
loop.Process();
}
return ret;
}
);
std::string result = res.get();
safe_delete(task_runner);
return result;
}
bool IpUtil::IsIPAddress(const std::string &ip_address)
{
struct sockaddr_in sa{};
int result = inet_pton(AF_INET, ip_address.c_str(), &(sa.sin_addr));
return result != 0;
}
+1 -8
View File
@@ -30,14 +30,7 @@ public:
static uint32_t IPToUInt(const std::string &ip);
static bool IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask);
static bool IsIpInPrivateRfc1918(const std::string &ip);
static std::string GetLocalIPAddress();
static std::string GetPublicIPAddress();
static std::string DNSLookupSync(
const std::string &addr,
int port
);
static bool IsIPAddress(const std::string &ip_address);
};
#endif //EQEMU_IP_UTIL_H
#endif //EQEMU_IP_UTIL_H
+6 -4
View File
@@ -30,7 +30,6 @@
#include "types.h"
#include "eqemu_exception.h"
#include "eqemu_config.h"
#include "path_manager.h"
namespace EQ {
struct IPCMutex::Implementation {
@@ -41,11 +40,12 @@ namespace EQ {
#endif
};
IPCMutex::IPCMutex(const std::string& name) : locked_(false) {
IPCMutex::IPCMutex(std::string name) : locked_(false) {
imp_ = new Implementation;
#ifdef _WINDOWS
auto Config = EQEmuConfig::get();
std::string final_name = fmt::format("{}/EQEmuMutex_{}", Config->SharedMemDir, name);
std::string final_name = Config->SharedMemDir + "EQEmuMutex_";
final_name += name;
imp_->mut_ = CreateMutex(nullptr,
FALSE,
@@ -55,7 +55,9 @@ namespace EQ {
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
}
#else
std::string final_name = fmt::format("{}/{}.lock", path.GetSharedMemoryPath(), name);
auto Config = EQEmuConfig::get();
std::string final_name = Config->SharedMemDir + name;
final_name += ".lock";
#ifdef __DARWIN
#if __DARWIN_C_LEVEL < 200809L
+1 -1
View File
@@ -37,7 +37,7 @@ namespace EQ {
Creates a named binary semaphore, basically a semaphore that is init S <- 1
\param name The name of this mutex.
*/
IPCMutex(const std::string& name);
IPCMutex(std::string name);
//! Destructor
~IPCMutex();
+9 -9
View File
@@ -370,7 +370,7 @@ namespace EQ
uint32 Slots; // Bitfield for which slots this item can be used in
uint32 Price; // Item cost (?)
uint32 Icon; // Icon Number
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
uint32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag;
bool ArtifactFlag;
@@ -473,14 +473,14 @@ namespace EQ
uint32 LDoNSold;
uint32 BaneDmgRaceAmt;
uint32 AugRestrict;
int32 Endur;
int32 DotShielding;
int32 Attack;
int32 Regen;
int32 ManaRegen;
int32 EnduranceRegen;
int32 Haste;
int32 DamageShield;
uint32 Endur;
uint32 DotShielding;
uint32 Attack;
uint32 Regen;
uint32 ManaRegen;
uint32 EnduranceRegen;
uint32 Haste;
uint32 DamageShield;
uint32 RecastDelay;
int RecastType;
uint32 AugDistiller;
+22 -22
View File
@@ -23,7 +23,7 @@
//#include "races.h"
#include "rulesys.h"
#include "shareddb.h"
#include "strings.h"
#include "string_util.h"
//#include "../common/light_source.h"
@@ -214,7 +214,7 @@ EQ::ItemInstance::~ItemInstance()
bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
{
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
// Check usage type
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
return true;
@@ -245,7 +245,7 @@ bool EQ::ItemInstance::IsStackable() const
{
if (!m_item)
return false;
return m_item->Stackable;
}
@@ -253,7 +253,7 @@ bool EQ::ItemInstance::IsCharged() const
{
if (!m_item)
return false;
if (m_item->MaxCharges > 1)
return true;
else
@@ -381,7 +381,7 @@ EQ::ItemInstance* EQ::ItemInstance::PopItem(uint8 index)
m_contents.erase(index);
return inst; // Return pointer that needs to be deleted (or otherwise managed)
}
return nullptr;
}
@@ -476,7 +476,7 @@ uint8 EQ::ItemInstance::GetTotalItemCount() const
{
if (!m_item)
return 0;
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
@@ -526,7 +526,7 @@ EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugty
{
continue;
}
return GetAugment(i);
return this->GetAugment(i);
}
}
@@ -549,7 +549,7 @@ uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
if (!m_item || !m_item->IsClassCommon())
return false;
bool ornamentSet = false;
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
@@ -642,7 +642,7 @@ void EQ::ItemInstance::PutAugment(uint8 slot, const ItemInstance& augment)
{
if (!m_item || !m_item->IsClassCommon())
return;
PutItem(slot, augment);
}
@@ -655,7 +655,7 @@ void EQ::ItemInstance::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id
if (aug) {
PutAugment(slot, *aug);
safe_delete(aug);
}
}
}
// Remove augment from item and destroy it
@@ -663,7 +663,7 @@ void EQ::ItemInstance::DeleteAugment(uint8 index)
{
if (!m_item || !m_item->IsClassCommon())
return;
DeleteItem(index);
}
@@ -672,7 +672,7 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
{
if (!m_item || !m_item->IsClassCommon())
return nullptr;
return PopItem(index);
}
@@ -680,7 +680,7 @@ bool EQ::ItemInstance::IsAugmented()
{
if (!m_item || !m_item->IsClassCommon())
return false;
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (GetAugmentItemID(index))
return true;
@@ -698,7 +698,7 @@ bool EQ::ItemInstance::ContainsAugmentByID(uint32 item_id)
if (!item_id) {
return false;
}
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
if (GetAugmentItemID(augment_slot) == item_id) {
return true;
@@ -718,7 +718,7 @@ int EQ::ItemInstance::CountAugmentByID(uint32 item_id)
if (!item_id) {
return quantity;
}
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
if (GetAugmentItemID(augment_slot) == item_id) {
quantity++;
@@ -873,7 +873,7 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
return false;
}
}
return true;
}
@@ -1097,7 +1097,7 @@ int EQ::ItemInstance::GetItemElementalFlag(bool augments) const
int EQ::ItemInstance::GetItemElementalDamage(bool augments) const
{
int64 damage = 0;
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->ElemDmgAmt;
@@ -1162,7 +1162,7 @@ int EQ::ItemInstance::GetItemRequiredLevel(bool augments) const
int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
{
int64 damage = 0;
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->Damage;
@@ -1178,7 +1178,7 @@ int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
int EQ::ItemInstance::GetItemBackstabDamage(bool augments) const
{
int64 damage = 0;
int damage = 0;
const auto item = GetItem();
if (item) {
damage = item->BackstabDmg;
@@ -1236,7 +1236,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
{
int64 damage = 0;
int damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgBody == against)
@@ -1253,7 +1253,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) con
int EQ::ItemInstance::GetItemBaneDamageRace(uint16 against, bool augments) const
{
int64 damage = 0;
int damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgRace == against)
@@ -1745,4 +1745,4 @@ EvolveInfo::EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32
EvolveInfo::~EvolveInfo() {
}
}
+5 -14
View File
@@ -30,19 +30,11 @@ struct LootTableEntries_Struct {
float probability;
};
struct ContentFlags {
int16 min_expansion;
int16 max_expansion;
char content_flags[100];
char content_flags_disabled[100];
};
struct LootTable_Struct {
uint32 mincash;
uint32 maxcash;
uint32 avgcoin;
uint32 NumEntries;
ContentFlags content_flags;
uint32 mincash;
uint32 maxcash;
uint32 avgcoin;
uint32 NumEntries;
LootTableEntries_Struct Entries[0];
};
@@ -59,8 +51,7 @@ struct LootDropEntries_Struct {
};
struct LootDrop_Struct {
uint32 NumEntries;
ContentFlags content_flags;
uint32 NumEntries;
LootDropEntries_Struct Entries[0];
};
#pragma pack()
+1 -1
View File
@@ -9,7 +9,7 @@
*/
#include <string.h> /* for memcpy() */
#include "../common/md5.h"
#include "../common/strings.h"
#include "../common/string_util.h"
#include "../common/seperator.h"
MD5::MD5() {
-3
View File
@@ -33,9 +33,6 @@
#include <sys/stat.h>
#endif
#include <filesystem>
namespace fs = std::filesystem;
namespace EQ {
struct MemoryMappedFile::Implementation {
+1 -7
View File
@@ -10,14 +10,8 @@
#include <iterator>
#include "types.h"
class MySQLRequestRow
class MySQLRequestRow : public std::iterator<std::input_iterator_tag, MYSQL_ROW>
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = MYSQL_ROW;
using difference_type = std::ptrdiff_t;
using pointer = MYSQL_ROW*;
using reference = MYSQL_ROW&;
private:
MYSQL_RES* m_Result;
+6 -6
View File
@@ -1,5 +1,5 @@
#include "console_server.h"
#include "../strings.h"
#include "../string_util.h"
#include <fmt/format.h>
EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
@@ -52,11 +52,11 @@ void EQ::Net::ConsoleServer::ConnectionDisconnected(ConsoleServerConnection *c)
void EQ::Net::ConsoleServer::ProcessCommand(ConsoleServerConnection *c, const std::string &cmd)
{
auto split = Strings::Split(cmd, ' ');
auto split = SplitString(cmd, ' ');
if (split.size() > 0) {
auto command = split[0];
command = Strings::ToLower(command);
ToLowerString(command);
if (command == "help" || command == "?") {
c->SendLine("Commands:");
@@ -70,9 +70,9 @@ void EQ::Net::ConsoleServer::ProcessCommand(ConsoleServerConnection *c, const st
c->SendPrompt();
return;
}
split.erase(split.begin(), split.begin() + 1);
auto cmd_def = m_commands.find(command);
if (cmd_def != m_commands.end()) {
if (c->Admin() >= cmd_def->second.status_required) {
+15 -14
View File
@@ -116,42 +116,43 @@ bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMes
}
switch (scm->chan_num) {
case ChatChannel_Guild: {
QueueMessage(fmt::format("{} tells the guild [{}], '{}'", scm->from, scm->guilddbid, scm->message));
break;
}
case ChatChannel_Auction: {
case 4: {
if (RuleB(Chat, ServerWideAuction)) {
QueueMessage(fmt::format("{} auctions, '{}'", scm->from, scm->message));
QueueMessage(fmt::format("{0} auctions, '{1}'", scm->from, scm->message));
break;
} else { // I think we want default action in this case?
return false;
}
}
case ChatChannel_OOC: {
case 5: {
if (RuleB(Chat, ServerWideOOC)) {
QueueMessage(fmt::format("{} says ooc, '{}'", scm->from, scm->message));
QueueMessage(fmt::format("{0} says ooc, '{1}'", scm->from, scm->message));
break;
} else { // I think we want default action in this case?
return false;
}
}
case ChatChannel_Broadcast: {
QueueMessage(fmt::format("{} BROADCASTS, '{}'", scm->from, scm->message));
case 6: {
QueueMessage(fmt::format("{0} BROADCASTS, '{1}'", scm->from, scm->message));
break;
}
case ChatChannel_Tell: {
QueueMessage(fmt::format("[{}] tells {}, '{}'", scm->from, scm->to, scm->message));
case 7: {
QueueMessage(fmt::format("[{0}] tells you, '{1}'", scm->from, scm->message));
if (onTell) {
onTell();
}
break;
}
case ChatChannel_GMSAY: {
QueueMessage(fmt::format("{} GMSAYS, '{}'", scm->from, scm->message));
case 11: {
QueueMessage(fmt::format("{0} GMSAYS, '{1}'", scm->from, scm->message));
break;
}
default: {
return false;
}
+6 -24
View File
@@ -3,7 +3,6 @@
#include "../event/task.h"
#include "../data_verification.h"
#include "crc32.h"
#include "../eqemu_logsys.h"
#include <zlib.h>
#include <fmt/format.h>
#include <sstream>
@@ -309,8 +308,6 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_combined[1] = OP_Combined;
m_last_session_stats = Clock::now();
m_outgoing_budget = owner->m_options.outgoing_data_rate;
LogNetcode("New session [{}] with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
}
//new connection made as client
@@ -469,7 +466,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
for (int i = 1; i >= 0; --i) {
switch (m_encode_passes[i]) {
case EncodeXOR:
if (temp.GetInt8(0) == 0)
if (temp.GetInt8(0) == 0)
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else
Decode(temp, 1, temp.Length() - 1);
@@ -633,8 +630,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
DynamicPacket p;
p.PutSerialize(0, reply);
InternalSend(p);
LogNetcode("[OP_SessionRequest] Session [{}] started with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
}
break;
@@ -652,12 +647,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
m_max_packet_size = reply.max_packet_size;
ChangeStatus(StatusConnected);
LogNetcode(
"[OP_SessionResponse] Session [{}] refresh with encode key [{}]",
m_connect_code,
HostToNetwork(m_encode_key)
);
}
}
break;
@@ -782,12 +771,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
SendDisconnect();
}
LogNetcode(
"[OP_SessionDisconnect] Session [{}] disconnect with encode key [{}]",
m_connect_code,
HostToNetwork(m_encode_key)
);
ChangeStatus(StatusDisconnecting);
break;
}
@@ -852,7 +835,6 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
}
if (p.Length() < (size_t)m_crc_bytes) {
LogNetcode("Session [{}] ignored packet (crc bytes invalid on session)", m_connect_code);
return false;
}
@@ -1096,7 +1078,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
if (m_status == DbProtocolStatus::StatusDisconnected) {
return;
}
auto resends = 0;
auto now = Clock::now();
auto s = &m_streams[stream];
@@ -1131,7 +1113,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
Close();
return;
}
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
auto &p = entry.second.packet;
if (p.Length() >= DaybreakHeader::size()) {
@@ -1412,7 +1394,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
size_t used = 0;
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size();
DynamicPacket first_packet;
first_packet.PutSerialize(0, first_header);
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
@@ -1424,8 +1406,8 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
sent.first_sent = Clock::now();
sent.times_resent = 0;
sent.resend_delay = EQ::Clamp(
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
-9
View File
@@ -65,15 +65,6 @@ EQ::Net::EQStream::~EQStream()
}
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
LogPacketServerClient(
"[{}] [{:#06x}] Size [{}] {}",
OpcodeManager::EmuToName(p->GetOpcode()),
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
p->Size(),
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
);
if (m_opcode_manager && *m_opcode_manager) {
uint16 opcode = 0;
if (p->GetOpcodeBypass() != 0) {
-4
View File
@@ -57,10 +57,6 @@ namespace EQ
virtual void SetOpcodeManager(OpcodeManager **opm) {
m_opcode_manager = opm;
}
virtual OpcodeManager * GetOpcodeManager() const
{
return (*m_opcode_manager);
};
virtual Stats GetStats() const;
virtual void ResetStats();
+1 -11
View File
@@ -135,7 +135,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
auto leg_opcode = *(uint16_t*)&m_buffer[current];
auto leg_size = *(uint16_t*)&m_buffer[current + 2] - 4;
//this creates a small edge case where the exact size of a
//this creates a small edge case where the exact size of a
//packet from the modern protocol can't be "43061256"
//so in send we pad it one byte if that's the case
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(ServerNewLSInfo_Struct)) {
@@ -319,16 +319,6 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
size_t message_len = length;
EQ::Net::StaticPacket packet(&data[0], message_len);
const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
LogPacketServerToServer(
"[{:#06x}] Size [{}] {}",
opcode,
packet.Length(),
(is_detail_enabled ? "\n" + packet.ToString() : "")
);
}
auto cb = m_message_callbacks.find(opcode);
if (cb != m_message_callbacks.end()) {
cb->second(opcode, packet);
-3
View File
@@ -184,9 +184,6 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
MOpcodes.lock();
res = emu_to_eq[emu_op];
MOpcodes.unlock();
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
#ifdef DEBUG_TRANSLATE
fprintf(stderr, "M Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
#endif
+54 -22
View File
@@ -11,7 +11,7 @@
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
@@ -28,11 +28,10 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../inventory_profile.h"
#include "rof_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include <iostream>
#include <sstream>
@@ -53,13 +52,13 @@ namespace RoF
static inline structs::InventorySlot_Struct ServerToRoFCorpseSlot(uint32 server_corpse_slot);
static inline uint32 ServerToRoFCorpseMainSlot(uint32 server_corpse_slot);
static inline structs::TypelessInventorySlot_Struct ServerToRoFTypelessSlot(uint32 server_slot, int16 server_type);
// client to server inventory location converters
static inline uint32 RoFToServerSlot(structs::InventorySlot_Struct rof_slot);
static inline uint32 RoFToServerCorpseSlot(structs::InventorySlot_Struct rof_corpse_slot);
static inline uint32 RoFToServerCorpseMainSlot(uint32 rof_corpse_slot);
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof_slot, int16 rof_type);
// server to client say link converter
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink);
@@ -76,8 +75,12 @@ namespace RoF
{
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -115,7 +118,12 @@ namespace RoF
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -728,6 +736,30 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -1526,7 +1558,7 @@ namespace RoF
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1806,10 +1838,10 @@ namespace RoF
OUT_str(zone_short_name2);
OUT(zone_id);
OUT(zone_instance);
OUT(suspend_buffs);
OUT(fast_regen_hp);
OUT(fast_regen_mana);
OUT(fast_regen_endurance);
OUT(SuspendBuffs);
OUT(FastRegenHP);
OUT(FastRegenMana);
OUT(FastRegenEndurance);
OUT(underworld_teleport_index);
eq->FogDensity = emu->fog_density;
@@ -1817,8 +1849,8 @@ namespace RoF
/*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1;
eq->unknown844 = 600;
OUT(lava_damage);
OUT(min_lava_damage);
OUT(LavaDamage);
OUT(MinLavaDamage);
eq->unknown888 = 1;
eq->unknown889 = 0;
eq->unknown890 = 1;
@@ -5156,7 +5188,7 @@ namespace RoF
void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
{
const EQ::ItemData *item = inst->GetUnscaledItem();
RoF::structs::ItemSerializationHeader hdr;
//sprintf(hdr.unknown000, "06e0002Y1W00");
@@ -5175,7 +5207,7 @@ namespace RoF
slot_id = ServerToRoFSlot(slot_id_in);
break;
}
hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type);
hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot);
hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex);
@@ -5263,7 +5295,7 @@ namespace RoF
ob.write("\0", 1);
ob.write("\0", 1);
RoF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF::structs::ItemBodyStruct));
@@ -5576,7 +5608,7 @@ namespace RoF
iqbs.unknown28 = 0;
iqbs.unknown30 = 0;
iqbs.unknown39 = 1;
ob.write((const char*)&iqbs, sizeof(RoF::structs::ItemQuaternaryBodyStruct));
EQ::OutBuffer::pos_type count_pos = ob.tellp();
@@ -5744,7 +5776,7 @@ namespace RoF
static inline uint32 ServerToRoFCorpseMainSlot(uint32 server_corpse_slot)
{
uint32 RoFSlot = invslot::SLOT_INVALID;
if (server_corpse_slot <= EQ::invslot::CORPSE_END && server_corpse_slot >= EQ::invslot::CORPSE_BEGIN) {
RoFSlot = server_corpse_slot;
}
@@ -6091,7 +6123,7 @@ namespace RoF
return;
}
auto segments = Strings::Split(serverSayLink, '\x12');
auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -6130,7 +6162,7 @@ namespace RoF
return;
}
auto segments = Strings::Split(rofSayLink, '\x12');
auto segments = SplitString(rofSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+75 -44
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -28,11 +28,10 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../inventory_profile.h"
#include "rof2_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include <iostream>
#include <sstream>
@@ -54,13 +53,13 @@ namespace RoF2
static inline structs::InventorySlot_Struct ServerToRoF2CorpseSlot(uint32 server_corpse_slot);
static inline uint32 ServerToRoF2CorpseMainSlot(uint32 server_corpse_slot);
static inline structs::TypelessInventorySlot_Struct ServerToRoF2TypelessSlot(uint32 server_slot, int16 server_type);
// client to server inventory location converters
static inline uint32 RoF2ToServerSlot(structs::InventorySlot_Struct rof2_slot);
static inline uint32 RoF2ToServerCorpseSlot(structs::InventorySlot_Struct rof2_corpse_slot);
static inline uint32 RoF2ToServerCorpseMainSlot(uint32 rof2_corpse_slot);
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2_slot, int16 rof2_type);
// server to client say link converter
static inline void ServerToRoF2SayLink(std::string &rof2_saylink, const std::string &server_saylink);
@@ -77,9 +76,12 @@ namespace RoF2
{
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -120,7 +122,12 @@ namespace RoF2
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -778,6 +785,30 @@ namespace RoF2
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -1856,13 +1887,13 @@ namespace RoF2
OUT_str(zone_short_name2);
OUT(zone_id);
OUT(zone_instance);
OUT(suspend_buffs);
OUT(fast_regen_hp);
OUT(fast_regen_mana);
OUT(fast_regen_endurance);
OUT(SuspendBuffs);
OUT(FastRegenHP);
OUT(FastRegenMana);
OUT(FastRegenEndurance);
OUT(underworld_teleport_index);
eq->fog_density = emu->fog_density;
eq->FogDensity = emu->fog_density;
/*fill in some unknowns with observed values, hopefully it will help */
eq->ZoneTimeZone = 0;
@@ -1874,22 +1905,22 @@ namespace RoF2
eq->SkyRelated2 = -1;
eq->NPCAggroMaxDist = 600;
eq->FilterID = 2008; // Guild Lobby observed value
OUT(lava_damage);
OUT(min_lava_damage);
eq->bDisallowManaStone = 1;
eq->bNoBind = 0;
eq->bNoAttack = 0;
eq->bNoCallOfHero = 0;
eq->bNoFlux = 0;
eq->bNoFear = 0;
eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off
eq->unknown895 = 0;
eq->can_place_campsite = 2;
eq->can_place_guild_banner = 2;
eq->fishing_related = -1; // Set from PoK Example
eq->forage_related = -1; // Set from PoK Example
eq->b_no_levitate = 0;
eq->blooming = 1.0; // Set from PoK Example
OUT(LavaDamage);
OUT(MinLavaDamage);
eq->bDisallowManaStone = 1;
eq->bNoBind = 0;
eq->bNoAttack = 0;
eq->bNoCallOfHero = 0;
eq->bNoFlux = 0;
eq->bNoFear = 0;
eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off
eq->unknown895 = 0;
eq->CanPlaceCampsite = 2;
eq->CanPlaceGuildBanner = 2;
eq->FishingRelated = -1; // Set from PoK Example
eq->ForageRelated = -1; // Set from PoK Example
eq->bNoLevitate = 0;
eq->Blooming = 1.0; // Set from PoK Example
FINISH_ENCODE();
}
@@ -2863,12 +2894,12 @@ namespace RoF2
EQApplicationPacket *inapp = *p;
*p = nullptr;
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
auto outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability) + prereq_size);
inapp->SetReadPosition(sizeof(AARankInfo_Struct)+emu->total_effects * sizeof(AARankEffect_Struct));
std::vector<int32> skill;
std::vector<int32> points;
@@ -2931,7 +2962,7 @@ namespace RoF2
outapp->WriteUInt32(inapp->ReadUInt32()); // base2
outapp->WriteUInt32(inapp->ReadUInt32()); // slot
}
dest->FastQueuePacket(&outapp);
delete inapp;
}
@@ -5031,11 +5062,11 @@ namespace RoF2
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF2::DECODE(OP_MoveItem)");
emu->from_slot = RoF2ToServerSlot(eq->from_slot);
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
IN(number_in_stack);
//LogNetcode("[RoF2] MoveItem Slot from [{}] to [{}], Number [{}]", emu->from_slot, emu->to_slot, emu->number_in_stack);
FINISH_DIRECT_DECODE();
@@ -5412,7 +5443,7 @@ namespace RoF2
void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
{
const EQ::ItemData *item = inst->GetUnscaledItem();
RoF2::structs::ItemSerializationHeader hdr;
//sprintf(hdr.unknown000, "06e0002Y1W00");
@@ -5431,7 +5462,7 @@ namespace RoF2
slot_id = ServerToRoF2Slot(slot_id_in);
break;
}
hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type);
hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot);
hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex);
@@ -5519,7 +5550,7 @@ namespace RoF2
ob.write("\0", 1);
ob.write("\0", 1);
RoF2::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct));
@@ -5842,7 +5873,7 @@ namespace RoF2
iqbs.unknown37a = 0; // (guessed position) New to RoF2
iqbs.unknown38 = 0;
iqbs.unknown39 = 1;
ob.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
EQ::OutBuffer::pos_type count_pos = ob.tellp();
@@ -6042,7 +6073,7 @@ namespace RoF2
uint32 server_slot = EQ::invslot::SLOT_INVALID;
uint32 temp_slot = invslot::SLOT_INVALID;
switch (rof2_slot.Type) {
case invtype::typePossessions: {
if (rof2_slot.Slot >= invslot::POSSESSIONS_BEGIN && rof2_slot.Slot <= invslot::POSSESSIONS_END) {
@@ -6157,11 +6188,11 @@ namespace RoF2
static inline uint32 RoF2ToServerCorpseSlot(structs::InventorySlot_Struct rof2_corpse_slot)
{
uint32 ServerSlot = EQ::invslot::SLOT_INVALID;
if (rof2_corpse_slot.Type != invtype::typeCorpse || rof2_corpse_slot.SubIndex != invbag::SLOT_INVALID || rof2_corpse_slot.AugIndex != invaug::SOCKET_INVALID) {
ServerSlot = EQ::invslot::SLOT_INVALID;
}
else {
ServerSlot = RoF2ToServerCorpseMainSlot(rof2_corpse_slot.Slot);
}
@@ -6315,7 +6346,7 @@ namespace RoF2
return;
}
auto segments = Strings::Split(server_saylink, '\x12');
auto segments = SplitString(server_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -6347,7 +6378,7 @@ namespace RoF2
return;
}
auto segments = Strings::Split(rof2_saylink, '\x12');
auto segments = SplitString(rof2_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "rof2_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 RoF2::invtype::GetInvTypeSize(int16 inv_type)
+1
View File
@@ -59,6 +59,7 @@ E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DisciplineUpdate)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
+39 -44
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -620,40 +620,40 @@ struct NewZone_Struct {
/*0800*/ int32 SkyRelated2; //seen -1 -- maybe some default sky time?
/*0804*/ char WeatherString2[32]; //
/*0836*/ float WeatherChangeTime; // not sure :P
/*0840*/ uint32 Climate;
/*0844*/ int32 NPCAggroMaxDist; //seen 600
/*0848*/ int32 FilterID; //seen 2008 -- maybe zone guide related?
/*0852*/ uint16 zone_id; // this might just be instance ID got 1736 for time
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 suspend_buffs; // padded bool
/*0880*/ uint32 lava_damage; // lava_damage value
/*0884*/ uint32 min_lava_damage; // min cap after resist calcs
/*0888*/ uint8 bDisallowManaStone; // can't use manastone in this zone
/*0889*/ uint8 bNoBind; // can't bind even if outdoor says we can!
/*0890*/ uint8 bNoAttack; // non-attack zone
/*0891*/ uint8 bNoCallOfHero; // coth line disabled
/*0892*/ uint8 bNoFlux; // gflux no worky
/*0893*/ uint8 bNoFear; // fear spells no worky
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off MQ2 calls bNoEncumber
/*0895*/ uint8 unknown895; // padding
/*0896*/ uint32 fast_regen_hp; // percentage I think?
/*0900*/ uint32 fast_regen_mana; // percentage I think?
/*0904*/ uint32 fast_regen_endurance; // percentage I think?
/*0908*/ uint32 can_place_campsite; // 0 = no, 1 = can place, 2 = place and goto
/*0912*/ uint32 can_place_guild_banner; // ^
/*0916*/ float fog_density; // Most zones have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 b_adjust_gamma; // padded bool
/*0924*/ uint32 time_string_id; // Seen 0
/*0928*/ uint32 b_no_mercenaries; // padded bool
/*0932*/ int32 fishing_related; // Seen -1 idk
/*0936*/ int32 forage_related; // Seen -1 idk
/*0940*/ uint32 b_no_levitate; // padded bool
/*0944*/ float blooming; // Seen 1.0 in PoK, and 0.25 in Guild Lobby
/*0840*/ uint32 Climate;
/*0844*/ int32 NPCAggroMaxDist; //seen 600
/*0848*/ int32 FilterID; //seen 2008 -- maybe zone guide related?
/*0852*/ uint16 zone_id; // this might just be instance ID got 1736 for time
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs; // padded bool
/*0880*/ uint32 LavaDamage; // LavaDamage value
/*0884*/ uint32 MinLavaDamage; // min cap after resist calcs
/*0888*/ uint8 bDisallowManaStone; // can't use manastone in this zone
/*0889*/ uint8 bNoBind; // can't bind even if outdoor says we can!
/*0890*/ uint8 bNoAttack; // non-attack zone
/*0891*/ uint8 bNoCallOfHero; // coth line disabled
/*0892*/ uint8 bNoFlux; // gflux no worky
/*0893*/ uint8 bNoFear; // fear spells no worky
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off MQ2 calls bNoEncumber
/*0895*/ uint8 unknown895; // padding
/*0896*/ uint32 FastRegenHP; // percentage I think?
/*0900*/ uint32 FastRegenMana; // percentage I think?
/*0904*/ uint32 FastRegenEndurance; // percentage I think?
/*0908*/ uint32 CanPlaceCampsite; // 0 = no, 1 = can place, 2 = place and goto
/*0912*/ uint32 CanPlaceGuildBanner; // ^
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 bAdjustGamma; // padded bool
/*0924*/ uint32 TimeStringID; // Seen 0
/*0928*/ uint32 bNoMercenaries; // padded bool
/*0932*/ int32 FishingRelated; // Seen -1 idk
/*0936*/ int32 ForageRelated; // Seen -1 idk
/*0940*/ uint32 bNoLevitate; // padded bool
/*0944*/ float Blooming; // Seen 1.0 in PoK, and 0.25 in Guild Lobby
/*0948*/
};
@@ -2649,11 +2649,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*007*/ uint8 unknown007;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*020*/ uint32 unknown020;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -3476,7 +3476,7 @@ struct TraderClick_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Approval;
/*012*/
/*012*/
};
struct FormattedMessage_Struct{
@@ -4989,7 +4989,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
@@ -5218,11 +5218,6 @@ struct SayLinkBodyFrame_Struct {
/*056*/
};
struct Checksum_Struct {
uint64_t checksum;
uint8_t data[2048];
};
}; /*structs*/
}; /*RoF2*/
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "rof_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 RoF::invtype::GetInvTypeSize(int16 inv_type)
+1
View File
@@ -45,6 +45,7 @@ E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DisciplineUpdate)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
+35 -35
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -571,39 +571,39 @@ struct NewZone_Struct {
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
/*0800*/ int32 unknown800; //seen -1
/*0804*/ char unknown804[40]; //
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 suspend_buffs;
/*0880*/ uint32 lava_damage; // Seen 50
/*0884*/ uint32 min_lava_damage; // Seen 10
/*0888*/ uint8 unknown888; // Seen 1
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; // Seen 1
/*0891*/ uint8 unknown891; // Seen 0
/*0892*/ uint8 unknown892; // Seen 0
/*0893*/ uint8 unknown893; // Seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; // Seen 0 - 00
/*0896*/ uint32 fast_regen_hp; // Seen 180
/*0900*/ uint32 fast_regen_mana; // Seen 180
/*0904*/ uint32 fast_regen_endurance; // Seen 180
/*0908*/ uint32 unknown908; // Seen 2
/*0912*/ uint32 unknown912; // Seen 2
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; // Seen 0
/*0924*/ uint32 unknown924; // Seen 0
/*0928*/ uint32 unknown928; // Seen 0
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 LavaDamage; // Seen 50
/*0884*/ uint32 MinLavaDamage; // Seen 10
/*0888*/ uint8 unknown888; // Seen 1
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; // Seen 1
/*0891*/ uint8 unknown891; // Seen 0
/*0892*/ uint8 unknown892; // Seen 0
/*0893*/ uint8 unknown893; // Seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; // Seen 0 - 00
/*0896*/ uint32 FastRegenHP; // Seen 180
/*0900*/ uint32 FastRegenMana; // Seen 180
/*0904*/ uint32 FastRegenEndurance; // Seen 180
/*0908*/ uint32 unknown908; // Seen 2
/*0912*/ uint32 unknown912; // Seen 2
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; // Seen 0
/*0924*/ uint32 unknown924; // Seen 0
/*0928*/ uint32 unknown928; // Seen 0
/*0932*/ int32 unknown932; // Seen -1
/*0936*/ int32 unknown936; // Seen -1
/*0940*/ uint32 unknown940; // Seen 0
/*0944*/ float unknown944; // Seen 1.0
/*0940*/ uint32 unknown940; // Seen 0
/*0944*/ float unknown944; // Seen 1.0
/*0948*/
};
@@ -2622,11 +2622,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*007*/ uint8 unknown007;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*020*/ uint32 unknown020;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -4921,7 +4921,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
+53 -20
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -28,11 +28,10 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../item_instance.h"
#include "sod_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include <iostream>
#include <sstream>
@@ -70,7 +69,12 @@ namespace SoD
{
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -111,7 +115,12 @@ namespace SoD
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -398,7 +407,7 @@ namespace SoD
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -500,6 +509,30 @@ namespace SoD
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -1056,7 +1089,7 @@ namespace SoD
//store away the emu struct
uchar* __emu_buffer = in->pBuffer;
EQ::InternalSerializedItem_Struct* int_struct = (EQ::InternalSerializedItem_Struct*)(&__emu_buffer[4]);
EQ::OutBuffer ob;
@@ -1073,7 +1106,7 @@ namespace SoD
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1332,17 +1365,17 @@ namespace SoD
OUT_str(zone_short_name2);
OUT(zone_id);
OUT(zone_instance);
OUT(suspend_buffs);
OUT(fast_regen_hp);
OUT(fast_regen_mana);
OUT(fast_regen_endurance);
OUT(SuspendBuffs);
OUT(FastRegenHP);
OUT(FastRegenMana);
OUT(FastRegenEndurance);
OUT(underworld_teleport_index);
/*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1;
eq->unknown844 = 600;
OUT(lava_damage);
OUT(min_lava_damage);
OUT(LavaDamage);
OUT(MinLavaDamage);
eq->unknown888 = 1;
eq->unknown889 = 0;
eq->unknown890 = 1;
@@ -1352,8 +1385,8 @@ namespace SoD
eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off
eq->unknown895 = 0;
eq->unknown908 = 2;
eq->unknown912 = 2;
eq->fog_density = emu->fog_density;
eq->unknown912 = 2;
eq->FogDensity = emu->fog_density;
FINISH_ENCODE();
}
@@ -3505,7 +3538,7 @@ namespace SoD
void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQ::ItemData *item = inst->GetUnscaledItem();
SoD::structs::ItemSerializationHeader hdr;
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
@@ -3816,7 +3849,7 @@ namespace SoD
iqbs.HealAmt = item->HealAmt;
iqbs.SpellDmg = item->SpellDmg;
iqbs.Clairvoyance = item->Clairvoyance;
ob.write((const char*)&iqbs, sizeof(SoD::structs::ItemQuaternaryBodyStruct));
EQ::OutBuffer::pos_type count_pos = ob.tellp();
@@ -4028,7 +4061,7 @@ namespace SoD
return;
}
auto segments = Strings::Split(server_saylink, '\x12');
auto segments = SplitString(server_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -4068,7 +4101,7 @@ namespace SoD
return;
}
auto segments = Strings::Split(sod_saylink, '\x12');
auto segments = SplitString(sod_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "sod_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 SoD::invtype::GetInvTypeSize(int16 inv_type)
+1
View File
@@ -36,6 +36,7 @@ E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
+33 -33
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -440,35 +440,35 @@ struct NewZone_Struct {
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
/*0800*/ int32 unknown800; //seen -1
/*0804*/ char unknown804[40]; //
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 suspend_buffs;
/*0880*/ uint32 lava_damage; //seen 50
/*0884*/ uint32 min_lava_damage; //seen 10
/*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1
/*0891*/ uint8 unknown891; //seen 0
/*0892*/ uint8 unknown892; //seen 0
/*0893*/ uint8 unknown893; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; //seen 0 - 00
/*0896*/ uint32 fast_regen_hp; //seen 180
/*0900*/ uint32 fast_regen_mana; //seen 180
/*0904*/ uint32 fast_regen_endurance; //seen 180
/*0908*/ uint32 unknown908; //seen 2
/*0912*/ uint32 unknown912; //seen 2
/*0916*/ float fog_density; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; //seen 0
/*0924*/ uint32 unknown924; //seen 0
/*0928*/ uint32 unknown928; //seen 0
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 LavaDamage; //seen 50
/*0884*/ uint32 MinLavaDamage; //seen 10
/*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1
/*0891*/ uint8 unknown891; //seen 0
/*0892*/ uint8 unknown892; //seen 0
/*0893*/ uint8 unknown893; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; //seen 0 - 00
/*0896*/ uint32 FastRegenHP; //seen 180
/*0900*/ uint32 FastRegenMana; //seen 180
/*0904*/ uint32 FastRegenEndurance; //seen 180
/*0908*/ uint32 unknown908; //seen 2
/*0912*/ uint32 unknown912; //seen 2
/*0916*/ float FogDensity; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; //seen 0
/*0924*/ uint32 unknown924; //seen 0
/*0928*/ uint32 unknown928; //seen 0
/*0932*/
};
@@ -2136,11 +2136,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*007*/ uint8 unknown007;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*020*/ uint32 unknown020;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -4276,7 +4276,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
+52 -19
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -28,11 +28,10 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../item_instance.h"
#include "sof_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include <iostream>
#include <sstream>
@@ -70,7 +69,12 @@ namespace SoF
{
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -109,7 +113,12 @@ namespace SoF
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -378,7 +387,7 @@ namespace SoF
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -488,6 +497,30 @@ namespace SoF
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -852,7 +885,7 @@ namespace SoF
//store away the emu struct
uchar* __emu_buffer = in->pBuffer;
EQ::InternalSerializedItem_Struct* int_struct = (EQ::InternalSerializedItem_Struct*)(&__emu_buffer[4]);
EQ::OutBuffer ob;
@@ -869,7 +902,7 @@ namespace SoF
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1010,17 +1043,17 @@ namespace SoF
OUT_str(zone_short_name2);
OUT(zone_id);
OUT(zone_instance);
OUT(suspend_buffs);
OUT(fast_regen_hp);
OUT(fast_regen_mana);
OUT(fast_regen_endurance);
OUT(SuspendBuffs);
OUT(FastRegenHP);
OUT(FastRegenMana);
OUT(FastRegenEndurance);
OUT(underworld_teleport_index);
/*fill in some unknowns with observed values, hopefully it will help */
eq->unknown796 = -1;
eq->unknown840 = 600;
OUT(lava_damage);
OUT(min_lava_damage);
OUT(LavaDamage);
OUT(MinLavaDamage);
eq->unknown884 = 1;
eq->unknown885 = 0;
eq->unknown886 = 1;
@@ -2903,7 +2936,7 @@ namespace SoF
void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQ::ItemData *item = inst->GetUnscaledItem();
SoF::structs::ItemSerializationHeader hdr;
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
@@ -3212,7 +3245,7 @@ namespace SoF
iqbs.HeroicSVCorrup = item->HeroicSVCorrup;
iqbs.HealAmt = item->HealAmt;
iqbs.SpellDmg = item->SpellDmg;
ob.write((const char*)&iqbs, sizeof(SoF::structs::ItemQuaternaryBodyStruct));
EQ::OutBuffer::pos_type count_pos = ob.tellp();
@@ -3321,7 +3354,7 @@ namespace SoF
static inline uint32 ServerToSoFCorpseSlot(uint32 server_corpse_slot)
{
uint32 SoFSlot = invslot::SLOT_INVALID;
if (server_corpse_slot <= EQ::invslot::slotGeneral8 && server_corpse_slot >= EQ::invslot::slotGeneral1) {
SoFSlot = server_corpse_slot;
}
@@ -3432,7 +3465,7 @@ namespace SoF
return;
}
auto segments = Strings::Split(server_saylink, '\x12');
auto segments = SplitString(server_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -3472,7 +3505,7 @@ namespace SoF
return;
}
auto segments = Strings::Split(sof_saylink, '\x12');
auto segments = SplitString(sof_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "sof_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 SoF::invtype::GetInvTypeSize(int16 inv_type)
+1
View File
@@ -37,6 +37,7 @@ E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
+29 -29
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -444,31 +444,31 @@ struct NewZone_Struct {
/*0700*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
/*0796*/ int32 unknown796; //seen -1
/*0800*/ char unknown800[40]; //
/*0840*/ int32 unknown840; //seen 600
/*0844*/ int32 unknown844;
/*0848*/ uint16 zone_id;
/*0850*/ uint16 zone_instance;
/*0852*/ uint32 scriptNPCReceivedanItem;
/*0856*/ uint32 bCheck; // padded bool
/*0860*/ uint32 scriptIDSomething;
/*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0868*/ uint32 scriptIDSomething3;
/*0872*/ uint32 suspend_buffs;
/*0876*/ uint32 lava_damage; //seen 50
/*0880*/ uint32 min_lava_damage; //seen 10
/*0884*/ uint8 unknown884; //seen 1
/*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj)
/*0886*/ uint8 unknown886; //seen 1
/*0887*/ uint8 unknown887; //seen 0
/*0888*/ uint8 unknown888; //seen 0
/*0893*/ uint8 unknown889; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown891; //seen 0 - 00
/*0892*/ uint32 fast_regen_hp; //seen 180
/*0896*/ uint32 fast_regen_mana; //seen 180
/*0900*/ uint32 fast_regen_endurance; //seen 180
/*0904*/ uint32 unknown904; //seen 2
/*0908*/ uint32 unknown908; //seen 2
/*0840*/ int32 unknown840; //seen 600
/*0844*/ int32 unknown844;
/*0848*/ uint16 zone_id;
/*0850*/ uint16 zone_instance;
/*0852*/ uint32 scriptNPCReceivedanItem;
/*0856*/ uint32 bCheck; // padded bool
/*0860*/ uint32 scriptIDSomething;
/*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0868*/ uint32 scriptIDSomething3;
/*0872*/ uint32 SuspendBuffs;
/*0876*/ uint32 LavaDamage; //seen 50
/*0880*/ uint32 MinLavaDamage; //seen 10
/*0884*/ uint8 unknown884; //seen 1
/*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj)
/*0886*/ uint8 unknown886; //seen 1
/*0887*/ uint8 unknown887; //seen 0
/*0888*/ uint8 unknown888; //seen 0
/*0893*/ uint8 unknown889; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown891; //seen 0 - 00
/*0892*/ uint32 FastRegenHP; //seen 180
/*0896*/ uint32 FastRegenMana; //seen 180
/*0900*/ uint32 FastRegenEndurance; //seen 180
/*0904*/ uint32 unknown904; //seen 2
/*0908*/ uint32 unknown908; //seen 2
/*0912*/
};
@@ -2106,11 +2106,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*007*/ uint8 unknown007;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*020*/ uint32 unknown020;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -4186,7 +4186,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
+43 -35
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -29,10 +29,9 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../item_instance.h"
#include "titanium_structs.h"
#include "../path_manager.h"
#include <sstream>
@@ -70,7 +69,11 @@ namespace Titanium
auto Config = EQEmuConfig::get();
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -111,7 +114,12 @@ namespace Titanium
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -330,13 +338,13 @@ namespace Titanium
SerializeItem(ob, (const EQ::ItemInstance*)eq->inst, ServerToTitaniumSlot(eq->slot_id), 0);
if (ob.tellp() == last_pos)
LogNetcode("Titanium::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
last_pos = ob.tellp();
}
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -432,6 +440,30 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -829,7 +861,7 @@ namespace Titanium
//store away the emu struct
uchar* __emu_buffer = in->pBuffer;
EQ::InternalSerializedItem_Struct* int_struct = (EQ::InternalSerializedItem_Struct*)(&__emu_buffer[4]);
EQ::OutBuffer ob;
@@ -846,7 +878,7 @@ namespace Titanium
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1432,30 +1464,6 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_SetFace)
{
auto emu = reinterpret_cast<FaceChange_Struct*>((*p)->pBuffer);
EQApplicationPacket outapp(OP_Illusion, sizeof(structs::Illusion_Struct));
auto buf = reinterpret_cast<structs::Illusion_Struct*>(outapp.pBuffer);
buf->spawnid = emu->entity_id;
buf->race = -1; // unchanged
buf->gender = -1; // unchanged
buf->texture = -1; // unchanged
buf->helmtexture = -1; // unchanged
buf->face = emu->face;
buf->hairstyle = emu->hairstyle;
buf->haircolor = emu->haircolor;
buf->beard = emu->beard;
buf->beardcolor = emu->beardcolor;
buf->size = 0.0f; // unchanged
safe_delete(*p); // not using the original packet
dest->QueuePacket(&outapp, ack_req);
}
ENCODE(OP_ShopPlayerSell)
{
ENCODE_LENGTH_EXACT(Merchant_Purchase_Struct);
@@ -2813,7 +2821,7 @@ namespace Titanium
return;
}
auto segments = Strings::Split(server_saylink, '\x12');
auto segments = SplitString(server_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -2853,7 +2861,7 @@ namespace Titanium
return;
}
auto segments = Strings::Split(titanium_saylink, '\x12');
auto segments = SplitString(titanium_saylink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "titanium_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 Titanium::invtype::GetInvTypeSize(int16 inv_type)
+1 -1
View File
@@ -33,6 +33,7 @@ E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
@@ -65,7 +66,6 @@ E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendCharInfo)
E(OP_SendAATable)
E(OP_SetFace)
E(OP_ShopPlayerSell)
E(OP_SpecialMesg)
E(OP_TaskDescription)
+3 -2
View File
@@ -1761,7 +1761,8 @@ struct AdventureRequestResponse_Struct{
struct Illusion_Struct {
/*000*/ uint32 spawnid;
/*004*/ char charname[64];
/*068*/ int race;
/*068*/ uint16 race;
/*070*/ char unknown070[2];
/*072*/ uint8 gender;
/*073*/ uint8 texture;
/*074*/ uint8 helmtexture;
@@ -3396,7 +3397,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
+52 -19
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -28,11 +28,10 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../strings.h"
#include "../string_util.h"
#include "../item_instance.h"
#include "uf_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include <iostream>
#include <sstream>
@@ -70,7 +69,12 @@ namespace UF
{
//create our opcode manager if we havent already
if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
//load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@@ -111,7 +115,12 @@ namespace UF
//we need to go to every stream and replace it's manager.
if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//TODO: get this file name from the config file
auto Config = EQEmuConfig::get();
std::string opfile = Config->PatchDir;
opfile += "patch_";
opfile += name;
opfile += ".conf";
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@@ -518,7 +527,7 @@ namespace UF
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -630,6 +639,30 @@ namespace UF
FINISH_ENCODE();
}
ENCODE(OP_DzCompass)
{
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
sizeof(structs::DynamicZoneCompass_Struct) +
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
);
OUT(client_id);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
{
OUT(entries[i].dz_zone_id);
OUT(entries[i].dz_instance_id);
OUT(entries[i].dz_type);
OUT(entries[i].x);
OUT(entries[i].y);
OUT(entries[i].z);
}
FINISH_ENCODE();
}
ENCODE(OP_DzExpeditionEndsWarning)
{
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
@@ -1281,7 +1314,7 @@ namespace UF
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1556,19 +1589,19 @@ namespace UF
OUT_str(zone_short_name2);
OUT(zone_id);
OUT(zone_instance);
OUT(suspend_buffs);
OUT(fast_regen_hp);
OUT(fast_regen_mana);
OUT(fast_regen_endurance);
OUT(SuspendBuffs);
OUT(FastRegenHP);
OUT(FastRegenMana);
OUT(FastRegenEndurance);
OUT(underworld_teleport_index);
eq->fog_density = emu->fog_density;
eq->FogDensity = emu->fog_density;
/*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1;
eq->unknown844 = 600;
OUT(lava_damage);
OUT(min_lava_damage);
OUT(LavaDamage);
OUT(MinLavaDamage);
eq->unknown888 = 1;
eq->unknown889 = 0;
eq->unknown890 = 1;
@@ -1708,7 +1741,7 @@ namespace UF
OUT(WIS);
OUT(face);
// OUT(unknown02264[47]);
if (spells::SPELLBOOK_SIZE <= EQ::spells::SPELLBOOK_SIZE) {
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
@@ -2089,7 +2122,7 @@ namespace UF
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].base_value = inapp->ReadUInt32();
@@ -3802,7 +3835,7 @@ namespace UF
void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQ::ItemData *item = inst->GetUnscaledItem();
UF::structs::ItemSerializationHeader hdr;
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
@@ -4387,7 +4420,7 @@ namespace UF
return;
}
auto segments = Strings::Split(serverSayLink, '\x12');
auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
@@ -4427,7 +4460,7 @@ namespace UF
return;
}
auto segments = Strings::Split(ufSayLink, '\x12');
auto segments = SplitString(ufSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
+2 -2
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "uf_limits.h"
#include "../strings.h"
#include "../string_util.h"
int16 UF::invtype::GetInvTypeSize(int16 inv_type)
+1
View File
@@ -39,6 +39,7 @@ E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DisciplineUpdate)
E(OP_DzChooseZone)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzExpeditionInvite)
+34 -34
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -440,35 +440,35 @@ struct NewZone_Struct {
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
/*0800*/ int32 unknown800; //seen -1
/*0804*/ char unknown804[40]; //
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 suspend_buffs;
/*0880*/ uint32 lava_damage; //seen 50
/*0884*/ uint32 min_lava_damage; //seen 10
/*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1
/*0891*/ uint8 unknown891; //seen 0
/*0892*/ uint8 unknown892; //seen 0
/*0893*/ uint8 unknown893; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; //seen 0 - 00
/*0896*/ uint32 fast_regen_hp; //seen 180
/*0900*/ uint32 fast_regen_mana; //seen 180
/*0904*/ uint32 fast_regen_endurance; //seen 180
/*0908*/ uint32 unknown908; //seen 2
/*0912*/ uint32 unknown912; //seen 2
/*0916*/ float fog_density; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; //seen 0
/*0924*/ uint32 unknown924; //seen 0
/*0928*/ uint32 unknown928; //seen 0
/*0844*/ int32 unknown844; //seen 600
/*0848*/ int32 unknown848;
/*0852*/ uint16 zone_id;
/*0854*/ uint16 zone_instance;
/*0856*/ uint32 scriptNPCReceivedanItem;
/*0860*/ uint32 bCheck; // padded bool
/*0864*/ uint32 scriptIDSomething;
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 LavaDamage; //seen 50
/*0884*/ uint32 MinLavaDamage; //seen 10
/*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1
/*0891*/ uint8 unknown891; //seen 0
/*0892*/ uint8 unknown892; //seen 0
/*0893*/ uint8 unknown893; //seen 0 - 00
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
/*0895*/ uint8 unknown895; //seen 0 - 00
/*0896*/ uint32 FastRegenHP; //seen 180
/*0900*/ uint32 FastRegenMana; //seen 180
/*0904*/ uint32 FastRegenEndurance; //seen 180
/*0908*/ uint32 unknown908; //seen 2
/*0912*/ uint32 unknown912; //seen 2
/*0916*/ float FogDensity; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16
/*0920*/ uint32 unknown920; //seen 0
/*0924*/ uint32 unknown924; //seen 0
/*0928*/ uint32 unknown928; //seen 0
/*0932*/ uint8 unknown932[12];
};
@@ -2185,11 +2185,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*007*/ uint8 unknown007;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*020*/ uint32 unknown020;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -3997,7 +3997,7 @@ struct ItemSerializationHeaderFinish
{
uint16 ornamentIcon;
/*060*/ uint8 unknown060; //0
/*061*/ uint8 unknown061; //0 -
/*061*/ uint8 unknown061; //0 -
/*062*/ uint8 isCopied; // New to Underfoot // Copied flag on item
/*063*/ uint8 ItemClass; //0, 1, or 2
};
@@ -4357,7 +4357,7 @@ struct DynamicZoneCompassEntry_Struct
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*008*/ uint32 unknown008;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
-133
View File
@@ -1,133 +0,0 @@
#include "path_manager.h"
#include "file.h"
#include "eqemu_logsys.h"
#include "eqemu_config.h"
#include "strings.h"
#include <filesystem>
namespace fs = std::filesystem;
inline std::string striptrailingslash(const std::string &file_path)
{
if (file_path.back() == '/' || file_path.back() == '\\') {
return file_path.substr(0, file_path.length() - 1);
}
return file_path;
}
void PathManager::LoadPaths()
{
m_server_path = File::FindEqemuConfigPath();
std::filesystem::current_path(m_server_path);
LogInfo("[PathManager] server [{}]", m_server_path);
if (!EQEmuConfig::LoadConfig()) {
LogError("[PathManager] Failed to load eqemu config");
return;
}
const auto c = EQEmuConfig::get();
// maps
if (File::Exists(fs::path{m_server_path + "/" + c->MapDir}.string())) {
m_maps_path = fs::relative(fs::path{m_server_path + "/" + c->MapDir}).string();
}
else if (File::Exists(fs::path{m_server_path + "/maps"}.string())) {
m_maps_path = fs::relative(fs::path{m_server_path + "/maps"}).string();
}
else if (File::Exists(fs::path{m_server_path + "/Maps"}.string())) {
m_maps_path = fs::relative(fs::path{m_server_path + "/Maps"}).string();
}
// quests
if (File::Exists(fs::path{m_server_path + "/" + c->QuestDir}.string())) {
m_quests_path = fs::relative(fs::path{m_server_path + "/" + c->QuestDir}).string();
}
// plugins
if (File::Exists(fs::path{m_server_path + "/" + c->PluginDir}.string())) {
m_plugins_path = fs::relative(fs::path{m_server_path + "/" + c->PluginDir}).string();
}
// lua_modules
if (File::Exists(fs::path{m_server_path + "/" + c->LuaModuleDir}.string())) {
m_lua_modules_path = fs::relative(fs::path{m_server_path + "/" + c->LuaModuleDir}).string();
}
// lua mods
if (File::Exists(fs::path{ m_server_path + "/mods" }.string())) {
m_lua_mods_path = fs::relative(fs::path{ m_server_path + "/mods" }).string();
}
// patches
if (File::Exists(fs::path{m_server_path + "/" + c->PatchDir}.string())) {
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
}
// shared_memory_path
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
}
// logging path
if (File::Exists(fs::path{m_server_path + "/" + c->LogDir}.string())) {
m_log_path = fs::relative(fs::path{m_server_path + "/" + c->LogDir}).string();
}
LogInfo("[PathManager] logs [{}]", m_log_path);
LogInfo("[PathManager] lua mods [{}]", m_lua_mods_path);
LogInfo("[PathManager] lua_modules [{}]", m_lua_modules_path);
LogInfo("[PathManager] maps [{}]", m_maps_path);
LogInfo("[PathManager] patches [{}]", m_patch_path);
LogInfo("[PathManager] plugins [{}]", m_plugins_path);
LogInfo("[PathManager] quests [{}]", m_quests_path);
LogInfo("[PathManager] shared_memory [{}]", m_shared_memory_path);
}
const std::string &PathManager::GetServerPath() const
{
return m_server_path;
}
const std::string &PathManager::GetMapsPath() const
{
return m_maps_path;
}
const std::string &PathManager::GetQuestsPath() const
{
return m_quests_path;
}
const std::string &PathManager::GetPluginsPath() const
{
return m_plugins_path;
}
const std::string &PathManager::GetSharedMemoryPath() const
{
return m_shared_memory_path;
}
const std::string &PathManager::GetLogPath() const
{
return m_log_path;
}
const std::string &PathManager::GetPatchPath() const
{
return m_patch_path;
}
const std::string &PathManager::GetLuaModulesPath() const
{
return m_lua_modules_path;
}
const std::string &PathManager::GetLuaModsPath() const
{
return m_lua_mods_path;
}
-35
View File
@@ -1,35 +0,0 @@
#ifndef EQEMU_PATH_MANAGER_H
#define EQEMU_PATH_MANAGER_H
#include <string>
class PathManager {
public:
void LoadPaths();
[[nodiscard]] const std::string &GetLogPath() const;
[[nodiscard]] const std::string &GetLuaModsPath() const;
[[nodiscard]] const std::string &GetLuaModulesPath() const;
[[nodiscard]] const std::string &GetMapsPath() const;
[[nodiscard]] const std::string &GetPatchPath() const;
[[nodiscard]] const std::string &GetPluginsPath() const;
[[nodiscard]] const std::string &GetQuestsPath() const;
[[nodiscard]] const std::string &GetServerPath() const;
[[nodiscard]] const std::string &GetSharedMemoryPath() const;
private:
std::string m_log_path;
std::string m_lua_mods_path;
std::string m_lua_modules_path;
std::string m_maps_path;
std::string m_patch_path;
std::string m_plugins_path;
std::string m_quests_path;
std::string m_server_path;
std::string m_shared_memory_path;
};
extern PathManager path;
#endif //EQEMU_PATH_MANAGER_H
+4 -8
View File
@@ -58,8 +58,7 @@ XS(XS_EQDB_field_count)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->field_count();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
@@ -85,8 +84,7 @@ XS(XS_EQDB_affected_rows)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->affected_rows();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
@@ -112,8 +110,7 @@ XS(XS_EQDB_insert_id)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->insert_id();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
@@ -139,8 +136,7 @@ XS(XS_EQDB_get_errno)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->get_errno();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
+2 -4
View File
@@ -54,8 +54,7 @@ XS(XS_EQDBRes_num_rows)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->num_rows();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
@@ -81,8 +80,7 @@ XS(XS_EQDBRes_num_fields)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->num_fields();
XSprePUSH;
PUSHu((UV) RETVAL);
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
-2
View File
@@ -67,8 +67,6 @@ std::string GetPlatformName()
return "Launch";
case EQEmuExePlatform::ExePlatformHC:
return "HC";
case EQEmuExePlatform::ExePlatformTests:
return "Tests";
default:
return "";
}
+1 -2
View File
@@ -36,8 +36,7 @@ enum EQEmuExePlatform
ExePlatformSharedMemory,
ExePlatformClientImport,
ExePlatformClientExport,
ExePlatformHC,
ExePlatformTests
ExePlatformHC
};
void RegisterExecutablePlatform(EQEmuExePlatform p);

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