Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jadebenn committed Feb 11, 2024
2 parents f98a001 + 0c1ee05 commit 02ceec5
Show file tree
Hide file tree
Showing 176 changed files with 1,256 additions and 1,678 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ set(INCLUDED_DIRECTORIES
"thirdparty/SQLite"
"thirdparty/cpplinq"
"thirdparty/cpp-httplib"
"thirdparty/MD5"

"tests"
"tests/dCommonTests"
Expand Down Expand Up @@ -320,7 +321,7 @@ add_subdirectory(dPhysics)
add_subdirectory(dServer)

# Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum" "MD5")

# Add platform specific common libraries
if(UNIX)
Expand Down
8 changes: 4 additions & 4 deletions dAuthServer/AuthServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ int main(int argc, char** argv) {
Game::randomEngine = std::mt19937(time(0));

//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
std::string ourIP = "localhost";
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort);
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);

//LU client is hardcoded to use this for auth port, so I'm making it the default.
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("auth_server_port")).value_or(1001);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;

Expand Down
9 changes: 3 additions & 6 deletions dChatServer/ChatServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,15 @@ int main(int argc, char** argv) {
masterPort = masterInfo->port;
}
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1501;
std::string ourIP = "localhost";
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("chat_server_port"), ourPort);
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("chat_server_port")).value_or(1501);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;

Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);

bool dontGenerateDCF = false;
GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF);
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);

Game::randomEngine = std::mt19937(time(0));
Expand Down
6 changes: 4 additions & 2 deletions dChatServer/PlayerContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
#include "dConfig.h"

void PlayerContainer::Initialize() {
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends);
m_MaxNumberOfBestFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends")).value_or(m_MaxNumberOfBestFriends);
m_MaxNumberOfFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends")).value_or(m_MaxNumberOfFriends);
}

