diff --git a/.dockerignore b/.dockerignore index 169e1b6..4d7abb3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,10 @@ cmake-build-debug/ cmake-build-release/ +# IDE folders +.vscode/ +.idea/ + # Dockerfile (in order to allow changes without rebuilding) Dockerfile diff --git a/Dockerfile b/Dockerfile index d4ec8c1..4e2fe96 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ ENV VCPKG_FORCE_SYSTEM_BINARIES=1 # Install vcpkg and the required libraries RUN git clone https://github.com/Microsoft/vcpkg.git RUN bash ./vcpkg/bootstrap-vcpkg.sh -RUN ./vcpkg/vcpkg install boost-system cryptopp effolkronium-random libmysql libevent lzo fmt spdlog argon2 +RUN ./vcpkg/vcpkg install cryptopp effolkronium-random libmariadb libevent lzo fmt spdlog argon2 COPY . . diff --git a/README.md b/README.md index f07e890..0a85423 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,34 @@ For-profit usage of this material is certainly illegal without the proper licensing agreements and is hereby discouraged (not legal advice). Even so, the nature of this project is HIGHLY EXPERIMENTAL - bugs are to be expected for now. -## 1. Building and usage - -### A. Use Docker to instantly bring up a server (recommended) +## 1. Usage We aim to provide Docker images which _just work_ for your convenience. A Docker Compose project is maintained in the [Deployment project](https://git.old-metin2.com/metin2/deploy). Please head over there for further instructions. -### B. Build the binaries yourself (for advanced users) +## 2. Building +### A. Building Docker images +#### Building a Docker image from the repository +In order to build a local Docker image on your local architecture, just build the +provided Dockerfile in this project: + +```shell +docker build -t metin2/server:test --provenance=false . +``` + +#### Publishing a multiplatform Docker image manually +This command is reserved only for repository maintainers in order to publish +new Docker images for public use with the Deployment project. + +**WARNING:** Using WSL for building might lead to QEMU segmentation fault issues; +this can be worked around by using `binfmt` and `qemu-user-static` as described +[here](https://github.com/docker/buildx/issues/1170#issuecomment-1159350550). + +```shell +docker build --push -t git.old-metin2.com/metin2/server: --platform linux/amd64,linux/arm64 --provenance=false . +``` + +### B. Building the binaries yourself (for advanced users) _Sadly, we're unable to provide hand-holding services. You should have some C++ development experience going forward with this route._ @@ -23,6 +43,7 @@ variety. This project is also compatible with WSL, even though WSL can be buggy at times. FreeBSD/Windows compatibility is untested and unsupported for the time being - there are other projects out there if that's what you want. +#### Setting up the requirements On your Linux box, install the dependencies for `vcpkg` and the other libraries we're going to install. ```shell @@ -39,18 +60,21 @@ Install `vcpkg` according to the [latest instructions](https://vcpkg.io/en/getti Build and install the required libraries: ```shell -vcpkg install boost-system cryptopp effolkronium-random libmysql libevent lzo fmt spdlog argon2 +vcpkg install cryptopp effolkronium-random libmariadb libevent lzo fmt spdlog argon2 ``` -Then, it's time to build your binaries. Your commands should look along the lines of: +#### Building the binaries +Instead of building the binaries directly from the CLI, we recommend using an IDE, since +you're probably doing some kind of development anyway. See the "Development" section for more information on that. + +If you decide do build from the command line, make sure to find the right path for `vcpkg.cmake` and run the following: ```shell mkdir build/ cd build && cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake .. make -j $(nproc) ``` -If everything goes right, you should now have compiled binaries you should just be able to use -as a drop-in replacement for your BSD binaries in your favourite serverfiles. +If everything goes right, you should now have compiled binaries in the `build/` directory. ## 2. Development The preferred IDE in order to develop and debug the server is [CLion](https://www.jetbrains.com/clion/), @@ -103,7 +127,6 @@ This is a very serious security risk and one of the reasons this project is stil ## 5. Further plans - Migrate `db.conf` and `game.conf` to a modern dotenv-like format, which would enable pretty nice Docker images. -- Add a health check to the Docker image. - Use the [fmt](https://fmt.dev/latest/index.html) library for safe and modern string formatting. - Handle kernel signals (SIGTERM, SIGHUP etc.) for gracefully shutting down the game server. - Improve memory safety. diff --git a/src/db/CMakeLists.txt b/src/db/CMakeLists.txt index 36a78d3..88d9380 100644 --- a/src/db/CMakeLists.txt +++ b/src/db/CMakeLists.txt @@ -20,23 +20,19 @@ endif() # Treat char variables as signed, especially useful for ARM builds target_compile_options(${PROJECT_NAME} PUBLIC -fsigned-char) -# Find dependencies +# Find and link dependencies # # vcpkg dependencies # -# Boost -find_package(Boost COMPONENTS system REQUIRED) -target_link_libraries (${PROJECT_NAME} PRIVATE Boost::boost Boost::system) - # Libevent find_package(Libevent CONFIG REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE libevent::core libevent::extra libevent::pthreads) +target_link_libraries(${PROJECT_NAME} libevent::core libevent::extra libevent::pthreads) # effolkronium/random find_package(effolkronium_random CONFIG REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE effolkronium_random) +target_link_libraries(${PROJECT_NAME} effolkronium_random) # # System-provided dependencies @@ -45,9 +41,9 @@ target_link_libraries(${PROJECT_NAME} PRIVATE effolkronium_random) # Pthreads set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads) +target_link_libraries(${PROJECT_NAME} Threads::Threads) # LibBSD -target_link_libraries(${PROJECT_NAME} PRIVATE bsd) +target_link_libraries(${PROJECT_NAME} bsd) -target_link_libraries(${PROJECT_NAME} PRIVATE libpoly libsql libthecore) +target_link_libraries(${PROJECT_NAME} libpoly libsql libthecore) diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 12c85b8..776ec90 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -20,15 +20,15 @@ endif() # Treat char variables as signed, especially useful for ARM builds target_compile_options(${PROJECT_NAME} PUBLIC -fsigned-char) -# Find dependencies +# Find and link dependencies # # vcpkg dependencies # -# MySQL -find_package(unofficial-libmysql REQUIRED) -target_link_libraries(${PROJECT_NAME} unofficial::libmysql::libmysql) +# MariaDB +find_package(unofficial-libmariadb REQUIRED) +target_link_libraries(${PROJECT_NAME} unofficial::libmariadb) # Argon2 find_package(unofficial-argon2 CONFIG REQUIRED) @@ -36,11 +36,7 @@ target_link_libraries(${PROJECT_NAME} unofficial::argon2::libargon2) # Crypto++ find_package(cryptopp CONFIG REQUIRED) -target_link_libraries (${PROJECT_NAME} cryptopp::cryptopp) - -# Boost -find_package(Boost REQUIRED) -target_link_libraries (${PROJECT_NAME} Boost::boost) +target_link_libraries(${PROJECT_NAME} cryptopp::cryptopp) # Libevent find_package(Libevent CONFIG REQUIRED) diff --git a/src/game/src/DragonSoul.cpp b/src/game/src/DragonSoul.cpp index 6d3a249..21dfede 100644 --- a/src/game/src/DragonSoul.cpp +++ b/src/game/src/DragonSoul.cpp @@ -9,7 +9,6 @@ #include "dragon_soul_table.h" #include "log.h" #include "DragonSoul.h" -#include typedef std::vector TTokenVector; @@ -389,7 +388,7 @@ bool DSManager::ExtractDragonHeart(LPCHARACTER ch, LPITEM pItem, LPITEM pExtract pDH->SetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX, iCharge); ch->AutoGiveItem(pDH, true); - std::string s = boost::lexical_cast (iCharge); + std::string s = std::to_string(iCharge); s += "%s"; LogManager::instance().ItemLog(ch, pItem, "DS_HEART_EXTRACT_SUCCESS", s.c_str()); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Dragon Stone remaining duration has been extracted.")); diff --git a/src/game/src/IFileMonitor.h b/src/game/src/IFileMonitor.h index 808919e..4fa0218 100644 --- a/src/game/src/IFileMonitor.h +++ b/src/game/src/IFileMonitor.h @@ -1,7 +1,6 @@ #ifndef IFILEMONITOR_INCLUDED #define IFILEMONITOR_INCLUDED -//#include #include enum eFileUpdatedOptions diff --git a/src/game/src/affect.cpp b/src/game/src/affect.cpp index cde2ac2..7227e89 100644 --- a/src/game/src/affect.cpp +++ b/src/game/src/affect.cpp @@ -1,31 +1,13 @@ - #include "stdafx.h" - -#ifndef DEBUG_ALLOC -#include -#endif - #include "affect.h" -#ifndef DEBUG_ALLOC -boost::object_pool affect_pool; -#endif - CAffect* CAffect::Acquire() { -#ifndef DEBUG_ALLOC - return affect_pool.malloc(); -#else return M2_NEW CAffect; -#endif } void CAffect::Release(CAffect* p) { -#ifndef DEBUG_ALLOC - affect_pool.free(p); -#else M2_DELETE(p); -#endif } diff --git a/src/game/src/auction_manager.cpp b/src/game/src/auction_manager.cpp index 03cbff7..d9cdd88 100644 --- a/src/game/src/auction_manager.cpp +++ b/src/game/src/auction_manager.cpp @@ -10,7 +10,6 @@ #include "item_manager.h" #include "log.h" #include "db.h" -#include #include "item.h" #include "desc_client.h" #include diff --git a/src/game/src/char.cpp b/src/game/src/char.cpp index ae92060..b3e8910 100644 --- a/src/game/src/char.cpp +++ b/src/game/src/char.cpp @@ -4244,7 +4244,7 @@ bool CHARACTER::RequestToParty(LPCHARACTER leader) void CHARACTER::DenyToParty(LPCHARACTER member) { - SPDLOG_DEBUG("DenyToParty {} member {} {}", GetName(), member->GetName(), (void*) get_pointer(member->m_pkPartyRequestEvent)); + SPDLOG_DEBUG("DenyToParty {} member {} {}", GetName(), member->GetName(), (void*) member->m_pkPartyRequestEvent.get()); if (!member->m_pkPartyRequestEvent) return; @@ -4270,7 +4270,7 @@ void CHARACTER::DenyToParty(LPCHARACTER member) void CHARACTER::AcceptToParty(LPCHARACTER member) { - SPDLOG_DEBUG("AcceptToParty {} member {} {}", GetName(), member->GetName(), (void*) get_pointer(member->m_pkPartyRequestEvent)); + SPDLOG_DEBUG("AcceptToParty {} member {} {}", GetName(), member->GetName(), (void*) member->m_pkPartyRequestEvent.get()); if (!member->m_pkPartyRequestEvent) return; diff --git a/src/game/src/char_affect.cpp b/src/game/src/char_affect.cpp index cd5cb4c..d67ddcd 100644 --- a/src/game/src/char_affect.cpp +++ b/src/game/src/char_affect.cpp @@ -160,7 +160,7 @@ void CHARACTER::StartAffectEvent() char_event_info* info = AllocEventInfo(); info->ch = this; m_pkAffectEvent = event_create(affect_event, info, passes_per_sec); - SPDLOG_DEBUG("StartAffectEvent {} {} {}", GetName(), (void*) this, (void*) get_pointer(m_pkAffectEvent)); + SPDLOG_DEBUG("StartAffectEvent {} {} {}", GetName(), (void*) this, (void*) m_pkAffectEvent.get()); } void CHARACTER::ClearAffect(bool bSave) diff --git a/src/game/src/char_battle.cpp b/src/game/src/char_battle.cpp index a7979cb..7a09363 100644 --- a/src/game/src/char_battle.cpp +++ b/src/game/src/char_battle.cpp @@ -1420,7 +1420,7 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) { if (m_pkDeadEvent) { - SPDLOG_DEBUG("DEAD_EVENT_CANCEL: {} {} {}", GetName(), (void*) this, (void*) get_pointer(m_pkDeadEvent)); + SPDLOG_DEBUG("DEAD_EVENT_CANCEL: {} {} {}", GetName(), (void*) this, (void*) m_pkDeadEvent.get()); event_cancel(&m_pkDeadEvent); } @@ -1456,7 +1456,7 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) } } - SPDLOG_DEBUG("DEAD_EVENT_CREATE: {} {} {}", GetName(), (void*) this, (void*) get_pointer(m_pkDeadEvent)); + SPDLOG_DEBUG("DEAD_EVENT_CREATE: {} {} {}", GetName(), (void*) this, (void*) m_pkDeadEvent.get()); } if (m_pkExchange != NULL) diff --git a/src/game/src/char_manager.cpp b/src/game/src/char_manager.cpp index f475753..17e92d7 100644 --- a/src/game/src/char_manager.cpp +++ b/src/game/src/char_manager.cpp @@ -16,10 +16,6 @@ #include "questlua.h" #include "locale_service.h" -#ifndef __GNUC__ -#include -#endif - CHARACTER_MANAGER::CHARACTER_MANAGER() : m_iVIDCount(0), m_pkChrSelectedStone(NULL), @@ -646,9 +642,7 @@ struct FuncUpdateAndResetChatCounter void CHARACTER_MANAGER::Update(int iPulse) { using namespace std; -#ifdef __GNUC__ using namespace __gnu_cxx; -#endif BeginPendingDestroy(); @@ -659,11 +653,7 @@ void CHARACTER_MANAGER::Update(int iPulse) // 컨테이너 복사 CHARACTER_VECTOR v; v.reserve(m_map_pkPCChr.size()); -#ifdef __GNUC__ transform(m_map_pkPCChr.begin(), m_map_pkPCChr.end(), back_inserter(v), select2nd()); -#else - transform(m_map_pkPCChr.begin(), m_map_pkPCChr.end(), back_inserter(v), boost::bind(&NAME_MAP::value_type::second, _1)); -#endif if (0 == (iPulse % PASSES_PER_SEC(5))) { @@ -686,11 +676,8 @@ void CHARACTER_MANAGER::Update(int iPulse) { CHARACTER_VECTOR v; v.reserve(m_set_pkChrState.size()); -#ifdef __GNUC__ transform(m_set_pkChrState.begin(), m_set_pkChrState.end(), back_inserter(v), identity()); -#else - v.insert(v.end(), m_set_pkChrState.begin(), m_set_pkChrState.end()); -#endif + for_each(v.begin(), v.end(), bind2nd(mem_fun(&CHARACTER::UpdateStateMachine), iPulse)); } } @@ -1029,16 +1016,10 @@ void CHARACTER_MANAGER::FlushPendingDestroy() CharacterVectorInteractor::CharacterVectorInteractor(const CHARACTER_SET & r) { using namespace std; -#ifdef __GNUC__ using namespace __gnu_cxx; -#endif reserve(r.size()); -#ifdef __GNUC__ transform(r.begin(), r.end(), back_inserter(*this), identity()); -#else - insert(end(), r.begin(), r.end()); -#endif if (CHARACTER_MANAGER::instance().BeginPendingDestroy()) m_bMyBegin = true; diff --git a/src/game/src/dragon_soul_table.cpp b/src/game/src/dragon_soul_table.cpp index 2fd7510..40dc078 100644 --- a/src/game/src/dragon_soul_table.cpp +++ b/src/game/src/dragon_soul_table.cpp @@ -3,7 +3,7 @@ #include "group_text_parse_tree.h" #include "dragon_soul_table.h" #include "item_manager.h" -#include + const std::string g_astGradeName[] = { "grade_normal", @@ -789,7 +789,7 @@ bool DragonSoulTable::GetRefineStrengthValues(BYTE ds_type, BYTE material_type, stDragonSoulName.c_str(), g_astMaterialName[material_type].c_str()); return false; } - std::string stStrengthIdx = boost::lexical_cast ((int)strength_idx); + std::string stStrengthIdx = std::to_string((int)strength_idx); if (!m_pRefineStrengthTableNode->GetGroupValue(stDragonSoulName, g_astMaterialName[material_type], stStrengthIdx, prob)) { diff --git a/src/game/src/event.cpp b/src/game/src/event.cpp index 9b08dd2..942b4fb 100644 --- a/src/game/src/event.cpp +++ b/src/game/src/event.cpp @@ -30,7 +30,7 @@ LPEVENT event_create_ex(TEVENTFUNC func, event_info_data* info, int when) #ifdef M2_USE_POOL new_event = event_pool.Construct(); #else - new_event = M2_NEW event; + new_event = std::make_shared(); #endif assert(NULL != new_event); @@ -136,7 +136,7 @@ int event_process(int pulse) } else { - new_time = (the_event->func) (get_pointer(the_event), processing_time); + new_time = (the_event->func) (the_event, processing_time); if (new_time <= 0 || the_event->is_force_to_end) { @@ -201,17 +201,3 @@ int event_count() { return cxx_q.Size(); } - -void intrusive_ptr_add_ref(EVENT* p) { - ++(p->ref_count); -} - -void intrusive_ptr_release(EVENT* p) { - if ( --(p->ref_count) == 0 ) { -#ifdef M2_USE_POOL - event_pool.Destroy(p); -#else - M2_DELETE(p); -#endif - } -} diff --git a/src/game/src/event.h b/src/game/src/event.h index 32b8025..0db8048 100644 --- a/src/game/src/event.h +++ b/src/game/src/event.h @@ -4,10 +4,9 @@ * * Author: 김한주 (aka. 비엽, Cronan), 송영진 (aka. myevan, 빗자루) */ -#ifndef __INC_LIBTHECORE_EVENT_H__ -#define __INC_LIBTHECORE_EVENT_H__ +#pragma once -#include +#include #ifdef M2_USE_POOL #include "pool.h" @@ -34,7 +33,7 @@ private: }; typedef struct event EVENT; -typedef boost::intrusive_ptr LPEVENT; +typedef std::shared_ptr LPEVENT; typedef int (*TEVENTFUNC) (LPEVENT event, int processing_time); #define EVENTFUNC(name) int (name) (LPEVENT event, int processing_time) @@ -63,9 +62,6 @@ struct event size_t ref_count; }; -extern void intrusive_ptr_add_ref(EVENT* p); -extern void intrusive_ptr_release(EVENT* p); - template // T should be a subclass of event_info_data T* AllocEventInfo() { #ifdef M2_USE_POOL @@ -89,5 +85,3 @@ extern void event_set_verbose(int level); extern event_info_data* FindEventInfo(DWORD dwID); extern event_info_data* event_info(LPEVENT event); - -#endif diff --git a/src/game/src/fifo_allocator.h b/src/game/src/fifo_allocator.h deleted file mode 100644 index 1a6e806..0000000 --- a/src/game/src/fifo_allocator.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _FIFO_ALLOCATOR_H_ -#define _FIFO_ALLOCATOR_H_ - -#include - -#ifdef __GNUC__ -#include -#define std std::tr1 -#else -#include -#define std boost -#endif - -// Allocator implementation detail with simple FIFO grow-only pool. -// It relies on default CRT malloc/free. -class FifoAllocator { -public: - FifoAllocator() {} - ~FifoAllocator() {} - - void SetUp() {} - void TearDown() { - CleanUp(); // deallocate pooled blocks - } - - void* Alloc(size_t size) { - void* p = NULL; - PoolType& pool = pool_map_[size]; - if (pool.size() < kWatermark) { - p = ::malloc(size); - } else { - p = pool.front(); - pool.pop_front(); - } - if (p != NULL) { - alloc_map_[p] = size; - } - return p; - } - void Free(void* p) { - if (p == NULL) { - return; - } - AllocMapType::iterator it = alloc_map_.find(p); - if (it == alloc_map_.end()) { - return; - } - size_t size = it->second; - alloc_map_.erase(it); - PoolMapType::iterator it2 = pool_map_.find(size); - if (it2 == pool_map_.end()) { - return; - } - PoolType& pool = it2->second; - pool.push_back(p); - } - -private: - void CleanUp() { - PoolMapType::iterator it = pool_map_.begin(), end = pool_map_.end(); - for ( ; it != end; ++it) { - PoolType& pool = it->second; - PoolType::iterator it2 = pool.begin(), end2 = pool.end(); - for ( ; it2 != end2; ++it2) { - ::free(*it2); - } - pool.clear(); - } - pool_map_.clear(); - } - - typedef std::deque PoolType; - typedef std::unordered_map PoolMapType; - typedef std::unordered_map AllocMapType; - - static const size_t kWatermark = 4; // FIFO enforcement level - - PoolMapType pool_map_; - AllocMapType alloc_map_; -}; - -#endif // _FIFO_ALLOCATOR_H_ diff --git a/src/game/src/horse_rider.cpp b/src/game/src/horse_rider.cpp index 3eabab6..9d24bfb 100644 --- a/src/game/src/horse_rider.cpp +++ b/src/game/src/horse_rider.cpp @@ -247,7 +247,7 @@ EVENTFUNC(horse_stamina_consume_event) } hr->CheckHorseHealthDropTime(); - SPDLOG_DEBUG("HORSE STAMINA - {}", (void*) get_pointer(event)); + SPDLOG_DEBUG("HORSE STAMINA - {}", (void*) event.get()); return delta; } @@ -278,7 +278,7 @@ EVENTFUNC(horse_stamina_regen_event) } hr->CheckHorseHealthDropTime(); - SPDLOG_DEBUG("HORSE STAMINA + {}", (void*) get_pointer(event)); + SPDLOG_DEBUG("HORSE STAMINA + {}", (void*) event.get()); return delta; @@ -292,7 +292,7 @@ void CHorseRider::StartStaminaConsumeEvent() if (GetHorseHealth() <= 0) return; - SPDLOG_DEBUG("HORSE STAMINA REGEN EVENT CANCEL {}", (void*) get_pointer(m_eventStaminaRegen)); + SPDLOG_DEBUG("HORSE STAMINA REGEN EVENT CANCEL {}", (void*) m_eventStaminaRegen.get()); event_cancel(&m_eventStaminaRegen); if (m_eventStaminaConsume) @@ -302,7 +302,7 @@ void CHorseRider::StartStaminaConsumeEvent() info->hr = this; m_eventStaminaConsume = event_create(horse_stamina_consume_event, info, PASSES_PER_SEC(HORSE_STAMINA_CONSUME_INTERVAL)); - SPDLOG_DEBUG("HORSE STAMINA CONSUME EVENT CREATE {}", (void*) get_pointer(m_eventStaminaConsume)); + SPDLOG_DEBUG("HORSE STAMINA CONSUME EVENT CREATE {}", (void*) m_eventStaminaConsume.get()); } void CHorseRider::StartStaminaRegenEvent() @@ -313,7 +313,7 @@ void CHorseRider::StartStaminaRegenEvent() if (GetHorseHealth() <= 0) return; - SPDLOG_DEBUG("HORSE STAMINA CONSUME EVENT CANCEL {}", (void*) get_pointer(m_eventStaminaConsume)); + SPDLOG_DEBUG("HORSE STAMINA CONSUME EVENT CANCEL {}", (void*) m_eventStaminaConsume.get()); event_cancel(&m_eventStaminaConsume); if (m_eventStaminaRegen) @@ -323,7 +323,7 @@ void CHorseRider::StartStaminaRegenEvent() info->hr = this; m_eventStaminaRegen = event_create(horse_stamina_regen_event, info, PASSES_PER_SEC(HORSE_STAMINA_REGEN_INTERVAL)); - SPDLOG_DEBUG("HORSE STAMINA REGEN EVENT CREATE {}", (void*) get_pointer(m_eventStaminaRegen)); + SPDLOG_DEBUG("HORSE STAMINA REGEN EVENT CREATE {}", (void*) m_eventStaminaRegen.get()); } // Health @@ -358,7 +358,7 @@ void CHorseRider::UpdateHorseHealth(int iHealth, bool bSend) void CHorseRider::HorseDie() { - SPDLOG_DEBUG("HORSE DIE {} {}", (void*) get_pointer(m_eventStaminaRegen), (void*) get_pointer(m_eventStaminaConsume)); + SPDLOG_DEBUG("HORSE DIE {} {}", (void*) m_eventStaminaRegen.get(), (void*) m_eventStaminaConsume.get()); UpdateHorseStamina(-m_Horse.sStamina); event_cancel(&m_eventStaminaRegen); event_cancel(&m_eventStaminaConsume); diff --git a/src/game/src/questmanager.cpp b/src/game/src/questmanager.cpp index d1065f0..85323ce 100644 --- a/src/game/src/questmanager.cpp +++ b/src/game/src/questmanager.cpp @@ -1676,7 +1676,7 @@ namespace quest void CQuestManager::AddServerTimer(const std::string& name, DWORD arg, LPEVENT event) { - SPDLOG_DEBUG("XXX AddServerTimer {} {} {}", name, arg, (void*) get_pointer(event)); + SPDLOG_DEBUG("XXX AddServerTimer {} {} {}", name, arg, (void*) event.get()); if (m_mapServerTimer.find(make_pair(name, arg)) != m_mapServerTimer.end()) { SPDLOG_ERROR("already registered server timer name:{} arg:{}", name, arg); diff --git a/src/game/src/questpc.cpp b/src/game/src/questpc.cpp index 766087c..f229ac4 100644 --- a/src/game/src/questpc.cpp +++ b/src/game/src/questpc.cpp @@ -165,7 +165,7 @@ namespace quest { RemoveTimer(name); m_TimerMap.insert(make_pair(name, pEvent)); - SPDLOG_DEBUG("QUEST add timer {} {}", (void*) get_pointer(pEvent), m_TimerMap.size()); + SPDLOG_DEBUG("QUEST add timer {} {}", (void*) pEvent.get(), m_TimerMap.size()); } void PC::RemoveTimerNotCancel(const string & name) @@ -174,7 +174,7 @@ namespace quest if (it != m_TimerMap.end()) { - SPDLOG_DEBUG("QUEST remove with no cancel {}", (void*) get_pointer(it->second)); + SPDLOG_DEBUG("QUEST remove with no cancel {}", (void*) it->second.get()); m_TimerMap.erase(it); } @@ -187,7 +187,7 @@ namespace quest if (it != m_TimerMap.end()) { - SPDLOG_DEBUG("QUEST remove timer {}", (void*) get_pointer(it->second)); + SPDLOG_DEBUG("QUEST remove timer {}", (void*) it->second.get()); CancelTimerEvent(&it->second); m_TimerMap.erase(it); } diff --git a/src/game/src/shop_manager.cpp b/src/game/src/shop_manager.cpp index 3ffca46..f8330bc 100644 --- a/src/game/src/shop_manager.cpp +++ b/src/game/src/shop_manager.cpp @@ -2,29 +2,23 @@ #include "../../libgame/include/grid.h" #include "constants.h" #include "utils.h" -#include "config.h" #include "shop.h" #include "desc.h" -#include "desc_manager.h" #include "char.h" #include "char_manager.h" #include "item.h" #include "item_manager.h" -#include "buffer_manager.h" #include "packet.h" -#include "log.h" #include "db.h" #include "questmanager.h" #include "monarch.h" #include "mob_manager.h" #include "locale_service.h" -#include "desc_client.h" #include "shop_manager.h" #include "group_text_parse_tree.h" #include "shopEx.h" -#include -#include "shop_manager.h" #include +#include CShopManager::CShopManager() { @@ -388,11 +382,11 @@ bool ConvertToShopItemTable(IN CGroupNode* pNode, OUT TShopTableEx& shopTable) stCoinType = "Gold"; } - if (boost::iequals(stCoinType, "Gold")) + if (iequals(stCoinType, "Gold")) { shopTable.coinType = SHOP_COIN_TYPE_GOLD; } - else if (boost::iequals(stCoinType, "SecondaryCoin")) + else if (iequals(stCoinType, "SecondaryCoin")) { shopTable.coinType = SHOP_COIN_TYPE_SECONDARY_COIN; } @@ -442,11 +436,11 @@ bool ConvertToShopItemTable(IN CGroupNode* pNode, OUT TShopTableEx& shopTable) stSort = "None"; } - if (boost::iequals(stSort, "Asc")) + if (iequals(stSort, "Asc")) { std::sort(shopItems.begin(), shopItems.end(), CompareShopItemName); } - else if(boost::iequals(stSort, "Desc")) + else if (iequals(stSort, "Desc")) { std::sort(shopItems.rbegin(), shopItems.rend(), CompareShopItemName); } diff --git a/src/game/src/utils.cpp b/src/game/src/utils.cpp index f12ab0d..362a137 100644 --- a/src/game/src/utils.cpp +++ b/src/game/src/utils.cpp @@ -230,3 +230,12 @@ bool WildCaseCmp(const char *w, const char *s) return false; } +bool ichar_equals(char a, char b) +{ + return std::tolower(static_cast(a)) == std::tolower(static_cast(b)); +} + +bool iequals(const std::string& a, const std::string& b) +{ + return std::equal(a.begin(), a.end(), b.begin(), b.end(), ichar_equals); +} diff --git a/src/game/src/utils.h b/src/game/src/utils.h index f3baec5..938392a 100644 --- a/src/game/src/utils.h +++ b/src/game/src/utils.h @@ -1,8 +1,6 @@ +#pragma once -#ifndef __INC_METIN_II_UTILS_H__ -#define __INC_METIN_II_UTILS_H__ - -#include +#include #define IS_SET(flag, bit) ((flag) & (bit)) #define SET_BIT(var, bit) ((var) |= (bit)) @@ -64,5 +62,5 @@ extern int parse_time_str(const char* str); extern bool WildCaseCmp(const char *w, const char *s); -#endif /* __INC_METIN_II_UTILS_H__ */ - +extern bool ichar_equals(char a, char b); +extern bool iequals(const std::string& a, const std::string& b); diff --git a/src/game/src/wedding.cpp b/src/game/src/wedding.cpp index 9028707..ffb9a4e 100644 --- a/src/game/src/wedding.cpp +++ b/src/game/src/wedding.cpp @@ -68,7 +68,7 @@ namespace marriage { if (m_pEndEvent) { - SPDLOG_ERROR("WeddingMap::SetEnded - ALREADY EndEvent(m_pEndEvent={})", (void*) get_pointer(m_pEndEvent)); + SPDLOG_ERROR("WeddingMap::SetEnded - ALREADY EndEvent(m_pEndEvent={})", (void*) m_pEndEvent.get()); return; } diff --git a/src/libgame/CMakeLists.txt b/src/libgame/CMakeLists.txt index 3d774fa..3ce45ef 100644 --- a/src/libgame/CMakeLists.txt +++ b/src/libgame/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.8) project(libgame CXX) @@ -11,12 +11,11 @@ file(GLOB SOURCES # Include header files include_directories("include") -find_package(Boost REQUIRED) - # Create shared library add_library(${PROJECT_NAME} STATIC ${SOURCES}) -if (Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES}) -endif (Boost_FOUND) \ No newline at end of file +# Find and link dependencies + +# spdlog +find_package(spdlog CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog) diff --git a/src/liblua/CMakeLists.txt b/src/liblua/CMakeLists.txt index c6724c7..5cff03d 100644 --- a/src/liblua/CMakeLists.txt +++ b/src/liblua/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.8) project(liblua CXX) diff --git a/src/libpoly/CMakeLists.txt b/src/libpoly/CMakeLists.txt index 10c1f8c..94fc291 100644 --- a/src/libpoly/CMakeLists.txt +++ b/src/libpoly/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.8) project(libpoly CXX) diff --git a/src/libsql/CMakeLists.txt b/src/libsql/CMakeLists.txt index 504c474..7da83f5 100644 --- a/src/libsql/CMakeLists.txt +++ b/src/libsql/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.8) project(libsql CXX) @@ -14,10 +14,12 @@ include_directories("include") # Create shared library add_library(${PROJECT_NAME} STATIC ${SOURCES}) -# Find dependencies -find_package(unofficial-libmysql REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE unofficial::libmysql::libmysql) +# Find and link dependencies -find_package(Boost REQUIRED) -include_directories(${Boost_INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES}) +# MariaDB +find_package(unofficial-libmariadb REQUIRED) +target_link_libraries(${PROJECT_NAME} PUBLIC unofficial::libmariadb) + +# spdlog +find_package(spdlog CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog) diff --git a/src/libsql/src/CAsyncSQL.cpp b/src/libsql/src/CAsyncSQL.cpp index 796dbee..6a1ac11 100644 --- a/src/libsql/src/CAsyncSQL.cpp +++ b/src/libsql/src/CAsyncSQL.cpp @@ -143,7 +143,7 @@ bool CAsyncSQL::Connect() if (0 != mysql_options(&m_hDB, MYSQL_OPT_RECONNECT, &reconnect)) SPDLOG_ERROR("Setting MYSQL_OPT_RECONNECT via mysql_options failed: {}", mysql_error(&m_hDB)); - SPDLOG_INFO("AsyncSQL: connected to {} (reconnect {})", m_stHost, m_hDB.reconnect); + SPDLOG_INFO("AsyncSQL: connected to {}", m_stHost); // db cache는 common db의 LOCALE 테이블에서 locale을 알아오고, 이후 character set을 수정한다. // 따라서 최초 Connection을 맺을 때에는 locale을 모르기 때문에 character set을 정할 수가 없음에도 불구하고, diff --git a/src/libthecore/CMakeLists.txt b/src/libthecore/CMakeLists.txt index 490d549..45a03b6 100644 --- a/src/libthecore/CMakeLists.txt +++ b/src/libthecore/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.8) project(libthecore CXX) @@ -14,14 +14,7 @@ include_directories("include") # Create shared library add_library(${PROJECT_NAME} STATIC ${SOURCES}) -# -# vcpkg dependencies -# - -# Boost -find_package(Boost REQUIRED) -include_directories(${Boost_INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES}) +# Find and link dependencies # fmt find_package(fmt CONFIG REQUIRED) diff --git a/src/quest/CMakeLists.txt b/src/quest/CMakeLists.txt index c41364b..3a5220a 100644 --- a/src/quest/CMakeLists.txt +++ b/src/quest/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.8) project(quest CXX) @@ -7,19 +7,13 @@ file(GLOB_RECURSE sources src/*.c ) +# Add the src directory to the include path include_directories(src) -# Find dependencies -find_package(Boost REQUIRED) - add_executable(${PROJECT_NAME} ${sources}) set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "qc") -# Link dependencies if found -if (Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES}) -endif (Boost_FOUND) +# Find and link dependencies +# liblua target_link_libraries(${PROJECT_NAME} liblua) -target_include_directories(${PROJECT_NAME} PUBLIC . ../liblua) \ No newline at end of file diff --git a/src/quest/src/qc.cc b/src/quest/src/qc.cc index ea24d26..d81962c 100644 --- a/src/quest/src/qc.cc +++ b/src/quest/src/qc.cc @@ -20,18 +20,9 @@ extern "C" { #include #include #include - -#ifndef __WIN32__ #include -#else -#include -#define typeof(t) BOOST_TYPEOF(t) -#include -#define mkdir(path, mode) _mkdir(path) -#endif -#include #include -#include +#include #include "crc32.h"