diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 76d9d1ea7..7c1882292 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,9 +3,8 @@ on: push: branches: - master - - tob_patch + - develop pull_request: - jobs: linux: name: Linux @@ -26,6 +25,17 @@ jobs: sudo apt-get update sudo apt-get install -y build-essential ninja-build ccache uuid-dev + - name: Restore vcpkg Cache + uses: actions/cache@v5 + with: + path: | + build/vcpkg_installed + submodules/vcpkg/downloads + key: ${{ runner.os }}-vcpkg-${{ hashFiles('vcpkg.json') }} + restore-keys: | + ${{ runner.os }}-vcpkg-${{ hashFiles('vcpkg.json') }}- + ${{ runner.os }}-vcpkg- + - name: Configure run: | cmake -S . -B build -G Ninja \ @@ -48,6 +58,9 @@ jobs: windows: name: Windows runs-on: windows-latest + env: + VCPKG_DOWNLOADS: ${{ github.workspace }}\submodules\vcpkg\downloads + VCPKG_BINARY_SOURCES: 'clear;files,${{ github.workspace }}\vcpkg_archives,readwrite' steps: - name: Checkout source uses: actions/checkout@v5 @@ -56,12 +69,22 @@ jobs: - name: Enable long paths run: git config --global core.longpaths true - + - name: Setup MSVC environment - uses: ilammy/msvc-dev-cmd@v1 + uses: TheMrMilchmann/setup-msvc-dev@v4 with: arch: x64 + - name: Restore vcpkg Cache + uses: actions/cache@v5 + with: + path: | + ${{ env.VCPKG_DOWNLOADS }} + ${{ github.workspace }}/vcpkg_archives + key: ${{ runner.os }}-vcpkg-${{ hashFiles('vcpkg.json') }} + restore-keys: | + ${{ runner.os }}-vcpkg- + - name: Configure shell: pwsh run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index b5f332e98..6f42bad57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ option(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON) if(MSVC) add_compile_options(/bigobj) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS NOMINMAX WIN32_LEAN_AND_MEAN CRASH_LOGGING _HAS_AUTO_PTR_ETC) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS NOMINMAX WIN32_LEAN_AND_MEAN CRASH_LOGGING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") option(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." OFF) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d9fa4ef93..1fa0d0af8 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -6,6 +6,7 @@ set(common_sources bodytypes.cpp classes.cpp cli/eqemu_command_handler.cpp + compiler_macros.h compression.cpp content/world_content_service.cpp crash.cpp diff --git a/common/compiler_macros.h b/common/compiler_macros.h new file mode 100644 index 000000000..16088a405 --- /dev/null +++ b/common/compiler_macros.h @@ -0,0 +1,20 @@ +#pragma once + +#if defined(_MSC_VER) + #define PUSH_DISABLE_DEPRECATED_WARNINGS() __pragma(warning(push)) \ + __pragma(warning(disable:4996)) + #define POP_DISABLE_DEPRECATED_WARNINGS() __pragma(warning(pop)) +#elif defined(__GNUC__) || defined(__clang__) + #define PUSH_DISABLE_DEPRECATED_WARNINGS() _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + #define POP_DISABLE_DEPRECATED_WARNINGS() _Pragma("GCC diagnostic pop") +#else + #define PUSH_DISABLE_DEPRECATED_WARNINGS() + #define POP_DISABLE_DEPRECATED_WARNINGS() +#endif + +#if defined(_MSC_VER) && !defined(__clang__) + #define UNREACHABLE() __assume(0) +#else + #define UNREACHABLE() __builtin_unreachable() +#endif \ No newline at end of file diff --git a/common/json/jsoncpp.cpp b/common/json/jsoncpp.cpp index 759e68fa6..eb1bd5a14 100644 --- a/common/json/jsoncpp.cpp +++ b/common/json/jsoncpp.cpp @@ -271,11 +271,7 @@ static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readVa namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr CharReaderPtr; -#else -typedef std::auto_ptr CharReaderPtr; -#endif // Implementation of class Features // //////////////////////////////// @@ -4153,11 +4149,7 @@ Value& Path::make(Value& root) const { namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr StreamWriterPtr; -#else -typedef std::auto_ptr StreamWriterPtr; -#endif static bool containsControlCharacter(const char* str) { while (*str) { diff --git a/libs/luabind/luabind/adopt_policy.hpp b/libs/luabind/luabind/adopt_policy.hpp index 5e81b948b..dc2426a05 100644 --- a/libs/luabind/luabind/adopt_policy.hpp +++ b/libs/luabind/luabind/adopt_policy.hpp @@ -103,7 +103,7 @@ namespace luabind { namespace detail if (luabind::move_back_reference(L, ptr)) return; - make_instance(L, std::auto_ptr(ptr)); + make_instance(L, std::unique_ptr(ptr)); } }; diff --git a/libs/luabind/luabind/class.hpp b/libs/luabind/luabind/class.hpp index 5b8636b97..a2188b358 100644 --- a/libs/luabind/luabind/class.hpp +++ b/libs/luabind/luabind/class.hpp @@ -335,7 +335,7 @@ namespace luabind template struct default_pointer { - typedef std::auto_ptr type; + typedef std::unique_ptr type; }; template diff --git a/libs/luabind/luabind/detail/constructor.hpp b/libs/luabind/luabind/detail/constructor.hpp index 1cbceb789..c3fc8ba7c 100644 --- a/libs/luabind/luabind/detail/constructor.hpp +++ b/libs/luabind/luabind/detail/constructor.hpp @@ -46,7 +46,7 @@ struct construct_aux<0, T, Pointer, Signature> object_rep* self = touserdata(self_); class_rep* cls = self->crep(); - std::auto_ptr instance(new T); + std::unique_ptr instance(new T); inject_backref(self_.interpreter(), instance.get(), instance.get()); void* naked_ptr = instance.get(); @@ -55,7 +55,7 @@ struct construct_aux<0, T, Pointer, Signature> void* storage = self->allocate(sizeof(holder_type)); self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); + std::move(ptr), registered_class::id, naked_ptr, cls)); } }; @@ -92,7 +92,7 @@ struct construct_aux object_rep* self = touserdata(self_); class_rep* cls = self->crep(); - std::auto_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); + std::unique_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); inject_backref(self_.interpreter(), instance.get(), instance.get()); void* naked_ptr = instance.get(); @@ -101,7 +101,7 @@ struct construct_aux void* storage = self->allocate(sizeof(holder_type)); self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); + std::move(ptr), registered_class::id, naked_ptr, cls)); } }; diff --git a/libs/luabind/luabind/detail/has_get_pointer.hpp b/libs/luabind/luabind/detail/has_get_pointer.hpp index 8a001ddda..67d6a7639 100644 --- a/libs/luabind/luabind/detail/has_get_pointer.hpp +++ b/libs/luabind/luabind/detail/has_get_pointer.hpp @@ -58,7 +58,7 @@ namespace has_get_pointer_ T* get_pointer(T const volatile*); template - T* get_pointer(std::auto_ptr const&); + T* get_pointer(std::unique_ptr const&); # endif diff --git a/libs/luabind/luabind/detail/instance_holder.hpp b/libs/luabind/luabind/detail/instance_holder.hpp index 456e13e6b..2c1d5d955 100644 --- a/libs/luabind/luabind/detail/instance_holder.hpp +++ b/libs/luabind/luabind/detail/instance_holder.hpp @@ -57,7 +57,7 @@ inline mpl::true_ check_const_pointer(void const*) } template -void release_ownership(std::auto_ptr& p) +void release_ownership(std::unique_ptr& p) { p.release(); } @@ -83,7 +83,7 @@ public: P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls ) : instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0)) - , p(p) + , p(std::move(p)) , weak(0) , dynamic_id(dynamic_id) , dynamic_ptr(dynamic_ptr) diff --git a/libs/luabind/luabind/detail/make_instance.hpp b/libs/luabind/luabind/detail/make_instance.hpp index 3150cf048..66d23fbd8 100644 --- a/libs/luabind/luabind/detail/make_instance.hpp +++ b/libs/luabind/luabind/detail/make_instance.hpp @@ -88,7 +88,7 @@ void make_instance(lua_State* L, P p) try { - new (storage) holder_type(p, dynamic.first, dynamic.second, cls); + new (storage) holder_type(std::move(p), dynamic.first, dynamic.second, cls); } catch (...) { diff --git a/libs/luabind/luabind/detail/policy.hpp b/libs/luabind/luabind/detail/policy.hpp index e154507e4..19cd2f1ae 100644 --- a/libs/luabind/luabind/detail/policy.hpp +++ b/libs/luabind/luabind/detail/policy.hpp @@ -169,7 +169,7 @@ namespace luabind { namespace detail { if (get_pointer(x)) { - make_instance(L, x); + make_instance(L, std::move(x)); } else { @@ -180,8 +180,8 @@ namespace luabind { namespace detail template void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_) { - std::auto_ptr ptr(new T(x)); - make_instance(L, ptr); + std::unique_ptr ptr(new T(x)); + make_instance(L, std::move(ptr)); } template diff --git a/libs/luabind/luabind/function.hpp b/libs/luabind/luabind/function.hpp index e156fbfcb..b93ca2627 100644 --- a/libs/luabind/luabind/function.hpp +++ b/libs/luabind/luabind/function.hpp @@ -46,7 +46,7 @@ namespace detail template scope def(char const* name, F f, Policies const& policies) { - return scope(std::auto_ptr( + return scope(std::unique_ptr( new detail::function_registration(name, f, policies))); } diff --git a/libs/luabind/luabind/scope.hpp b/libs/luabind/luabind/scope.hpp index 3b5f293bf..e2cfaed36 100644 --- a/libs/luabind/luabind/scope.hpp +++ b/libs/luabind/luabind/scope.hpp @@ -56,7 +56,7 @@ namespace luabind { struct LUABIND_API scope { scope(); - explicit scope(std::auto_ptr reg); + explicit scope(std::unique_ptr reg); scope(scope const& other_); ~scope(); diff --git a/libs/luabind/src/class.cpp b/libs/luabind/src/class.cpp index 8a67cf6f3..f42b9a8c0 100644 --- a/libs/luabind/src/class.cpp +++ b/libs/luabind/src/class.cpp @@ -235,7 +235,7 @@ namespace luabind { namespace detail { // -- interface --------------------------------------------------------- class_base::class_base(char const* name) - : scope(std::auto_ptr( + : scope(std::unique_ptr( m_registration = new class_registration(name)) ) { @@ -258,14 +258,14 @@ namespace luabind { namespace detail { void class_base::add_member(registration* member) { - std::auto_ptr ptr(member); - m_registration->m_members.operator,(scope(ptr)); + std::unique_ptr ptr(member); + m_registration->m_members.operator,(scope(std::move(ptr))); } void class_base::add_default_member(registration* member) { - std::auto_ptr ptr(member); - m_registration->m_default_members.operator,(scope(ptr)); + std::unique_ptr ptr(member); + m_registration->m_default_members.operator,(scope(std::move(ptr))); } const char* class_base::name() const diff --git a/libs/luabind/src/scope.cpp b/libs/luabind/src/scope.cpp index 52bd132f9..0333205ce 100644 --- a/libs/luabind/src/scope.cpp +++ b/libs/luabind/src/scope.cpp @@ -49,7 +49,8 @@ namespace luabind { namespace detail { { } - scope::scope(std::auto_ptr reg) + + scope::scope(std::unique_ptr reg) : m_chain(reg.release()) { } @@ -193,7 +194,7 @@ namespace luabind { }; namespace_::namespace_(char const* name) - : scope(std::auto_ptr( + : scope(std::unique_ptr( m_registration = new registration_(name))) { } diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index 2ef0713bd..3fa140768 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -16,11 +16,12 @@ along with this program. If not, see . */ #include "encryption.h" +#include "common/compiler_macros.h" #ifdef EQEMU_USE_OPENSSL -#include -#include -#include +#include +#include +#include #endif #ifdef EQEMU_USE_MBEDTLS #include @@ -32,6 +33,8 @@ #include #include +#include + #ifdef ENABLE_SECURITY #include @@ -127,21 +130,92 @@ const char *eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char *buff #endif #ifdef EQEMU_USE_OPENSSL - DES_key_schedule k; - DES_cblock v; - - memset(&k, 0, sizeof(DES_key_schedule)); - memset(&v, 0, sizeof(DES_cblock)); - + // Decrypt requires block-aligned input; encrypt zero-pads a trailing + // partial block to match the legacy DES_ncbc_encrypt semantics the + // game protocol expects. if (!enc && buffer_in_sz && buffer_in_sz % 8 != 0) { return nullptr; } - DES_ncbc_encrypt((const unsigned char*)buffer_in, (unsigned char*)buffer_out, (long)buffer_in_sz, &k, &v, enc); + unsigned char key[8] = {0}; + unsigned char iv[8] = {0}; + + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (!ctx) { + return nullptr; + } + + bool result = EVP_CipherInit_ex2(ctx, EVP_des_cbc(), key, iv, enc, nullptr) == 1; + if (result) { + EVP_CIPHER_CTX_set_padding(ctx, 0); + + const unsigned char* src = reinterpret_cast(buffer_in); + size_t src_len = buffer_in_sz; + std::unique_ptr padded; + + if (enc && buffer_in_sz % 8 != 0) { + src_len = ((buffer_in_sz / 8) + 1) * 8; + padded.reset(new unsigned char[src_len]()); + memcpy(padded.get(), buffer_in, buffer_in_sz); + src = padded.get(); + } + + int outl = 0; + int final_len = 0; + result = EVP_CipherUpdate(ctx, reinterpret_cast(buffer_out), &outl, src, static_cast(src_len)) == 1 + && EVP_CipherFinal_ex(ctx, reinterpret_cast(buffer_out) + outl, &final_len) == 1; + } + + EVP_CIPHER_CTX_free(ctx); + if (!result) { + return nullptr; + } #endif return buffer_out; } +#ifdef EQEMU_USE_OPENSSL +static OSSL_PROVIDER *s_legacy_provider = nullptr; +static OSSL_PROVIDER *s_default_provider = nullptr; +#endif + +bool eqcrypt_init() +{ +#ifdef EQEMU_USE_OPENSSL + if (!s_default_provider) { + s_default_provider = OSSL_PROVIDER_load(nullptr, "default"); + } + if (!s_legacy_provider) { + s_legacy_provider = OSSL_PROVIDER_load(nullptr, "legacy"); + } + + if (!s_default_provider || !s_legacy_provider) { + char buf[256]; + while (auto err = ERR_get_error()) { + ERR_error_string_n(err, buf, sizeof(buf)); + LogError("OpenSSL provider load failure: {}", buf); + } + return false; + } +#endif + + return true; +} + +void eqcrypt_shutdown() +{ +#ifdef EQEMU_USE_OPENSSL + if (s_legacy_provider) { + OSSL_PROVIDER_unload(s_legacy_provider); + s_legacy_provider = nullptr; + } + if (s_default_provider) { + OSSL_PROVIDER_unload(s_default_provider); + s_default_provider = nullptr; + } +#endif +} + std::string eqcrypt_md5(const std::string &msg) { std::string ret; @@ -164,12 +238,12 @@ std::string eqcrypt_md5(const std::string &msg) unsigned char md5_digest[16]; char tmp[4]; - MD5((const unsigned char*)msg.c_str(), msg.length(), md5_digest); - - for (int i = 0; i < 16; ++i) { - sprintf(&tmp[0], "%02x", md5_digest[i]); - ret.push_back(tmp[0]); - ret.push_back(tmp[1]); + if (EVP_Digest(msg.data(), msg.length(), md5_digest, nullptr, EVP_md5(), nullptr) == 1) { + for (int i = 0; i < 16; ++i) { + sprintf(&tmp[0], "%02x", md5_digest[i]); + ret.push_back(tmp[0]); + ret.push_back(tmp[1]); + } } #endif @@ -198,12 +272,12 @@ std::string eqcrypt_sha1(const std::string &msg) unsigned char sha_digest[20]; char tmp[4]; - SHA1((const unsigned char*)msg.c_str(), msg.length(), sha_digest); - - for (int i = 0; i < 20; ++i) { - sprintf(&tmp[0], "%02x", sha_digest[i]); - ret.push_back(tmp[0]); - ret.push_back(tmp[1]); + if (EVP_Digest(msg.data(), msg.length(), sha_digest, nullptr, EVP_sha1(), nullptr) == 1) { + for (int i = 0; i < 20; ++i) { + sprintf(&tmp[0], "%02x", sha_digest[i]); + ret.push_back(tmp[0]); + ret.push_back(tmp[1]); + } } #endif @@ -232,12 +306,12 @@ std::string eqcrypt_sha512(const std::string &msg) unsigned char sha_digest[64]; char tmp[4]; - SHA512((const unsigned char*)msg.c_str(), msg.length(), sha_digest); - - for (int i = 0; i < 64; ++i) { - sprintf(&tmp[0], "%02x", sha_digest[i]); - ret.push_back(tmp[0]); - ret.push_back(tmp[1]); + if (EVP_Digest(msg.data(), msg.length(), sha_digest, nullptr, EVP_sha512(), nullptr) == 1) { + for (int i = 0; i < 64; ++i) { + sprintf(&tmp[0], "%02x", sha_digest[i]); + ret.push_back(tmp[0]); + ret.push_back(tmp[1]); + } } #endif diff --git a/loginserver/encryption.h b/loginserver/encryption.h index 4f188789d..d1f683d06 100644 --- a/loginserver/encryption.h +++ b/loginserver/encryption.h @@ -48,10 +48,20 @@ namespace CryptoHash { } std::string GetEncryptionByModeId(uint32 mode); + +// DES-CBC with an all-zero key and IV (EQ login protocol obfuscation, not security). +// On encrypt, a trailing partial block is zero-padded to the next 8-byte boundary, so +// buffer_out must be at least ((buffer_in_sz + 7) / 8) * 8 bytes. On decrypt, buffer_in_sz +// must already be a multiple of 8 or the call returns nullptr. const char *eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char *buffer_out, bool enc); std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode); bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode); +// OpenSSL 3.0 moved DES behind the "legacy" provider; these load/unload it +// for the lifetime of the process. No-op when built against mbedtls. +bool eqcrypt_init(); +void eqcrypt_shutdown(); + struct EncryptionResult { std::string password; int mode = 0; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index faa22e955..9b9766223 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -26,6 +26,7 @@ #include "common/platform.h" #include "common/timer.h" #include "common/types.h" +#include "loginserver/encryption.h" #include "loginserver/login_server.h" #include "loginserver/loginserver_command_handler.h" #include "loginserver/loginserver_webserver.h" @@ -160,6 +161,11 @@ int main(int argc, char **argv) RegisterExecutablePlatform(ExePlatformLogin); set_exception_handler(); + if (!eqcrypt_init()) { + LogError("Failed to initialize crypto providers"); + return 1; + } + LogInfo("Logging System Init"); if (argc == 1) { @@ -280,5 +286,7 @@ int main(int argc, char **argv) LogInfo("Server Manager Shutdown"); delete server.server_manager; + eqcrypt_shutdown(); + return 0; } diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 406532687..d0f41d94e 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -17,11 +17,13 @@ */ #ifdef EMBPERL +#include "zone/embparser.h" + +#include "common/compiler_macros.h" #include "common/features.h" #include "common/misc_functions.h" #include "common/seperator.h" #include "common/strings.h" -#include "zone/embparser.h" #include "zone/masterentity.h" #include "zone/qglobals.h" #include "zone/questmgr.h" @@ -398,6 +400,8 @@ int PerlembParser::EventCommon( zone ); } + + return 0; } int PerlembParser::EventNPC( @@ -1211,31 +1215,33 @@ QuestType PerlembParser::GetQuestTypes( event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE ) { return is_global ? QuestType::SpellGlobal : QuestType::Spell; - } else { - if (npc_mob) { - if (!inst) { - if (npc_mob->IsBot()) { - return is_global ? QuestType::BotGlobal : QuestType::Bot; - } else if (npc_mob->IsMerc()) { - return is_global ? QuestType::MercGlobal : QuestType::Merc; - } else if (npc_mob->IsNPC()) { - return is_global ? QuestType::NPCGlobal : QuestType::NPC; - } - } else { - return is_global ? QuestType::ItemGlobal : QuestType::Item; - } - } else if (!npc_mob && mob) { - if (!inst) { - if (mob->IsClient()) { - return is_global ? QuestType::PlayerGlobal : QuestType::Player; - } - } else { - return is_global ? QuestType::ItemGlobal : QuestType::Item; - } - } else if (zone) { - return is_global ? QuestType::ZoneGlobal : QuestType::Zone; - } } + + if (npc_mob) { + if (!inst) { + if (npc_mob->IsBot()) { + return is_global ? QuestType::BotGlobal : QuestType::Bot; + } else if (npc_mob->IsMerc()) { + return is_global ? QuestType::MercGlobal : QuestType::Merc; + } else if (npc_mob->IsNPC()) { + return is_global ? QuestType::NPCGlobal : QuestType::NPC; + } + } else { + return is_global ? QuestType::ItemGlobal : QuestType::Item; + } + } else if (mob) { + if (!inst) { + if (mob->IsClient()) { + return is_global ? QuestType::PlayerGlobal : QuestType::Player; + } + } else { + return is_global ? QuestType::ItemGlobal : QuestType::Item; + } + } else if (zone) { + return is_global ? QuestType::ZoneGlobal : QuestType::Zone; + } + + UNREACHABLE(); } std::string PerlembParser::GetQuestPackageName( diff --git a/zone/lua_packet.cpp b/zone/lua_packet.cpp index 7dbc4bd32..0c89438a2 100644 --- a/zone/lua_packet.cpp +++ b/zone/lua_packet.cpp @@ -82,6 +82,16 @@ Lua_Packet::Lua_Packet(const Lua_Packet& o) { } } +Lua_Packet::~Lua_Packet() +{ + if (owned_) { + EQApplicationPacket* ptr = GetLuaPtrData(); + if (ptr) { + delete ptr; + } + } +} + int Lua_Packet::GetSize() { Lua_Safe_Call_Int(); return static_cast(self->size); diff --git a/zone/lua_packet.h b/zone/lua_packet.h index b5b375371..df94b3811 100644 --- a/zone/lua_packet.h +++ b/zone/lua_packet.h @@ -41,7 +41,7 @@ public: Lua_Packet(int opcode, int size, bool raw); Lua_Packet& operator=(const Lua_Packet& o); Lua_Packet(const Lua_Packet& o); - virtual ~Lua_Packet() { if(owned_) { EQApplicationPacket *ptr = GetLuaPtrData(); if(ptr) { delete ptr; } } } + virtual ~Lua_Packet(); int GetSize(); int GetOpcode(); diff --git a/zone/lua_ptr.h b/zone/lua_ptr.h index 7dbf9100c..9333dd9a8 100644 --- a/zone/lua_ptr.h +++ b/zone/lua_ptr.h @@ -48,7 +48,8 @@ public: Lua_Ptr(T *d) : d_(d) { } - ~Lua_Ptr() { + + virtual ~Lua_Ptr() { } T *GetLuaPtrData() {