PlayerContainer::~PlayerContainer() {
Expand Down
7 changes: 0 additions & 7 deletions dCommon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ set(DCOMMON_SOURCES
"Game.cpp"
"GeneralUtils.cpp"
"LDFFormat.cpp"
"MD5.cpp"
"Metrics.cpp"
"NiPoint3.cpp"
"NiQuaternion.cpp"
"SHA512.cpp"
"Demangler.cpp"
"ZCompression.cpp"
"BrickByBrickFix.cpp"
Expand Down Expand Up @@ -68,8 +66,3 @@ else ()
endif ()

target_link_libraries(dCommon ZLIB::ZLIB)

# Disable deprecation warnings on MD5.cpp and SHA512.cpp for Apple Clang
if (APPLE)
set_source_files_properties("MD5.cpp" "SHA512.cpp" PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
endif()
4 changes: 0 additions & 4 deletions dCommon/GeneralUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,3 @@ std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::stri

return sortedFiles;
}

bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) {
return TryParse<float>(x.c_str(), dst.x) && TryParse<float>(y.c_str(), dst.y) && TryParse<float>(z.c_str(), dst.z);
}
160 changes: 98 additions & 62 deletions dCommon/GeneralUtils.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#pragma once

// C++
#include <stdint.h>
#include <charconv>
#include <cstdint>
#include <random>
#include <time.h>
#include <ctime>
#include <string>
#include <type_traits>
#include <string_view>
#include <optional>
#include <functional>
#include <type_traits>
#include <stdexcept>
#include "BitStream.h"
#include "NiPoint3.h"

#include "dPlatforms.h"
#include "Game.h"
#include "Logger.h"

Expand Down Expand Up @@ -123,90 +126,125 @@ namespace GeneralUtils {

std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);

// Concept constraining to enum types
template <typename T>
T Parse(const char* value);
concept Enum = std::is_enum_v<T>;

template <>
inline bool Parse(const char* value) {
return std::stoi(value);
}
// Concept constraining to numeric types
template <typename T>
concept Numeric = std::integral<T> || Enum<T> || std::floating_point<T>;

template <>
inline int32_t Parse(const char* value) {
return std::stoi(value);
}
// Concept trickery to enable parsing underlying numeric types
template <Numeric T>
struct numeric_parse { using type = T; };

template <>
inline int64_t Parse(const char* value) {
return std::stoll(value);
}
// If an enum, present an alias to its underlying type for parsing
template <Numeric T> requires Enum<T>
struct numeric_parse<T> { using type = std::underlying_type_t<T>; };

template <>
inline float Parse(const char* value) {
return std::stof(value);
}
// If a boolean, present an alias to an intermediate integral type for parsing
template <Numeric T> requires std::same_as<T, bool>
struct numeric_parse<T> { using type = uint32_t; };

template <>
inline double Parse(const char* value) {
return std::stod(value);
}
// Shorthand type alias
template <Numeric T>
using numeric_parse_t = numeric_parse<T>::type;

template <>
inline uint16_t Parse(const char* value) {
return std::stoul(value);
}
/**
* For numeric values: Parses a string_view and returns an optional variable depending on the result.
* @param str The string_view to be evaluated
* @returns An std::optional containing the desired value if it is equivalent to the string
*/
template <Numeric T>
[[nodiscard]] std::optional<T> TryParse(const std::string_view str) {
numeric_parse_t<T> result;

template <>
inline uint32_t Parse(const char* value) {
return std::stoul(value);
}
const char* const strEnd = str.data() + str.size();
const auto [parseEnd, ec] = std::from_chars(str.data(), strEnd, result);
const bool isParsed = parseEnd == strEnd && ec == std::errc{};

template <>
inline uint64_t Parse(const char* value) {
return std::stoull(value);
return isParsed ? static_cast<T>(result) : std::optional<T>{};
}

template <>
inline eInventoryType Parse(const char* value) {
return static_cast<eInventoryType>(std::stoul(value));
}
#ifdef DARKFLAME_PLATFORM_MACOS

template <>
inline eReplicaComponentType Parse(const char* value) {
return static_cast<eReplicaComponentType>(std::stoul(value));
}
// Anonymous namespace containing MacOS floating-point parse function specializations
namespace {
template <std::floating_point T>
[[nodiscard]] T Parse(const std::string_view str, size_t* parseNum);

template <typename T>
bool TryParse(const char* value, T& dst) {
try {
dst = Parse<T>(value);
template <>
[[nodiscard]] float Parse<float>(const std::string_view str, size_t* parseNum) {
return std::stof(std::string{ str }, parseNum);
}

return true;
} catch (...) {
return false;
template <>
[[nodiscard]] double Parse<double>(const std::string_view str, size_t* parseNum) {
return std::stod(std::string{ str }, parseNum);
}

template <>
[[nodiscard]] long double Parse<long double>(const std::string_view str, size_t* parseNum) {
return std::stold(std::string{ str }, parseNum);
}
}

template <typename T>
T Parse(const std::string& value) {
return Parse<T>(value.c_str());
/**
* For floating-point values: Parses a string_view and returns an optional variable depending on the result.
* Note that this function overload is only included for MacOS, as from_chars will fulfill its purpose otherwise.
* @param str The string_view to be evaluated
* @returns An std::optional containing the desired value if it is equivalent to the string
*/
template <std::floating_point T>
[[nodiscard]] std::optional<T> TryParse(const std::string_view str) noexcept try {
size_t parseNum;
const T result = Parse<T>(str, &parseNum);
const bool isParsed = str.length() == parseNum;

return isParsed ? result : std::optional<T>{};
} catch (...) {
return std::nullopt;
}

#endif

/**
* The TryParse overload for handling NiPoint3 by passing 3 seperate string references
* @param strX The string representing the X coordinate
* @param strY The string representing the Y coordinate
* @param strZ The string representing the Z coordinate
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
bool TryParse(const std::string& value, T& dst) {
return TryParse<T>(value.c_str(), dst);
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string& strX, const std::string& strY, const std::string& strZ) {
const auto x = TryParse<float>(strX);
if (!x) return std::nullopt;

const auto y = TryParse<float>(strY);
if (!y) return std::nullopt;

const auto z = TryParse<float>(strZ);
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt;
}

bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst);
/**
* The TryParse overload for handling NiPoint3 by passingn a reference to a vector of three strings
* @param str The string vector representing the X, Y, and Xcoordinates
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::vector<std::string>& str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
}

template<typename T>
template <typename T>
std::u16string to_u16string(T value) {
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
}

// From boost::hash_combine
template <class T>
void hash_combine(std::size_t& s, const T& v) {
constexpr void hash_combine(std::size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
Expand Down Expand Up @@ -239,10 +277,8 @@ namespace GeneralUtils {
* @param entry Enum entry to cast
* @returns The enum entry's value in its underlying type
*/
template <typename eType>
inline constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) {
static_assert(std::is_enum_v<eType>, "Not an enum");

template <Enum eType>
constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) noexcept {
return static_cast<typename std::underlying_type_t<eType>>(entry);
}

Expand Down
Loading

0 comments on commit 02ceec5

Please sign in to comment.