mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-24 06:27:24 +00:00
feat: Improve console output to show packet enum names (magic_enum) (#1344)
* add enum stringification functionality from third party source
* squashed commit
* Macros: Add test and improve speed
Space macros out
utilize cache locality
ensure no lost functionality
* moved stringify code to dCommon
* Rename #defines in stringify enum tests
* Revert "moved stringify code to dCommon"
This reverts commit 33fa5f8d2f
.
* improve macro functionality
change function handle
formatting and function definition tweaks
* typo fixes
* moved code to dCommon/dEnums and tests to dCommonTests/dEnumsTests
* initial magic_enums alternate implementation of enum stringification
* deleted unused tests
* reverted compile flag oopsy and fixed output types
* fixed testing suite
* test formatting improvement
* formatting again :(
* added gm string to "aborting gm!" message
* Push my suggestion for CI tests.
* updated magic enum test
* fix test variable type
* added gm test
* making sure magic_enum is on a release branch
* tidying up console outputs
* re-implemented enum array access for performance
* now it is bugged :(
* nvm, working
* helping out the snowflake compilers
* changed return type too
* optimization too
* formatting too I guess because why not
* being even more painfully specific
* Update WorldServer.cpp to match emo's feedback
* Update MagicEnumTests.cpp to use srand(time(NULL))
* Update eGameMessageType.h - formatting
* Trying to fix the crash but can't actually compile the code to check on my own rn
* Update WorldServer.cpp - third try at this
* Update MagicEnumTests.cpp - use better macro definitions
* Update MagicEnumTests.cpp - c string comparison fix
* addressing all but the cmake feedback
* fixed cmake to the best of my very limited ability
* added tests to verify magic enum arrays are pre-sorted
* updated
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
Co-authored-by: Jettford <mrjettbradford@gmail.com>
This commit is contained in:
parent
c1e8546d48
commit
fcf4d6c6fa
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -17,3 +17,6 @@
|
|||||||
[submodule "thirdparty/AccountManager"]
|
[submodule "thirdparty/AccountManager"]
|
||||||
path = thirdparty/AccountManager
|
path = thirdparty/AccountManager
|
||||||
url = https://github.com/DarkflameUniverse/AccountManager
|
url = https://github.com/DarkflameUniverse/AccountManager
|
||||||
|
[submodule "thirdparty/magic_enum"]
|
||||||
|
path = thirdparty/magic_enum
|
||||||
|
url = https://github.com/Neargye/magic_enum.git
|
||||||
|
@ -293,6 +293,7 @@ set(INCLUDED_DIRECTORIES
|
|||||||
"dScripts/zone/PROPERTY/GF"
|
"dScripts/zone/PROPERTY/GF"
|
||||||
"dScripts/zone/PROPERTY/NS"
|
"dScripts/zone/PROPERTY/NS"
|
||||||
|
|
||||||
|
"thirdparty/magic_enum/include/magic_enum"
|
||||||
"thirdparty/raknet/Source"
|
"thirdparty/raknet/Source"
|
||||||
"thirdparty/tinyxml2"
|
"thirdparty/tinyxml2"
|
||||||
"thirdparty/recastnavigation"
|
"thirdparty/recastnavigation"
|
||||||
@ -374,7 +375,7 @@ add_subdirectory(dNavigation)
|
|||||||
add_subdirectory(dPhysics)
|
add_subdirectory(dPhysics)
|
||||||
|
|
||||||
# Create a list of common libraries shared between all binaries
|
# Create a list of common libraries shared between all binaries
|
||||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp")
|
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
|
||||||
|
|
||||||
# Add platform specific common libraries
|
# Add platform specific common libraries
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
|
29
dCommon/dEnums/StringifiedEnum.h
Normal file
29
dCommon/dEnums/StringifiedEnum.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __STRINGIFIEDENUM_H__
|
||||||
|
#define __STRINGIFIEDENUM_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
|
namespace StringifiedEnum {
|
||||||
|
template<typename T>
|
||||||
|
const std::string_view ToString(const T e) {
|
||||||
|
constexpr auto sv = &magic_enum::enum_entries<T>();
|
||||||
|
std::string_view output;
|
||||||
|
|
||||||
|
const auto it = std::lower_bound(
|
||||||
|
sv->begin(), sv->end(), e,
|
||||||
|
[&](const std::pair<T, std::string_view>& lhs, const T rhs)
|
||||||
|
{ return lhs.first < rhs; }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (it != sv->end() && it->first == e) {
|
||||||
|
output = it->second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output = "UNKNOWN";
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !__STRINGIFIEDENUM_H__
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
enum class eGameMessageType : uint16_t {
|
enum class eGameMessageType : uint16_t {
|
||||||
GET_POSITION = 0,
|
GET_POSITION = 0,
|
||||||
GET_ROTATION = 1,
|
GET_ROTATION = 1,
|
||||||
@ -1602,4 +1604,10 @@ enum class eGameMessageType : uint16_t {
|
|||||||
GET_IS_ON_RAIL = 1772
|
GET_IS_ON_RAIL = 1772
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<eGameMessageType> {
|
||||||
|
static constexpr int min = 0;
|
||||||
|
static constexpr int max = 1772;
|
||||||
|
};
|
||||||
|
|
||||||
#endif //!__EGAMEMESSAGETYPE__H__
|
#endif //!__EGAMEMESSAGETYPE__H__
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
enum class eWorldMessageType : uint32_t {
|
enum class eWorldMessageType : uint32_t {
|
||||||
VALIDATION = 1, // Session info
|
VALIDATION = 1, // Session info
|
||||||
CHARACTER_LIST_REQUEST,
|
CHARACTER_LIST_REQUEST,
|
||||||
@ -40,4 +42,10 @@ enum class eWorldMessageType : uint32_t {
|
|||||||
UI_HELP_TOP_5 = 91
|
UI_HELP_TOP_5 = 91
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<eWorldMessageType> {
|
||||||
|
static constexpr int min = 0;
|
||||||
|
static constexpr int max = 91;
|
||||||
|
};
|
||||||
|
|
||||||
#endif //!__EWORLDMESSAGETYPE__H__
|
#endif //!__EWORLDMESSAGETYPE__H__
|
||||||
|
@ -34,10 +34,10 @@
|
|||||||
#include "eMissionTaskType.h"
|
#include "eMissionTaskType.h"
|
||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
#include "eConnectionType.h"
|
#include "eConnectionType.h"
|
||||||
|
#include "eGameMessageType.h"
|
||||||
#include "ePlayerFlag.h"
|
#include "ePlayerFlag.h"
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
|
#include "StringifiedEnum.h"
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
||||||
|
|
||||||
@ -49,11 +49,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
|||||||
User* usr = UserManager::Instance()->GetUser(sysAddr);
|
User* usr = UserManager::Instance()->GetUser(sysAddr);
|
||||||
|
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
LOG("Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID);
|
LOG("Failed to find associated entity (%llu), aborting GM: %4i, %s!", objectID, messageID, StringifiedEnum::ToString(messageID).data());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageID != eGameMessageType::READY_FOR_UPDATES) LOG_DEBUG("received game message ID: %i", messageID);
|
if (messageID != eGameMessageType::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||||
|
|
||||||
switch (messageID) {
|
switch (messageID) {
|
||||||
|
|
||||||
@ -344,12 +344,12 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
|||||||
|
|
||||||
SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream
|
SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream
|
||||||
|
|
||||||
ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < sync.sBitStream.size(); k++) {
|
for (unsigned int k = 0; k < sync.sBitStream.size(); k++) {
|
||||||
char s;
|
char s;
|
||||||
s = sync.sBitStream.at(k);
|
s = sync.sBitStream.at(k);
|
||||||
buffer << setw(2) << hex << setfill('0') << (int)s << " ";
|
buffer << std::setw(2) << std::hex << std::setfill('0') << static_cast<int>(s) << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usr != nullptr) {
|
if (usr != nullptr) {
|
||||||
@ -694,7 +694,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
|||||||
GameMessages::SendVendorStatusUpdate(entity, sysAddr, true);
|
GameMessages::SendVendorStatusUpdate(entity, sysAddr, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_DEBUG("Unknown game message ID: %i", messageID);
|
LOG_DEBUG("Received Unknown GM with ID: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "GameMessages.h"
|
#include "GameMessages.h"
|
||||||
#include "CDClientDatabase.h"
|
#include "CDClientDatabase.h"
|
||||||
|
#include "eGameMessageType.h"
|
||||||
enum class eGameMessageType : uint16_t;
|
|
||||||
|
|
||||||
namespace GameMessageHandler {
|
namespace GameMessageHandler {
|
||||||
void HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID);
|
void HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID);
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "CheatDetection.h"
|
#include "CheatDetection.h"
|
||||||
#include "eGameMasterLevel.h"
|
#include "eGameMasterLevel.h"
|
||||||
|
#include "StringifiedEnum.h"
|
||||||
|
|
||||||
namespace Game {
|
namespace Game {
|
||||||
Logger* logger = nullptr;
|
Logger* logger = nullptr;
|
||||||
@ -1244,7 +1245,9 @@ void HandlePacket(Packet* packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG("Unknown world packet received: %i", int(packet->data[3]));
|
const auto messageId = *reinterpret_cast<eWorldMessageType*>(&packet->data[3]);
|
||||||
|
const std::string_view messageIdString = StringifiedEnum::ToString(messageId);
|
||||||
|
LOG("Unknown world packet received: %4i, %s", messageId, messageIdString.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ set(DCOMMONTEST_SOURCES
|
|||||||
"dCommonDependencies.cpp"
|
"dCommonDependencies.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(dEnumsTests)
|
||||||
|
list(APPEND DCOMMONTEST_SOURCES ${DENUMS_TESTS})
|
||||||
|
|
||||||
# Set our executable
|
# Set our executable
|
||||||
add_executable(dCommonTests ${DCOMMONTEST_SOURCES})
|
add_executable(dCommonTests ${DCOMMONTEST_SOURCES})
|
||||||
|
|
||||||
|
10
tests/dCommonTests/dEnumsTests/CMakeLists.txt
Normal file
10
tests/dCommonTests/dEnumsTests/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
set(DENUMS_TESTS
|
||||||
|
"MagicEnumTests.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get the folder name and prepend it to the files above
|
||||||
|
get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||||
|
list(TRANSFORM DENUMS_TESTS PREPEND "${thisFolderName}/")
|
||||||
|
|
||||||
|
# Export to parent scope
|
||||||
|
set(DENUMS_TESTS ${DENUMS_TESTS} PARENT_SCOPE)
|
142
tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp
Normal file
142
tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "StringifiedEnum.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "eGameMessageType.h"
|
||||||
|
#include "eWorldMessageType.h"
|
||||||
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
|
#define ENUM_EQ(e, y, z)\
|
||||||
|
LOG("%s %s", StringifiedEnum::ToString(static_cast<e>(y)).data(), #z);\
|
||||||
|
ASSERT_STREQ(StringifiedEnum::ToString(static_cast<e>(y)).data(), #z);
|
||||||
|
|
||||||
|
#define ENUM_NE(e, y)\
|
||||||
|
ENUM_EQ(e, y, UNKNOWN);
|
||||||
|
|
||||||
|
// Test World Message Enum Reflection
|
||||||
|
TEST(MagicEnumTest, eWorldMessageTypeTest) {
|
||||||
|
Game::logger = new Logger("./MagicEnumTest_eWorldMessageTypeTest.log", true, true);
|
||||||
|
|
||||||
|
ENUM_EQ(eWorldMessageType, 1, VALIDATION);
|
||||||
|
ENUM_EQ(eWorldMessageType, 2, CHARACTER_LIST_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 3, CHARACTER_CREATE_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 4, LOGIN_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 5, GAME_MSG);
|
||||||
|
ENUM_EQ(eWorldMessageType, 6, CHARACTER_DELETE_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 7, CHARACTER_RENAME_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 8, HAPPY_FLOWER_MODE_NOTIFY);
|
||||||
|
ENUM_EQ(eWorldMessageType, 9, SLASH_RELOAD_MAP);
|
||||||
|
ENUM_EQ(eWorldMessageType, 10, SLASH_PUSH_MAP_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 11, SLASH_PUSH_MAP);
|
||||||
|
ENUM_EQ(eWorldMessageType, 12, SLASH_PULL_MAP);
|
||||||
|
ENUM_EQ(eWorldMessageType, 13, LOCK_MAP_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 14, GENERAL_CHAT_MESSAGE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 15, HTTP_MONITOR_INFO_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 16, SLASH_DEBUG_SCRIPTS);
|
||||||
|
ENUM_EQ(eWorldMessageType, 17, MODELS_CLEAR);
|
||||||
|
ENUM_EQ(eWorldMessageType, 18, EXHIBIT_INSERT_MODEL);
|
||||||
|
ENUM_EQ(eWorldMessageType, 19, LEVEL_LOAD_COMPLETE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 20, TMP_GUILD_CREATE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 21, ROUTE_PACKET);
|
||||||
|
ENUM_EQ(eWorldMessageType, 22, POSITION_UPDATE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 23, MAIL);
|
||||||
|
ENUM_EQ(eWorldMessageType, 24, WORD_CHECK);
|
||||||
|
ENUM_EQ(eWorldMessageType, 25, STRING_CHECK);
|
||||||
|
ENUM_EQ(eWorldMessageType, 26, GET_PLAYERS_IN_ZONE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 27, REQUEST_UGC_MANIFEST_INFO);
|
||||||
|
ENUM_EQ(eWorldMessageType, 28, BLUEPRINT_GET_ALL_DATA_REQUEST);
|
||||||
|
ENUM_EQ(eWorldMessageType, 29, CANCEL_MAP_QUEUE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 30, HANDLE_FUNNESS);
|
||||||
|
ENUM_EQ(eWorldMessageType, 31, FAKE_PRG_CSR_MESSAGE);
|
||||||
|
ENUM_EQ(eWorldMessageType, 32, REQUEST_FREE_TRIAL_REFRESH);
|
||||||
|
ENUM_EQ(eWorldMessageType, 33, GM_SET_FREE_TRIAL_STATUS);
|
||||||
|
ENUM_EQ(eWorldMessageType, 91, UI_HELP_TOP_5);
|
||||||
|
ENUM_NE(eWorldMessageType, 37);
|
||||||
|
ENUM_NE(eWorldMessageType, 123);
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
auto begin = std::chrono::high_resolution_clock::now();
|
||||||
|
for (int i = 0; i < 10000000; ++i) {
|
||||||
|
volatile auto f = StringifiedEnum::ToString(static_cast<eWorldMessageType>(i)).data();
|
||||||
|
|
||||||
|
// To ensure the compiler doesn't optimize out the call, I print it at random intervals
|
||||||
|
if (rand() % 100000 == 0) LOG("%i, %s", i, f);
|
||||||
|
}
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
LOG("Time: %lld", std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count());
|
||||||
|
|
||||||
|
delete Game::logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Game Message Enum Reflection
|
||||||
|
TEST(MagicEnumTest, eGameMessageTypeTest) {
|
||||||
|
|
||||||
|
Game::logger = new Logger("./MagicEnumTest_eGameMessageTypeTest.log", true, true);
|
||||||
|
|
||||||
|
// Only doing the first and last 10 for the sake of my sanity
|
||||||
|
ENUM_EQ(eGameMessageType, 0, GET_POSITION);
|
||||||
|
ENUM_EQ(eGameMessageType, 1, GET_ROTATION);
|
||||||
|
ENUM_EQ(eGameMessageType, 2, GET_LINEAR_VELOCITY);
|
||||||
|
ENUM_EQ(eGameMessageType, 3, GET_ANGULAR_VELOCITY);
|
||||||
|
ENUM_EQ(eGameMessageType, 4, GET_FORWARD_VELOCITY);
|
||||||
|
ENUM_EQ(eGameMessageType, 5, GET_PLAYER_FORWARD);
|
||||||
|
ENUM_EQ(eGameMessageType, 6, GET_FORWARD_VECTOR);
|
||||||
|
ENUM_EQ(eGameMessageType, 7, SET_POSITION);
|
||||||
|
ENUM_EQ(eGameMessageType, 8, SET_LOCAL_POSITION);
|
||||||
|
ENUM_EQ(eGameMessageType, 9, SET_ROTATION);
|
||||||
|
ENUM_EQ(eGameMessageType, 10, SET_LINEAR_VELOCITY);
|
||||||
|
ENUM_EQ(eGameMessageType, 1762, USE_SKILL_SET);
|
||||||
|
ENUM_EQ(eGameMessageType, 1763, SET_SKILL_SET_POSSESSOR);
|
||||||
|
ENUM_EQ(eGameMessageType, 1764, POPULATE_ACTION_BAR);
|
||||||
|
ENUM_EQ(eGameMessageType, 1765, GET_COMPONENT_TEMPLATE_ID);
|
||||||
|
ENUM_EQ(eGameMessageType, 1766, GET_POSSESSABLE_SKILL_SET);
|
||||||
|
ENUM_EQ(eGameMessageType, 1767, MARK_INVENTORY_ITEM_AS_ACTIVE);
|
||||||
|
ENUM_EQ(eGameMessageType, 1768, UPDATE_FORGED_ITEM);
|
||||||
|
ENUM_EQ(eGameMessageType, 1769, CAN_ITEMS_BE_REFORGED);
|
||||||
|
ENUM_EQ(eGameMessageType, 1771, NOTIFY_CLIENT_RAIL_START_FAILED);
|
||||||
|
ENUM_EQ(eGameMessageType, 1772, GET_IS_ON_RAIL);
|
||||||
|
ENUM_NE(eGameMessageType, 32);
|
||||||
|
ENUM_NE(eGameMessageType, 1776);
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
auto begin = std::chrono::high_resolution_clock::now();
|
||||||
|
for (int i = 0; i < 10000000; ++i) {
|
||||||
|
volatile auto f = StringifiedEnum::ToString(static_cast<eGameMessageType>(i)).data();
|
||||||
|
|
||||||
|
// To ensure the compiler doesn't optimize out the call, I print it at random intervals
|
||||||
|
if (rand() % 100000 == 0) LOG("%i, %s", i, f);
|
||||||
|
}
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
LOG("Time: %lld", std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count());
|
||||||
|
|
||||||
|
delete Game::logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_EARRAY_SORTED(EARRAY_VAR)\
|
||||||
|
for (int i = 0; i < EARRAY_VAR->size(); i++) {\
|
||||||
|
const auto entryCurr = EARRAY_VAR->at(i).first;\
|
||||||
|
LOG_EARRAY(EARRAY_VAR, i, entryCurr);\
|
||||||
|
const auto entryNext = EARRAY_VAR->at(++i).first;\
|
||||||
|
LOG_EARRAY(EARRAY_VAR, i, entryNext);\
|
||||||
|
ASSERT_TRUE(entryCurr < entryNext);\
|
||||||
|
};\
|
||||||
|
|
||||||
|
#define LOG_EARRAY(EARRAY_VAR, INDICE, ENTRY)\
|
||||||
|
LOG(#EARRAY_VAR"[%i] = %i, %s", INDICE, ENTRY, magic_enum::enum_name(ENTRY).data());
|
||||||
|
|
||||||
|
// Test that the magic enum arrays are pre-sorted
|
||||||
|
TEST(MagicEnumTest, ArraysAreSorted) {
|
||||||
|
Game::logger = new Logger("./MagicEnumTest_ArraysAreSorted.log", true, true);
|
||||||
|
|
||||||
|
constexpr auto wmArray = &magic_enum::enum_entries<eWorldMessageType>();
|
||||||
|
ASSERT_EARRAY_SORTED(wmArray);
|
||||||
|
|
||||||
|
constexpr auto gmArray = &magic_enum::enum_entries<eGameMessageType>();
|
||||||
|
ASSERT_EARRAY_SORTED(gmArray);
|
||||||
|
|
||||||
|
delete Game::logger;
|
||||||
|
}
|
3
thirdparty/CMakeLists.txt
vendored
3
thirdparty/CMakeLists.txt
vendored
@ -19,6 +19,9 @@ add_library(bcrypt ${SOURCES_LIBBCRYPT})
|
|||||||
# Source code for sqlite
|
# Source code for sqlite
|
||||||
add_subdirectory(SQLite)
|
add_subdirectory(SQLite)
|
||||||
|
|
||||||
|
# Source code for magic_enum
|
||||||
|
add_subdirectory(magic_enum)
|
||||||
|
|
||||||
# MariaDB C++ Connector
|
# MariaDB C++ Connector
|
||||||
include(CMakeMariaDBLists.txt)
|
include(CMakeMariaDBLists.txt)
|
||||||
|
|
||||||
|
1
thirdparty/magic_enum
vendored
Submodule
1
thirdparty/magic_enum
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e55b9b54d5cf61f8e117cafb17846d7d742dd3b4
|
Loading…
Reference in New Issue
Block a user