mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-02 06:08:24 +00:00
Merge remote-tracking branch 'upstream/main' into PetFixes
This commit is contained in:
164
dCommon/Amf3.h
164
dCommon/Amf3.h
@@ -31,54 +31,68 @@ enum class eAmf : uint8_t {
|
||||
|
||||
class AMFBaseValue {
|
||||
public:
|
||||
virtual eAmf GetValueType() { return eAmf::Undefined; };
|
||||
AMFBaseValue() {};
|
||||
virtual ~AMFBaseValue() {};
|
||||
[[nodiscard]] constexpr virtual eAmf GetValueType() const noexcept { return eAmf::Undefined; }
|
||||
constexpr AMFBaseValue() noexcept = default;
|
||||
constexpr virtual ~AMFBaseValue() noexcept = default;
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
// AMFValue template class instantiations
|
||||
template <typename ValueType>
|
||||
class AMFValue : public AMFBaseValue {
|
||||
public:
|
||||
AMFValue() {};
|
||||
AMFValue(ValueType value) { SetValue(value); };
|
||||
virtual ~AMFValue() override {};
|
||||
AMFValue() = default;
|
||||
AMFValue(const ValueType value) { m_Data = value; }
|
||||
virtual ~AMFValue() override = default;
|
||||
|
||||
eAmf GetValueType() override { return eAmf::Undefined; };
|
||||
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override;
|
||||
|
||||
[[nodiscard]] const ValueType& GetValue() const { return m_Data; }
|
||||
void SetValue(const ValueType value) { m_Data = value; }
|
||||
|
||||
const ValueType& GetValue() { return data; };
|
||||
void SetValue(ValueType value) { data = value; };
|
||||
protected:
|
||||
ValueType data;
|
||||
ValueType m_Data;
|
||||
};
|
||||
|
||||
// Explicit template class instantiations
|
||||
template class AMFValue<std::nullptr_t>;
|
||||
template class AMFValue<bool>;
|
||||
template class AMFValue<int32_t>;
|
||||
template class AMFValue<uint32_t>;
|
||||
template class AMFValue<std::string>;
|
||||
template class AMFValue<double>;
|
||||
|
||||
// AMFValue template class member function instantiations
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<std::nullptr_t>::GetValueType() const noexcept { return eAmf::Null; }
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<bool>::GetValueType() const noexcept { return m_Data ? eAmf::True : eAmf::False; }
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<int32_t>::GetValueType() const noexcept { return eAmf::Integer; }
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<uint32_t>::GetValueType() const noexcept { return eAmf::Integer; }
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<std::string>::GetValueType() const noexcept { return eAmf::String; }
|
||||
template <> [[nodiscard]] constexpr eAmf AMFValue<double>::GetValueType() const noexcept { return eAmf::Double; }
|
||||
|
||||
template <typename ValueType>
|
||||
[[nodiscard]] constexpr eAmf AMFValue<ValueType>::GetValueType() const noexcept { return eAmf::Undefined; }
|
||||
|
||||
// As a string this is much easier to write and read from a BitStream.
|
||||
template<>
|
||||
template <>
|
||||
class AMFValue<const char*> : public AMFBaseValue {
|
||||
public:
|
||||
AMFValue() {};
|
||||
AMFValue(const char* value) { SetValue(std::string(value)); };
|
||||
virtual ~AMFValue() override {};
|
||||
AMFValue() = default;
|
||||
AMFValue(const char* value) { m_Data = value; }
|
||||
virtual ~AMFValue() override = default;
|
||||
|
||||
eAmf GetValueType() override { return eAmf::String; };
|
||||
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::String; }
|
||||
|
||||
const std::string& GetValue() { return data; };
|
||||
void SetValue(std::string value) { data = value; };
|
||||
[[nodiscard]] const std::string& GetValue() const { return m_Data; }
|
||||
void SetValue(const std::string& value) { m_Data = value; }
|
||||
protected:
|
||||
std::string data;
|
||||
std::string m_Data;
|
||||
};
|
||||
|
||||
typedef AMFValue<std::nullptr_t> AMFNullValue;
|
||||
typedef AMFValue<bool> AMFBoolValue;
|
||||
typedef AMFValue<int32_t> AMFIntValue;
|
||||
typedef AMFValue<std::string> AMFStringValue;
|
||||
typedef AMFValue<double> AMFDoubleValue;
|
||||
|
||||
template<> inline eAmf AMFValue<std::nullptr_t>::GetValueType() { return eAmf::Null; };
|
||||
template<> inline eAmf AMFValue<bool>::GetValueType() { return this->data ? eAmf::True : eAmf::False; };
|
||||
template<> inline eAmf AMFValue<int32_t>::GetValueType() { return eAmf::Integer; };
|
||||
template<> inline eAmf AMFValue<uint32_t>::GetValueType() { return eAmf::Integer; };
|
||||
template<> inline eAmf AMFValue<std::string>::GetValueType() { return eAmf::String; };
|
||||
template<> inline eAmf AMFValue<double>::GetValueType() { return eAmf::Double; };
|
||||
using AMFNullValue = AMFValue<std::nullptr_t>;
|
||||
using AMFBoolValue = AMFValue<bool>;
|
||||
using AMFIntValue = AMFValue<int32_t>;
|
||||
using AMFStringValue = AMFValue<std::string>;
|
||||
using AMFDoubleValue = AMFValue<double>;
|
||||
|
||||
/**
|
||||
* The AMFArrayValue object holds 2 types of lists:
|
||||
@@ -89,12 +103,11 @@ template<> inline eAmf AMFValue<double>::GetValueType() { return eAmf::Double; }
|
||||
* and are not to be deleted by a caller.
|
||||
*/
|
||||
class AMFArrayValue : public AMFBaseValue {
|
||||
|
||||
typedef std::unordered_map<std::string, AMFBaseValue*> AMFAssociative;
|
||||
typedef std::vector<AMFBaseValue*> AMFDense;
|
||||
using AMFAssociative = std::unordered_map<std::string, AMFBaseValue*>;
|
||||
using AMFDense = std::vector<AMFBaseValue*>;
|
||||
|
||||
public:
|
||||
eAmf GetValueType() override { return eAmf::Array; };
|
||||
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; }
|
||||
|
||||
~AMFArrayValue() override {
|
||||
for (auto valueToDelete : GetDense()) {
|
||||
@@ -109,17 +122,17 @@ public:
|
||||
valueToDelete.second = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Associative portion of the object
|
||||
*/
|
||||
inline AMFAssociative& GetAssociative() { return this->associative; };
|
||||
[[nodiscard]] inline AMFAssociative& GetAssociative() noexcept { return this->associative; }
|
||||
|
||||
/**
|
||||
* Returns the dense portion of the object
|
||||
*/
|
||||
inline AMFDense& GetDense() { return this->dense; };
|
||||
[[nodiscard]] inline AMFDense& GetDense() noexcept { return this->dense; }
|
||||
|
||||
/**
|
||||
* Inserts an AMFValue into the associative portion with the given key.
|
||||
@@ -135,8 +148,8 @@ public:
|
||||
* @return The inserted element if the type matched,
|
||||
* or nullptr if a key existed and was not the same type
|
||||
*/
|
||||
template<typename ValueType>
|
||||
std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, ValueType value) {
|
||||
template <typename ValueType>
|
||||
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, const ValueType value) {
|
||||
auto element = associative.find(key);
|
||||
AMFValue<ValueType>* val = nullptr;
|
||||
bool found = true;
|
||||
@@ -148,10 +161,10 @@ public:
|
||||
found = false;
|
||||
}
|
||||
return std::make_pair(val, found);
|
||||
};
|
||||
}
|
||||
|
||||
// Associates an array with a string key
|
||||
std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
|
||||
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
|
||||
auto element = associative.find(key);
|
||||
AMFArrayValue* val = nullptr;
|
||||
bool found = true;
|
||||
@@ -163,10 +176,10 @@ public:
|
||||
found = false;
|
||||
}
|
||||
return std::make_pair(val, found);
|
||||
};
|
||||
}
|
||||
|
||||
// Associates an array with an integer key
|
||||
std::pair<AMFBaseValue*, bool> Insert(const uint32_t& index) {
|
||||
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) {
|
||||
AMFArrayValue* val = nullptr;
|
||||
bool inserted = false;
|
||||
if (index >= dense.size()) {
|
||||
@@ -176,7 +189,7 @@ public:
|
||||
inserted = true;
|
||||
}
|
||||
return std::make_pair(dynamic_cast<AMFArrayValue*>(dense.at(index)), inserted);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts an AMFValue into the AMFArray key'd by index.
|
||||
@@ -188,8 +201,8 @@ public:
|
||||
* @return The inserted element, or nullptr if the type did not match
|
||||
* what was at the index.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
std::pair<AMFValue<ValueType>*, bool> Insert(const uint32_t& index, ValueType value) {
|
||||
template <typename ValueType>
|
||||
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) {
|
||||
AMFValue<ValueType>* val = nullptr;
|
||||
bool inserted = false;
|
||||
if (index >= this->dense.size()) {
|
||||
@@ -199,7 +212,7 @@ public:
|
||||
inserted = true;
|
||||
}
|
||||
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(this->dense.at(index)), inserted);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an AMFValue into the associative portion with the given key.
|
||||
@@ -210,7 +223,7 @@ public:
|
||||
* @param key The key to associate with the value
|
||||
* @param value The value to insert
|
||||
*/
|
||||
void Insert(const std::string& key, AMFBaseValue* value) {
|
||||
void Insert(const std::string& key, AMFBaseValue* const value) {
|
||||
auto element = associative.find(key);
|
||||
if (element != associative.end() && element->second) {
|
||||
delete element->second;
|
||||
@@ -218,7 +231,7 @@ public:
|
||||
} else {
|
||||
associative.insert(std::make_pair(key, value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an AMFValue into the associative portion with the given index.
|
||||
@@ -229,7 +242,7 @@ public:
|
||||
* @param key The key to associate with the value
|
||||
* @param value The value to insert
|
||||
*/
|
||||
void Insert(const uint32_t index, AMFBaseValue* value) {
|
||||
void Insert(const size_t index, AMFBaseValue* const value) {
|
||||
if (index < dense.size()) {
|
||||
AMFDense::iterator itr = dense.begin() + index;
|
||||
if (*itr) delete dense.at(index);
|
||||
@@ -237,7 +250,7 @@ public:
|
||||
dense.resize(index + 1);
|
||||
}
|
||||
dense.at(index) = value;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes an AMFValue into the back of the dense portion.
|
||||
@@ -249,10 +262,10 @@ public:
|
||||
*
|
||||
* @return The inserted pointer, or nullptr should the key already be in use.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline AMFValue<ValueType>* Push(ValueType value) {
|
||||
template <typename ValueType>
|
||||
[[maybe_unused]] inline AMFValue<ValueType>* Push(const ValueType value) {
|
||||
return Insert(this->dense.size(), value).first;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the key from the associative portion
|
||||
@@ -261,7 +274,7 @@ public:
|
||||
*
|
||||
* @param key The key to remove from the associative portion
|
||||
*/
|
||||
void Remove(const std::string& key, bool deleteValue = true) {
|
||||
void Remove(const std::string& key, const bool deleteValue = true) {
|
||||
AMFAssociative::iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
if (deleteValue) delete it->second;
|
||||
@@ -272,7 +285,7 @@ public:
|
||||
/**
|
||||
* Pops the last element in the dense portion, deleting it in the process.
|
||||
*/
|
||||
void Remove(const uint32_t index) {
|
||||
void Remove(const size_t index) {
|
||||
if (!this->dense.empty() && index < this->dense.size()) {
|
||||
auto itr = this->dense.begin() + index;
|
||||
if (*itr) delete (*itr);
|
||||
@@ -284,29 +297,29 @@ public:
|
||||
if (!this->dense.empty()) Remove(this->dense.size() - 1);
|
||||
}
|
||||
|
||||
AMFArrayValue* GetArray(const std::string& key) {
|
||||
[[nodiscard]] AMFArrayValue* GetArray(const std::string& key) {
|
||||
AMFAssociative::const_iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
return dynamic_cast<AMFArrayValue*>(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
AMFArrayValue* GetArray(const uint32_t index) {
|
||||
[[nodiscard]] AMFArrayValue* GetArray(const size_t index) {
|
||||
return index >= this->dense.size() ? nullptr : dynamic_cast<AMFArrayValue*>(this->dense.at(index));
|
||||
};
|
||||
}
|
||||
|
||||
inline AMFArrayValue* InsertArray(const std::string& key) {
|
||||
[[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) {
|
||||
return static_cast<AMFArrayValue*>(Insert(key).first);
|
||||
};
|
||||
}
|
||||
|
||||
inline AMFArrayValue* InsertArray(const uint32_t index) {
|
||||
[[maybe_unused]] inline AMFArrayValue* InsertArray(const size_t index) {
|
||||
return static_cast<AMFArrayValue*>(Insert(index).first);
|
||||
};
|
||||
}
|
||||
|
||||
inline AMFArrayValue* PushArray() {
|
||||
[[maybe_unused]] inline AMFArrayValue* PushArray() {
|
||||
return static_cast<AMFArrayValue*>(Insert(this->dense.size()).first);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an AMFValue by the key from the associative portion and converts it
|
||||
@@ -318,18 +331,18 @@ public:
|
||||
* @return The AMFValue
|
||||
*/
|
||||
template <typename AmfType>
|
||||
AMFValue<AmfType>* Get(const std::string& key) const {
|
||||
[[nodiscard]] AMFValue<AmfType>* Get(const std::string& key) const {
|
||||
AMFAssociative::const_iterator it = this->associative.find(key);
|
||||
return it != this->associative.end() ?
|
||||
dynamic_cast<AMFValue<AmfType>*>(it->second) :
|
||||
nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
// Get from the array but dont cast it
|
||||
AMFBaseValue* Get(const std::string& key) const {
|
||||
[[nodiscard]] AMFBaseValue* Get(const std::string& key) const {
|
||||
AMFAssociative::const_iterator it = this->associative.find(key);
|
||||
return it != this->associative.end() ? it->second : nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an AMFValue object at a position in the dense portion.
|
||||
@@ -341,16 +354,17 @@ public:
|
||||
* @return The casted object, or nullptr.
|
||||
*/
|
||||
template <typename AmfType>
|
||||
AMFValue<AmfType>* Get(uint32_t index) const {
|
||||
[[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const {
|
||||
return index < this->dense.size() ?
|
||||
dynamic_cast<AMFValue<AmfType>*>(this->dense.at(index)) :
|
||||
nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
// Get from the dense but dont cast it
|
||||
AMFBaseValue* Get(const uint32_t index) const {
|
||||
[[nodiscard]] AMFBaseValue* Get(const size_t index) const {
|
||||
return index < this->dense.size() ? this->dense.at(index) : nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The associative portion. These values are key'd with strings to an AMFValue.
|
||||
|
||||
@@ -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"
|
||||
@@ -20,6 +18,12 @@ set(DCOMMON_SOURCES
|
||||
"FdbToSqlite.cpp"
|
||||
)
|
||||
|
||||
# Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible.
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97185
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set_source_files_properties("FdbToSqlite.cpp" PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow")
|
||||
endif()
|
||||
|
||||
add_subdirectory(dClient)
|
||||
|
||||
foreach(file ${DCOMMON_DCLIENT_SOURCES})
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
template <>
|
||||
inline bool Parse(const char* value) {
|
||||
return std::stoi(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int32_t Parse(const char* value) {
|
||||
return std::stoi(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t Parse(const char* value) {
|
||||
return std::stoll(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float Parse(const char* value) {
|
||||
return std::stof(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double Parse(const char* value) {
|
||||
return std::stod(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint16_t Parse(const char* value) {
|
||||
return std::stoul(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32_t Parse(const char* value) {
|
||||
return std::stoul(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t Parse(const char* value) {
|
||||
return std::stoull(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline eInventoryType Parse(const char* value) {
|
||||
return static_cast<eInventoryType>(std::stoul(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline eReplicaComponentType Parse(const char* value) {
|
||||
return static_cast<eReplicaComponentType>(std::stoul(value));
|
||||
}
|
||||
concept Enum = std::is_enum_v<T>;
|
||||
|
||||
// Concept constraining to numeric types
|
||||
template <typename T>
|
||||
bool TryParse(const char* value, T& dst) {
|
||||
try {
|
||||
dst = Parse<T>(value);
|
||||
concept Numeric = std::integral<T> || Enum<T> || std::floating_point<T>;
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
// Concept trickery to enable parsing underlying numeric types
|
||||
template <Numeric T>
|
||||
struct numeric_parse { using type = T; };
|
||||
|
||||
// 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>; };
|
||||
|
||||
// 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; };
|
||||
|
||||
// Shorthand type alias
|
||||
template <Numeric T>
|
||||
using numeric_parse_t = numeric_parse<T>::type;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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{};
|
||||
|
||||
return isParsed ? static_cast<T>(result) : std::optional<T>{};
|
||||
}
|
||||
|
||||
#ifdef DARKFLAME_PLATFORM_MACOS
|
||||
|
||||
// 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 <>
|
||||
[[nodiscard]] float Parse<float>(const std::string_view str, size_t* parseNum) {
|
||||
return std::stof(std::string{ str }, parseNum);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
T Parse(const std::string& value) {
|
||||
return Parse<T>(value.c_str());
|
||||
[[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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
bool TryParse(const std::string& value, T& dst) {
|
||||
return TryParse<T>(value.c_str(), dst);
|
||||
}
|
||||
|
||||
bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,33 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
|
||||
}
|
||||
|
||||
case LDF_TYPE_S32: {
|
||||
int32_t data;
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto data = GeneralUtils::TryParse<int32_t>(ldfTypeAndValue.second);
|
||||
if (!data) {
|
||||
LOG("Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
returnValue = new LDFData<int32_t>(key, data);
|
||||
returnValue = new LDFData<int32_t>(key, data.value());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LDF_TYPE_FLOAT: {
|
||||
float data;
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto data = GeneralUtils::TryParse<float>(ldfTypeAndValue.second);
|
||||
if (!data) {
|
||||
LOG("Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
returnValue = new LDFData<float>(key, data);
|
||||
returnValue = new LDFData<float>(key, data.value());
|
||||
break;
|
||||
}
|
||||
|
||||
case LDF_TYPE_DOUBLE: {
|
||||
double data;
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto data = GeneralUtils::TryParse<double>(ldfTypeAndValue.second);
|
||||
if (!data) {
|
||||
LOG("Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
returnValue = new LDFData<double>(key, data);
|
||||
returnValue = new LDFData<double>(key, data.value());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -100,10 +100,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
|
||||
} else if (ldfTypeAndValue.second == "false") {
|
||||
data = 0;
|
||||
} else {
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto dataOptional = GeneralUtils::TryParse<uint32_t>(ldfTypeAndValue.second);
|
||||
if (!dataOptional) {
|
||||
LOG("Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
data = dataOptional.value();
|
||||
}
|
||||
|
||||
returnValue = new LDFData<uint32_t>(key, data);
|
||||
@@ -118,10 +120,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
|
||||
} else if (ldfTypeAndValue.second == "false") {
|
||||
data = false;
|
||||
} else {
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto dataOptional = GeneralUtils::TryParse<bool>(ldfTypeAndValue.second);
|
||||
if (!dataOptional) {
|
||||
LOG("Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
data = dataOptional.value();
|
||||
}
|
||||
|
||||
returnValue = new LDFData<bool>(key, data);
|
||||
@@ -129,22 +133,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
|
||||
}
|
||||
|
||||
case LDF_TYPE_U64: {
|
||||
uint64_t data;
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto data = GeneralUtils::TryParse<uint64_t>(ldfTypeAndValue.second);
|
||||
if (!data) {
|
||||
LOG("Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
returnValue = new LDFData<uint64_t>(key, data);
|
||||
returnValue = new LDFData<uint64_t>(key, data.value());
|
||||
break;
|
||||
}
|
||||
|
||||
case LDF_TYPE_OBJID: {
|
||||
LWOOBJID data;
|
||||
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
|
||||
const auto data = GeneralUtils::TryParse<LWOOBJID>(ldfTypeAndValue.second);
|
||||
if (!data) {
|
||||
LOG("Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
|
||||
return nullptr;
|
||||
}
|
||||
returnValue = new LDFData<LWOOBJID>(key, data);
|
||||
returnValue = new LDFData<LWOOBJID>(key, data.value());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
return new LDFData<T>(key, value);
|
||||
}
|
||||
|
||||
inline static T Default = {};
|
||||
inline static const T Default = {};
|
||||
};
|
||||
|
||||
// LDF Types
|
||||
|
||||
348
dCommon/MD5.cpp
348
dCommon/MD5.cpp
@@ -1,348 +0,0 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
based on:
|
||||
|
||||
md5.h and md5.c
|
||||
reference implemantion of RFC 1321
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
/* interface header */
|
||||
#include "MD5.h"
|
||||
|
||||
/* system implementation headers */
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
// Constants for MD5Transform routine.
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
|
||||
return x & y | ~x & z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
|
||||
return x & z | y & ~z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
// rotate_left rotates x left n bits.
|
||||
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// default ctor, just initailize
|
||||
MD5::MD5() {
|
||||
init();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// nifty shortcut ctor, compute MD5 for string and finalize it right away
|
||||
MD5::MD5(const std::string& text) {
|
||||
init();
|
||||
update(text.c_str(), text.length());
|
||||
finalize();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
void MD5::init() {
|
||||
finalized = false;
|
||||
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
|
||||
void MD5::decode(uint4 output[], const uint1 input[], size_type len) {
|
||||
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
|
||||
(((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// encodes input (uint4) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::encode(uint1 output[], const uint4 input[], size_type len) {
|
||||
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = input[i] & 0xff;
|
||||
output[j + 1] = (input[i] >> 8) & 0xff;
|
||||
output[j + 2] = (input[i] >> 16) & 0xff;
|
||||
output[j + 3] = (input[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// apply MD5 algo on a block
|
||||
void MD5::transform(const uint1 block[blocksize]) {
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
decode(x, block, blocksize);
|
||||
|
||||
/* Round 1 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(x, 0, sizeof x);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 block update operation. Continues an MD5 message-digest
|
||||
// operation, processing another message block
|
||||
void MD5::update(const unsigned char input[], size_type length) {
|
||||
// compute number of bytes mod 64
|
||||
size_type index = count[0] / 8 % blocksize;
|
||||
|
||||
// Update number of bits
|
||||
if ((count[0] += (length << 3)) < (length << 3))
|
||||
count[1]++;
|
||||
count[1] += (length >> 29);
|
||||
|
||||
// number of bytes we need to fill in buffer
|
||||
size_type firstpart = 64 - index;
|
||||
|
||||
size_type i;
|
||||
|
||||
// transform as many times as possible.
|
||||
if (length >= firstpart) {
|
||||
// fill buffer first, transform
|
||||
memcpy(&buffer[index], input, firstpart);
|
||||
transform(buffer);
|
||||
|
||||
// transform chunks of blocksize (64 bytes)
|
||||
for (i = firstpart; i + blocksize <= length; i += blocksize)
|
||||
transform(&input[i]);
|
||||
|
||||
index = 0;
|
||||
} else
|
||||
i = 0;
|
||||
|
||||
// buffer remaining input
|
||||
memcpy(&buffer[index], &input[i], length - i);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// for convenience provide a verson with signed char
|
||||
void MD5::update(const char input[], size_type length) {
|
||||
update((const unsigned char*)input, length);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
// the message digest and zeroizing the context.
|
||||
MD5& MD5::finalize() {
|
||||
static unsigned char padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (!finalized) {
|
||||
// Save number of bits
|
||||
unsigned char bits[8];
|
||||
encode(bits, count, 8);
|
||||
|
||||
// pad out to 56 mod 64.
|
||||
size_type index = count[0] / 8 % 64;
|
||||
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(padding, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
update(bits, 8);
|
||||
|
||||
// Store state in digest
|
||||
encode(digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
memset(count, 0, sizeof count);
|
||||
|
||||
finalized = true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// return hex representation of digest as string
|
||||
std::string MD5::hexdigest() const {
|
||||
if (!finalized)
|
||||
return "";
|
||||
|
||||
char buf[33];
|
||||
for (int i = 0; i < 16; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
buf[32] = 0;
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, MD5 md5) {
|
||||
return out << md5.hexdigest();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::string md5(const std::string str) {
|
||||
MD5 md5 = MD5(str);
|
||||
|
||||
return md5.hexdigest();
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
based on:
|
||||
|
||||
md5.h and md5.c
|
||||
reference implementation of RFC 1321
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BZF_MD5_H
|
||||
#define BZF_MD5_H
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// a small class for calculating MD5 hashes of strings or byte arrays
|
||||
// it is not meant to be fast or secure
|
||||
//
|
||||
// usage: 1) feed it blocks of uchars with update()
|
||||
// 2) finalize()
|
||||
// 3) get hexdigest() string
|
||||
// or
|
||||
// MD5(std::string).hexdigest()
|
||||
//
|
||||
// assumes that char is 8 bit and int is 32 bit
|
||||
class MD5
|
||||
{
|
||||
public:
|
||||
typedef unsigned int size_type; // must be 32bit
|
||||
|
||||
MD5();
|
||||
MD5(const std::string& text);
|
||||
void update(const unsigned char* buf, size_type length);
|
||||
void update(const char* buf, size_type length);
|
||||
MD5& finalize();
|
||||
std::string hexdigest() const;
|
||||
friend std::ostream& operator<<(std::ostream&, MD5 md5);
|
||||
|
||||
private:
|
||||
void init();
|
||||
typedef unsigned char uint1; // 8bit
|
||||
typedef unsigned int uint4; // 32bit
|
||||
enum { blocksize = 64 }; // VC6 won't eat a const static int here
|
||||
|
||||
void transform(const uint1 block[blocksize]);
|
||||
static void decode(uint4 output[], const uint1 input[], size_type len);
|
||||
static void encode(uint1 output[], const uint4 input[], size_type len);
|
||||
|
||||
bool finalized;
|
||||
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
|
||||
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
|
||||
uint4 state[4]; // digest so far
|
||||
uint1 digest[16]; // the result
|
||||
|
||||
// low level logic operations
|
||||
static inline uint4 F(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 rotate_left(uint4 x, int n);
|
||||
static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
};
|
||||
|
||||
std::string md5(const std::string str);
|
||||
|
||||
#endif
|
||||
@@ -1,210 +1,24 @@
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
// C++
|
||||
#include <cmath>
|
||||
|
||||
// Static Variables
|
||||
const NiPoint3 NiPoint3::ZERO(0.0f, 0.0f, 0.0f);
|
||||
const NiPoint3 NiPoint3::UNIT_X(1.0f, 0.0f, 0.0f);
|
||||
const NiPoint3 NiPoint3::UNIT_Y(0.0f, 1.0f, 0.0f);
|
||||
const NiPoint3 NiPoint3::UNIT_Z(0.0f, 0.0f, 1.0f);
|
||||
const NiPoint3 NiPoint3::UNIT_ALL(1.0f, 1.0f, 1.0f);
|
||||
|
||||
//! Initializer
|
||||
NiPoint3::NiPoint3(void) {
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
//! Initializer
|
||||
NiPoint3::NiPoint3(float x, float y, float z) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
//! Copy Constructor
|
||||
NiPoint3::NiPoint3(const NiPoint3& point) {
|
||||
this->x = point.x;
|
||||
this->y = point.y;
|
||||
this->z = point.z;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
NiPoint3::~NiPoint3(void) {}
|
||||
|
||||
// MARK: Getters / Setters
|
||||
|
||||
//! Gets the X coordinate
|
||||
float NiPoint3::GetX(void) const {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
void NiPoint3::SetX(float x) {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
float NiPoint3::GetY(void) const {
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
void NiPoint3::SetY(float y) {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
float NiPoint3::GetZ(void) const {
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
void NiPoint3::SetZ(float z) {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Gets the length of the vector
|
||||
float NiPoint3::Length(void) const {
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Gets the squared length of a vector
|
||||
float NiPoint3::SquaredLength(void) const {
|
||||
return (x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
float NiPoint3::DotProduct(const Vector3& vec) const {
|
||||
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
|
||||
}
|
||||
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
Vector3 NiPoint3::CrossProduct(const Vector3& vec) const {
|
||||
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
|
||||
((this->z * vec.x) - (this->x * vec.z)),
|
||||
((this->x * vec.y) - (this->y * vec.x)));
|
||||
float NiPoint3::Length() const {
|
||||
return std::sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Unitize the vector
|
||||
NiPoint3 NiPoint3::Unitize(void) const {
|
||||
NiPoint3 NiPoint3::Unitize() const {
|
||||
float length = this->Length();
|
||||
|
||||
return length != 0 ? *this / length : NiPoint3::ZERO;
|
||||
return length != 0 ? *this / length : NiPoint3Constant::ZERO;
|
||||
}
|
||||
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool NiPoint3::operator==(const NiPoint3& point) const {
|
||||
return point.x == this->x && point.y == this->y && point.z == this->z;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool NiPoint3::operator!=(const NiPoint3& point) const {
|
||||
return !(*this == point);
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
float& NiPoint3::operator[](int i) {
|
||||
float* base = &x;
|
||||
return base[i];
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
const float& NiPoint3::operator[](int i) const {
|
||||
const float* base = &x;
|
||||
return base[i];
|
||||
}
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
|
||||
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
|
||||
}
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3& NiPoint3::operator+=(const NiPoint3& point) {
|
||||
this->x += point.x;
|
||||
this->y += point.y;
|
||||
this->z += point.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
NiPoint3& NiPoint3::operator*=(const float scalar) {
|
||||
this->x *= scalar;
|
||||
this->y *= scalar;
|
||||
this->z *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for subtraction of vectors
|
||||
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
|
||||
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
|
||||
}
|
||||
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
NiPoint3 NiPoint3::operator+(float fScalar) const {
|
||||
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
|
||||
}
|
||||
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
NiPoint3 NiPoint3::operator-(float fScalar) const {
|
||||
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar multiplication of a vector
|
||||
NiPoint3 NiPoint3::operator*(float fScalar) const {
|
||||
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar division of a vector
|
||||
NiPoint3 NiPoint3::operator/(float fScalar) const {
|
||||
float retX = this->x != 0 ? this->x / fScalar : 0;
|
||||
float retY = this->y != 0 ? this->y / fScalar : 0;
|
||||
float retZ = this->z != 0 ? this->z / fScalar : 0;
|
||||
return NiPoint3(retX, retY, retZ);
|
||||
}
|
||||
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
|
||||
bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) {
|
||||
if (this->x < minPoint.x) return false;
|
||||
if (this->x > maxPoint.x) return false;
|
||||
if (this->y < minPoint.y) return false;
|
||||
if (this->y > maxPoint.y) return false;
|
||||
|
||||
return (this->z < maxPoint.z && this->z > minPoint.z);
|
||||
}
|
||||
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
bool NiPoint3::IsWithinSpehere(const NiPoint3& sphereCenter, float radius) {
|
||||
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
|
||||
return (diffVec.SquaredLength() <= (radius * radius));
|
||||
}
|
||||
|
||||
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) {
|
||||
if (a == b) return a;
|
||||
|
||||
const auto pa = p - a;
|
||||
const auto ab = b - a;
|
||||
|
||||
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
|
||||
|
||||
if (t <= 0.0f) return a;
|
||||
|
||||
if (t >= 1.0f) return b;
|
||||
|
||||
return a + ab * t;
|
||||
}
|
||||
|
||||
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b) {
|
||||
const auto dot = a.DotProduct(b);
|
||||
const auto lenA = a.SquaredLength();
|
||||
@@ -220,15 +34,7 @@ float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b) {
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) {
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta) {
|
||||
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, const float maxDistanceDelta) {
|
||||
float dx = target.x - current.x;
|
||||
float dy = target.y - current.y;
|
||||
float dz = target.z - current.z;
|
||||
@@ -249,29 +55,3 @@ NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target,
|
||||
float length = std::sqrt(lengthSquared);
|
||||
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
|
||||
}
|
||||
|
||||
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
|
||||
NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) {
|
||||
Vector3 vector;
|
||||
float num12 = rotation.x + rotation.x;
|
||||
float num2 = rotation.y + rotation.y;
|
||||
float num = rotation.z + rotation.z;
|
||||
float num11 = rotation.w * num12;
|
||||
float num10 = rotation.w * num2;
|
||||
float num9 = rotation.w * num;
|
||||
float num8 = rotation.x * num12;
|
||||
float num7 = rotation.x * num2;
|
||||
float num6 = rotation.x * num;
|
||||
float num5 = rotation.y * num2;
|
||||
float num4 = rotation.y * num;
|
||||
float num3 = rotation.z * num;
|
||||
|
||||
NiPoint3 value = *this;
|
||||
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
|
||||
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
|
||||
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
|
||||
vector.x = num15;
|
||||
vector.y = num14;
|
||||
vector.z = num13;
|
||||
return vector;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef __NIPOINT3_H__
|
||||
#define __NIPOINT3_H__
|
||||
|
||||
/*!
|
||||
\file NiPoint3.hpp
|
||||
@@ -12,13 +13,13 @@ typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoin
|
||||
//! A custom class the defines a point in space
|
||||
class NiPoint3 {
|
||||
public:
|
||||
float x; //!< The x position
|
||||
float y; //!< The y position
|
||||
float z; //!< The z position
|
||||
float x{ 0 }; //!< The x position
|
||||
float y{ 0 }; //!< The y position
|
||||
float z{ 0 }; //!< The z position
|
||||
|
||||
|
||||
//! Initializer
|
||||
NiPoint3(void);
|
||||
constexpr NiPoint3() = default;
|
||||
|
||||
//! Initializer
|
||||
/*!
|
||||
@@ -26,23 +27,21 @@ public:
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiPoint3(float x, float y, float z);
|
||||
constexpr NiPoint3(const float x, const float y, const float z) noexcept
|
||||
: x{ x }
|
||||
, y{ y }
|
||||
, z{ z } {
|
||||
}
|
||||
|
||||
//! Copy Constructor
|
||||
/*!
|
||||
\param point The point to copy
|
||||
*/
|
||||
NiPoint3(const NiPoint3& point);
|
||||
|
||||
//! Destructor
|
||||
~NiPoint3(void);
|
||||
|
||||
// MARK: Constants
|
||||
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
|
||||
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
|
||||
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
|
||||
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
|
||||
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
|
||||
constexpr NiPoint3(const NiPoint3& point) noexcept
|
||||
: x{ point.x }
|
||||
, y{ point.y }
|
||||
, z{ point.z } {
|
||||
}
|
||||
|
||||
// MARK: Getters / Setters
|
||||
|
||||
@@ -50,38 +49,37 @@ public:
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
[[nodiscard]] constexpr float GetX() const noexcept;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
constexpr void SetX(const float x) noexcept;
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
[[nodiscard]] constexpr float GetY() const noexcept;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
constexpr void SetY(const float y) noexcept;
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
[[nodiscard]] constexpr float GetZ() const noexcept;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
|
||||
constexpr void SetZ(const float z) noexcept;
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
@@ -89,72 +87,70 @@ public:
|
||||
/*!
|
||||
\return The scalar length of the vector
|
||||
*/
|
||||
float Length(void) const;
|
||||
[[nodiscard]] float Length() const;
|
||||
|
||||
//! Gets the squared length of a vector
|
||||
/*!
|
||||
\return The squared length of a vector
|
||||
*/
|
||||
float SquaredLength(void) const;
|
||||
[[nodiscard]] constexpr float SquaredLength() const noexcept;
|
||||
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The dot product of the two vectors
|
||||
*/
|
||||
float DotProduct(const Vector3& vec) const;
|
||||
[[nodiscard]] constexpr float DotProduct(const Vector3& vec) const noexcept;
|
||||
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The cross product of the two vectors
|
||||
*/
|
||||
Vector3 CrossProduct(const Vector3& vec) const;
|
||||
[[nodiscard]] constexpr Vector3 CrossProduct(const Vector3& vec) const noexcept;
|
||||
|
||||
//! Unitize the vector
|
||||
/*!
|
||||
\returns The current vector
|
||||
*/
|
||||
NiPoint3 Unitize(void) const;
|
||||
|
||||
[[nodiscard]] NiPoint3 Unitize() const;
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiPoint3& point) const;
|
||||
constexpr bool operator==(const NiPoint3& point) const noexcept;
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiPoint3& point) const;
|
||||
constexpr bool operator!=(const NiPoint3& point) const noexcept;
|
||||
|
||||
//! Operator for subscripting
|
||||
float& operator[](int i);
|
||||
constexpr float& operator[](const int i) noexcept;
|
||||
|
||||
//! Operator for subscripting
|
||||
const float& operator[](int i) const;
|
||||
constexpr const float& operator[](const int i) const noexcept;
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3 operator+(const NiPoint3& point) const;
|
||||
constexpr NiPoint3 operator+(const NiPoint3& point) const noexcept;
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3& operator+=(const NiPoint3& point);
|
||||
constexpr NiPoint3& operator+=(const NiPoint3& point) noexcept;
|
||||
|
||||
NiPoint3& operator*=(const float scalar);
|
||||
constexpr NiPoint3& operator*=(const float scalar) noexcept;
|
||||
|
||||
//! Operator for subtraction of vectors
|
||||
NiPoint3 operator-(const NiPoint3& point) const;
|
||||
constexpr NiPoint3 operator-(const NiPoint3& point) const noexcept;
|
||||
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
NiPoint3 operator+(float fScalar) const;
|
||||
constexpr NiPoint3 operator+(const float fScalar) const noexcept;
|
||||
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
NiPoint3 operator-(float fScalar) const;
|
||||
constexpr NiPoint3 operator-(const float fScalar) const noexcept;
|
||||
|
||||
//! Operator for scalar multiplication of a vector
|
||||
NiPoint3 operator*(float fScalar) const;
|
||||
constexpr NiPoint3 operator*(const float fScalar) const noexcept;
|
||||
|
||||
//! Operator for scalar division of a vector
|
||||
NiPoint3 operator/(float fScalar) const;
|
||||
|
||||
constexpr NiPoint3 operator/(const float fScalar) const noexcept;
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
@@ -164,14 +160,14 @@ public:
|
||||
\param maxPoint The maximum point of the bounding box
|
||||
\return Whether or not this point lies within the box
|
||||
*/
|
||||
bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
|
||||
[[nodiscard]] constexpr bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) noexcept;
|
||||
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
/*!
|
||||
\param sphereCenter The sphere center
|
||||
\param radius The radius
|
||||
*/
|
||||
bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
|
||||
[[nodiscard]] constexpr bool IsWithinSphere(const NiPoint3& sphereCenter, const float radius) noexcept;
|
||||
|
||||
/*!
|
||||
\param a Start of line
|
||||
@@ -179,15 +175,30 @@ public:
|
||||
\param p Refrence point
|
||||
\return The point of line AB which is closest to P
|
||||
*/
|
||||
static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
|
||||
[[nodiscard]] static constexpr NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) noexcept;
|
||||
|
||||
static float Angle(const NiPoint3& a, const NiPoint3& b);
|
||||
[[nodiscard]] static float Angle(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
static float Distance(const NiPoint3& a, const NiPoint3& b);
|
||||
[[nodiscard]] static float Distance(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
|
||||
[[nodiscard]] static constexpr float DistanceSquared(const NiPoint3& a, const NiPoint3& b) noexcept;
|
||||
|
||||
static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
|
||||
[[nodiscard]] static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, const float maxDistanceDelta);
|
||||
|
||||
NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
|
||||
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
|
||||
[[nodiscard]] constexpr NiPoint3 RotateByQuaternion(const NiQuaternion& rotation) noexcept;
|
||||
};
|
||||
|
||||
// Static Variables
|
||||
namespace NiPoint3Constant {
|
||||
constexpr NiPoint3 ZERO(0.0f, 0.0f, 0.0f);
|
||||
constexpr NiPoint3 UNIT_X(1.0f, 0.0f, 0.0f);
|
||||
constexpr NiPoint3 UNIT_Y(0.0f, 1.0f, 0.0f);
|
||||
constexpr NiPoint3 UNIT_Z(0.0f, 0.0f, 1.0f);
|
||||
constexpr NiPoint3 UNIT_ALL(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// .inl file needed for code organization and to circumvent circular dependency issues
|
||||
#include "NiPoint3.inl"
|
||||
|
||||
#endif // !__NIPOINT3_H__
|
||||
|
||||
196
dCommon/NiPoint3.inl
Normal file
196
dCommon/NiPoint3.inl
Normal file
@@ -0,0 +1,196 @@
|
||||
#pragma once
|
||||
#ifndef __NIPOINT3_H__
|
||||
#error "This should only be included inline in NiPoint3.h: Do not include directly!"
|
||||
#endif
|
||||
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
// MARK: Getters / Setters
|
||||
|
||||
//! Gets the X coordinate
|
||||
constexpr float NiPoint3::GetX() const noexcept {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
constexpr void NiPoint3::SetX(const float x) noexcept {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
constexpr float NiPoint3::GetY() const noexcept {
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
constexpr void NiPoint3::SetY(const float y) noexcept {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
constexpr float NiPoint3::GetZ() const noexcept {
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
constexpr void NiPoint3::SetZ(const float z) noexcept {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Gets the squared length of a vector
|
||||
constexpr float NiPoint3::SquaredLength() const noexcept {
|
||||
return (x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
constexpr float NiPoint3::DotProduct(const Vector3& vec) const noexcept {
|
||||
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
|
||||
}
|
||||
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
constexpr Vector3 NiPoint3::CrossProduct(const Vector3& vec) const noexcept {
|
||||
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
|
||||
((this->z * vec.x) - (this->x * vec.z)),
|
||||
((this->x * vec.y) - (this->y * vec.x)));
|
||||
}
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
constexpr bool NiPoint3::operator==(const NiPoint3& point) const noexcept {
|
||||
return point.x == this->x && point.y == this->y && point.z == this->z;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
constexpr bool NiPoint3::operator!=(const NiPoint3& point) const noexcept {
|
||||
return !(*this == point);
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
constexpr float& NiPoint3::operator[](const int i) noexcept {
|
||||
float* base = &x;
|
||||
return base[i];
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
constexpr const float& NiPoint3::operator[](const int i) const noexcept {
|
||||
const float* base = &x;
|
||||
return base[i];
|
||||
}
|
||||
|
||||
//! Operator for addition of vectors
|
||||
constexpr NiPoint3 NiPoint3::operator+(const NiPoint3& point) const noexcept {
|
||||
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
|
||||
}
|
||||
|
||||
//! Operator for addition of vectors
|
||||
constexpr NiPoint3& NiPoint3::operator+=(const NiPoint3& point) noexcept {
|
||||
this->x += point.x;
|
||||
this->y += point.y;
|
||||
this->z += point.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr NiPoint3& NiPoint3::operator*=(const float scalar) noexcept {
|
||||
this->x *= scalar;
|
||||
this->y *= scalar;
|
||||
this->z *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Operator for subtraction of vectors
|
||||
constexpr NiPoint3 NiPoint3::operator-(const NiPoint3& point) const noexcept {
|
||||
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
|
||||
}
|
||||
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
constexpr NiPoint3 NiPoint3::operator+(const float fScalar) const noexcept {
|
||||
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
|
||||
}
|
||||
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
constexpr NiPoint3 NiPoint3::operator-(const float fScalar) const noexcept {
|
||||
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar multiplication of a vector
|
||||
constexpr NiPoint3 NiPoint3::operator*(const float fScalar) const noexcept {
|
||||
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar division of a vector
|
||||
constexpr NiPoint3 NiPoint3::operator/(const float fScalar) const noexcept {
|
||||
float retX = this->x != 0 ? this->x / fScalar : 0;
|
||||
float retY = this->y != 0 ? this->y / fScalar : 0;
|
||||
float retZ = this->z != 0 ? this->z / fScalar : 0;
|
||||
return NiPoint3(retX, retY, retZ);
|
||||
}
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
|
||||
constexpr bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) noexcept {
|
||||
if (this->x < minPoint.x) return false;
|
||||
if (this->x > maxPoint.x) return false;
|
||||
if (this->y < minPoint.y) return false;
|
||||
if (this->y > maxPoint.y) return false;
|
||||
|
||||
return (this->z < maxPoint.z && this->z > minPoint.z);
|
||||
}
|
||||
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
constexpr bool NiPoint3::IsWithinSphere(const NiPoint3& sphereCenter, const float radius) noexcept {
|
||||
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
|
||||
return (diffVec.SquaredLength() <= (radius * radius));
|
||||
}
|
||||
|
||||
constexpr NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) noexcept {
|
||||
if (a == b) return a;
|
||||
|
||||
const auto pa = p - a;
|
||||
const auto ab = b - a;
|
||||
|
||||
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
|
||||
|
||||
if (t <= 0.0f) return a;
|
||||
|
||||
if (t >= 1.0f) return b;
|
||||
|
||||
return a + ab * t;
|
||||
}
|
||||
|
||||
constexpr float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) noexcept {
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
|
||||
constexpr NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) noexcept {
|
||||
Vector3 vector;
|
||||
float num12 = rotation.x + rotation.x;
|
||||
float num2 = rotation.y + rotation.y;
|
||||
float num = rotation.z + rotation.z;
|
||||
float num11 = rotation.w * num12;
|
||||
float num10 = rotation.w * num2;
|
||||
float num9 = rotation.w * num;
|
||||
float num8 = rotation.x * num12;
|
||||
float num7 = rotation.x * num2;
|
||||
float num6 = rotation.x * num;
|
||||
float num5 = rotation.y * num2;
|
||||
float num4 = rotation.y * num;
|
||||
float num3 = rotation.z * num;
|
||||
|
||||
NiPoint3 value = *this;
|
||||
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
|
||||
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
|
||||
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
|
||||
vector.x = num15;
|
||||
vector.y = num14;
|
||||
vector.z = num13;
|
||||
return vector;
|
||||
}
|
||||
@@ -3,89 +3,8 @@
|
||||
// C++
|
||||
#include <cmath>
|
||||
|
||||
// Static Variables
|
||||
const NiQuaternion NiQuaternion::IDENTITY(1, 0, 0, 0);
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion::NiQuaternion(void) {
|
||||
this->w = 1;
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion::NiQuaternion(float w, float x, float y, float z) {
|
||||
this->w = w;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
NiQuaternion::~NiQuaternion(void) {}
|
||||
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
float NiQuaternion::GetW(void) const {
|
||||
return this->w;
|
||||
}
|
||||
|
||||
//! Sets the W coordinate
|
||||
void NiQuaternion::SetW(float w) {
|
||||
this->w = w;
|
||||
}
|
||||
|
||||
//! Gets the X coordinate
|
||||
float NiQuaternion::GetX(void) const {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
void NiQuaternion::SetX(float x) {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
float NiQuaternion::GetY(void) const {
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
void NiQuaternion::SetY(float y) {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
float NiQuaternion::GetZ(void) const {
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
void NiQuaternion::SetZ(float z) {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
Vector3 NiQuaternion::GetForwardVector(void) const {
|
||||
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
|
||||
}
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
Vector3 NiQuaternion::GetUpVector(void) const {
|
||||
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
|
||||
}
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
Vector3 NiQuaternion::GetRightVector(void) const {
|
||||
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
|
||||
}
|
||||
|
||||
Vector3 NiQuaternion::GetEulerAngles() const {
|
||||
Vector3 angles;
|
||||
|
||||
@@ -111,22 +30,9 @@ Vector3 NiQuaternion::GetEulerAngles() const {
|
||||
return angles;
|
||||
}
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool NiQuaternion::operator==(const NiQuaternion& rot) const {
|
||||
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool NiQuaternion::operator!=(const NiQuaternion& rot) const {
|
||||
return !(*this == rot);
|
||||
}
|
||||
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
//To make sure we don't orient around the X/Z axis:
|
||||
NiPoint3 source = sourcePoint;
|
||||
@@ -136,7 +42,7 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
|
||||
|
||||
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 posZ = NiPoint3Constant::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
@@ -148,10 +54,11 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 posZ = NiPoint3Constant::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef __NIQUATERNION_H__
|
||||
#define __NIQUATERNION_H__
|
||||
|
||||
// Custom Classes
|
||||
#include "NiPoint3.h"
|
||||
@@ -14,14 +15,14 @@ typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version o
|
||||
//! A class that defines a rotation in space
|
||||
class NiQuaternion {
|
||||
public:
|
||||
float w; //!< The w coordinate
|
||||
float x; //!< The x coordinate
|
||||
float y; //!< The y coordinate
|
||||
float z; //!< The z coordinate
|
||||
float w{ 1 }; //!< The w coordinate
|
||||
float x{ 0 }; //!< The x coordinate
|
||||
float y{ 0 }; //!< The y coordinate
|
||||
float z{ 0 }; //!< The z coordinate
|
||||
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion(void);
|
||||
constexpr NiQuaternion() = default;
|
||||
|
||||
//! The initializer
|
||||
/*!
|
||||
@@ -30,13 +31,12 @@ public:
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiQuaternion(float w, float x, float y, float z);
|
||||
|
||||
//! Destructor
|
||||
~NiQuaternion(void);
|
||||
|
||||
// MARK: Constants
|
||||
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
|
||||
constexpr NiQuaternion(const float w, const float x, const float y, const float z) noexcept
|
||||
: w{ w }
|
||||
, x{ x }
|
||||
, y{ y }
|
||||
, z{ z } {
|
||||
}
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
@@ -44,50 +44,49 @@ public:
|
||||
/*!
|
||||
\return The w coordinate
|
||||
*/
|
||||
float GetW(void) const;
|
||||
[[nodiscard]] constexpr float GetW() const noexcept;
|
||||
|
||||
//! Sets the W coordinate
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
*/
|
||||
void SetW(float w);
|
||||
constexpr void SetW(const float w) noexcept;
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
[[nodiscard]] constexpr float GetX() const noexcept;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
constexpr void SetX(const float x) noexcept;
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
[[nodiscard]] constexpr float GetY() const noexcept;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
constexpr void SetY(const float y) noexcept;
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
[[nodiscard]] constexpr float GetZ() const noexcept;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
|
||||
constexpr void SetZ(const float z) noexcept;
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
@@ -95,31 +94,29 @@ public:
|
||||
/*!
|
||||
\return The forward vector of the quaternion
|
||||
*/
|
||||
Vector3 GetForwardVector(void) const;
|
||||
[[nodiscard]] constexpr Vector3 GetForwardVector() const noexcept;
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
/*!
|
||||
\return The up vector fo the quaternion
|
||||
*/
|
||||
Vector3 GetUpVector(void) const;
|
||||
[[nodiscard]] constexpr Vector3 GetUpVector() const noexcept;
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
/*!
|
||||
\return The right vector of the quaternion
|
||||
*/
|
||||
Vector3 GetRightVector(void) const;
|
||||
|
||||
Vector3 GetEulerAngles() const;
|
||||
[[nodiscard]] constexpr Vector3 GetRightVector() const noexcept;
|
||||
|
||||
[[nodiscard]] Vector3 GetEulerAngles() const;
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiQuaternion& rot) const;
|
||||
constexpr bool operator==(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiQuaternion& rot) const;
|
||||
|
||||
constexpr bool operator!=(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
@@ -129,7 +126,7 @@ public:
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
[[nodiscard]] static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
/*!
|
||||
@@ -137,7 +134,7 @@ public:
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
[[nodiscard]] static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
/*!
|
||||
@@ -145,7 +142,17 @@ public:
|
||||
\param angle The angle relative to this axis
|
||||
\return A quaternion created from the axis and angle
|
||||
*/
|
||||
static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
|
||||
[[nodiscard]] static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
|
||||
|
||||
static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
[[nodiscard]] static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
};
|
||||
|
||||
// Static Variables
|
||||
namespace NiQuaternionConstant {
|
||||
constexpr NiQuaternion IDENTITY(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Include constexpr and inline function definitions in a seperate file for readability
|
||||
#include "NiQuaternion.inl"
|
||||
|
||||
#endif // !__NIQUATERNION_H__
|
||||
|
||||
75
dCommon/NiQuaternion.inl
Normal file
75
dCommon/NiQuaternion.inl
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef __NIQUATERNION_H__
|
||||
#error "This should only be included inline in NiQuaternion.h: Do not include directly!"
|
||||
#endif
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
constexpr float NiQuaternion::GetW() const noexcept {
|
||||
return this->w;
|
||||
}
|
||||
|
||||
//! Sets the W coordinate
|
||||
constexpr void NiQuaternion::SetW(const float w) noexcept {
|
||||
this->w = w;
|
||||
}
|
||||
|
||||
//! Gets the X coordinate
|
||||
constexpr float NiQuaternion::GetX() const noexcept {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
constexpr void NiQuaternion::SetX(const float x) noexcept {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
constexpr float NiQuaternion::GetY() const noexcept {
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
constexpr void NiQuaternion::SetY(const float y) noexcept {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
constexpr float NiQuaternion::GetZ() const noexcept {
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
constexpr void NiQuaternion::SetZ(const float z) noexcept {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetForwardVector() const noexcept {
|
||||
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
|
||||
}
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetUpVector() const noexcept {
|
||||
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
|
||||
}
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetRightVector() const noexcept {
|
||||
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
|
||||
}
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
constexpr bool NiQuaternion::operator==(const NiQuaternion& rot) const noexcept {
|
||||
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
constexpr bool NiQuaternion::operator!=(const NiQuaternion& rot) const noexcept {
|
||||
return !(*this == rot);
|
||||
}
|
||||
50
dCommon/PositionUpdate.h
Normal file
50
dCommon/PositionUpdate.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef __POSITIONUPDATE__H__
|
||||
#define __POSITIONUPDATE__H__
|
||||
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
|
||||
struct RemoteInputInfo {
|
||||
RemoteInputInfo() {
|
||||
m_RemoteInputX = 0;
|
||||
m_RemoteInputY = 0;
|
||||
m_IsPowersliding = false;
|
||||
m_IsModified = false;
|
||||
}
|
||||
|
||||
void operator=(const RemoteInputInfo& other) {
|
||||
m_RemoteInputX = other.m_RemoteInputX;
|
||||
m_RemoteInputY = other.m_RemoteInputY;
|
||||
m_IsPowersliding = other.m_IsPowersliding;
|
||||
m_IsModified = other.m_IsModified;
|
||||
}
|
||||
|
||||
bool operator==(const RemoteInputInfo& other) {
|
||||
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
|
||||
}
|
||||
|
||||
float m_RemoteInputX;
|
||||
float m_RemoteInputY;
|
||||
bool m_IsPowersliding;
|
||||
bool m_IsModified;
|
||||
};
|
||||
|
||||
struct LocalSpaceInfo {
|
||||
LWOOBJID objectId = LWOOBJID_EMPTY;
|
||||
NiPoint3 position = NiPoint3Constant::ZERO;
|
||||
NiPoint3 linearVelocity = NiPoint3Constant::ZERO;
|
||||
};
|
||||
|
||||
struct PositionUpdate {
|
||||
NiPoint3 position = NiPoint3Constant::ZERO;
|
||||
NiQuaternion rotation = NiQuaternionConstant::IDENTITY;
|
||||
bool onGround = false;
|
||||
bool onRail = false;
|
||||
NiPoint3 velocity = NiPoint3Constant::ZERO;
|
||||
NiPoint3 angularVelocity = NiPoint3Constant::ZERO;
|
||||
LocalSpaceInfo localSpaceInfo;
|
||||
RemoteInputInfo remoteInputInfo;
|
||||
};
|
||||
|
||||
#endif //!__POSITIONUPDATE__H__
|
||||
@@ -1,154 +0,0 @@
|
||||
// Source: http://www.zedwood.com/article/cpp-sha512-function
|
||||
|
||||
#include "SHA512.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
|
||||
const unsigned long long SHA512::sha512_k[80] = //ULL = uint64
|
||||
{ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
|
||||
|
||||
void SHA512::transform(const unsigned char* message, unsigned int block_nb) {
|
||||
uint64 w[80];
|
||||
uint64 wv[8];
|
||||
uint64 t1, t2;
|
||||
const unsigned char* sub_block;
|
||||
int i, j;
|
||||
for (i = 0; i < (int)block_nb; i++) {
|
||||
sub_block = message + (i << 7);
|
||||
for (j = 0; j < 16; j++) {
|
||||
SHA2_PACK64(&sub_block[j << 3], &w[j]);
|
||||
}
|
||||
for (j = 16; j < 80; j++) {
|
||||
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
wv[j] = m_h[j];
|
||||
}
|
||||
for (j = 0; j < 80; j++) {
|
||||
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
|
||||
+ sha512_k[j] + w[j];
|
||||
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
m_h[j] += wv[j];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512::init() {
|
||||
m_h[0] = 0x6a09e667f3bcc908ULL;
|
||||
m_h[1] = 0xbb67ae8584caa73bULL;
|
||||
m_h[2] = 0x3c6ef372fe94f82bULL;
|
||||
m_h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||
m_h[4] = 0x510e527fade682d1ULL;
|
||||
m_h[5] = 0x9b05688c2b3e6c1fULL;
|
||||
m_h[6] = 0x1f83d9abfb41bd6bULL;
|
||||
m_h[7] = 0x5be0cd19137e2179ULL;
|
||||
m_len = 0;
|
||||
m_tot_len = 0;
|
||||
}
|
||||
|
||||
void SHA512::update(const unsigned char* message, unsigned int len) {
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char* shifted_message;
|
||||
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
|
||||
rem_len = len < tmp_len ? len : tmp_len;
|
||||
memcpy(&m_block[m_len], message, rem_len);
|
||||
if (m_len + len < SHA384_512_BLOCK_SIZE) {
|
||||
m_len += len;
|
||||
return;
|
||||
}
|
||||
new_len = len - rem_len;
|
||||
block_nb = new_len / SHA384_512_BLOCK_SIZE;
|
||||
shifted_message = message + rem_len;
|
||||
transform(m_block, 1);
|
||||
transform(shifted_message, block_nb);
|
||||
rem_len = new_len % SHA384_512_BLOCK_SIZE;
|
||||
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
|
||||
m_len = rem_len;
|
||||
m_tot_len += (block_nb + 1) << 7;
|
||||
}
|
||||
|
||||
void SHA512::final(unsigned char* digest) {
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
unsigned int len_b;
|
||||
int i;
|
||||
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
|
||||
< (m_len % SHA384_512_BLOCK_SIZE));
|
||||
len_b = (m_tot_len + m_len) << 3;
|
||||
pm_len = block_nb << 7;
|
||||
memset(m_block + m_len, 0, pm_len - m_len);
|
||||
m_block[m_len] = 0x80;
|
||||
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
|
||||
transform(m_block, block_nb);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
|
||||
}
|
||||
}
|
||||
|
||||
std::string sha512(std::string input) {
|
||||
unsigned char digest[SHA512::DIGEST_SIZE];
|
||||
memset(digest, 0, SHA512::DIGEST_SIZE);
|
||||
class SHA512 ctx;
|
||||
ctx.init();
|
||||
ctx.update((unsigned char*)input.c_str(), input.length());
|
||||
ctx.final(digest);
|
||||
|
||||
char buf[2 * SHA512::DIGEST_SIZE + 1];
|
||||
buf[2 * SHA512::DIGEST_SIZE] = 0;
|
||||
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// C++
|
||||
#include <string>
|
||||
|
||||
class SHA512 {
|
||||
protected:
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
const static uint64 sha512_k[];
|
||||
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update(const unsigned char* message, unsigned int len);
|
||||
void final(unsigned char* digest);
|
||||
static const unsigned int DIGEST_SIZE = (512 / 8);
|
||||
|
||||
protected:
|
||||
void transform(const unsigned char* message, unsigned int block_nb);
|
||||
unsigned int m_tot_len;
|
||||
unsigned int m_len;
|
||||
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
|
||||
uint64 m_h[8];
|
||||
};
|
||||
|
||||
std::string sha512(std::string input);
|
||||
|
||||
#define SHA2_SHFR(x, n) (x >> n)
|
||||
#define SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
|
||||
#define SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
|
||||
#define SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
|
||||
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
|
||||
#define SHA512_F1(x) (SHA2_ROTR(x, 28) ^ SHA2_ROTR(x, 34) ^ SHA2_ROTR(x, 39))
|
||||
#define SHA512_F2(x) (SHA2_ROTR(x, 14) ^ SHA2_ROTR(x, 18) ^ SHA2_ROTR(x, 41))
|
||||
#define SHA512_F3(x) (SHA2_ROTR(x, 1) ^ SHA2_ROTR(x, 8) ^ SHA2_SHFR(x, 7))
|
||||
#define SHA512_F4(x) (SHA2_ROTR(x, 19) ^ SHA2_ROTR(x, 61) ^ SHA2_SHFR(x, 6))
|
||||
#define SHA2_UNPACK32(x, str) \
|
||||
{ \
|
||||
*((str) + 3) = (uint8) ((x) ); \
|
||||
*((str) + 2) = (uint8) ((x) >> 8); \
|
||||
*((str) + 1) = (uint8) ((x) >> 16); \
|
||||
*((str) + 0) = (uint8) ((x) >> 24); \
|
||||
}
|
||||
#define SHA2_UNPACK64(x, str) \
|
||||
{ \
|
||||
*((str) + 7) = (uint8) ((x) ); \
|
||||
*((str) + 6) = (uint8) ((x) >> 8); \
|
||||
*((str) + 5) = (uint8) ((x) >> 16); \
|
||||
*((str) + 4) = (uint8) ((x) >> 24); \
|
||||
*((str) + 3) = (uint8) ((x) >> 32); \
|
||||
*((str) + 2) = (uint8) ((x) >> 40); \
|
||||
*((str) + 1) = (uint8) ((x) >> 48); \
|
||||
*((str) + 0) = (uint8) ((x) >> 56); \
|
||||
}
|
||||
#define SHA2_PACK64(str, x) \
|
||||
{ \
|
||||
*(x) = ((uint64) *((str) + 7) ) \
|
||||
| ((uint64) *((str) + 6) << 8) \
|
||||
| ((uint64) *((str) + 5) << 16) \
|
||||
| ((uint64) *((str) + 4) << 24) \
|
||||
| ((uint64) *((str) + 3) << 32) \
|
||||
| ((uint64) *((str) + 2) << 40) \
|
||||
| ((uint64) *((str) + 1) << 48) \
|
||||
| ((uint64) *((str) + 0) << 56); \
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
set(DCOMMON_DCLIENT_SOURCES
|
||||
"AssetManager.cpp"
|
||||
"PackIndex.cpp"
|
||||
"Pack.cpp"
|
||||
"AssetManager.cpp"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
12
dCommon/dClient/ClientVersion.h
Normal file
12
dCommon/dClient/ClientVersion.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __CLIENTVERSION_H__
|
||||
#define __CLIENTVERSION_H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ClientVersion {
|
||||
constexpr uint16_t major = 1;
|
||||
constexpr uint16_t current = 10;
|
||||
constexpr uint16_t minor = 64;
|
||||
}
|
||||
|
||||
#endif // !__CLIENTVERSION_H__
|
||||
@@ -9,15 +9,15 @@ namespace StringifiedEnum {
|
||||
const std::string_view ToString(const T e) {
|
||||
static_assert(std::is_enum_v<T>, "Not an enum"); // Check type
|
||||
|
||||
constexpr auto sv = &magic_enum::enum_entries<T>();
|
||||
constexpr auto& sv = magic_enum::enum_entries<T>();
|
||||
|
||||
const auto it = std::lower_bound(
|
||||
sv->begin(), sv->end(), e,
|
||||
sv.begin(), sv.end(), e,
|
||||
[&](const std::pair<T, std::string_view>& lhs, const T rhs) { return lhs.first < rhs; }
|
||||
);
|
||||
|
||||
std::string_view output;
|
||||
if (it != sv->end() && it->first == e) {
|
||||
if (it != sv.end() && it->first == e) {
|
||||
output = it->second;
|
||||
} else {
|
||||
output = "UNKNOWN";
|
||||
|
||||
@@ -39,86 +39,84 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
|
||||
|
||||
//=========== TYPEDEFS ==========
|
||||
|
||||
typedef int32_t LOT; //!< A LOT
|
||||
typedef int64_t LWOOBJID; //!< An object ID (should be unsigned actually but ok)
|
||||
typedef int32_t TSkillID; //!< A skill ID
|
||||
typedef uint32_t LWOCLONEID; //!< Used for Clone IDs
|
||||
typedef uint16_t LWOMAPID; //!< Used for Map IDs
|
||||
typedef uint16_t LWOINSTANCEID; //!< Used for Instance IDs
|
||||
typedef uint32_t PROPERTYCLONELIST; //!< Used for Property Clone IDs
|
||||
typedef uint32_t StripId;
|
||||
using LOT = int32_t; //!< A LOT
|
||||
using LWOOBJID = int64_t; //!< An object ID (should be unsigned actually but ok)
|
||||
using TSkillID = int32_t; //!< A skill ID
|
||||
using LWOCLONEID = uint32_t; //!< Used for Clone IDs
|
||||
using LWOMAPID = uint16_t; //!< Used for Map IDs
|
||||
using LWOINSTANCEID = uint16_t; //!< Used for Instance IDs
|
||||
using PROPERTYCLONELIST = uint32_t; //!< Used for Property Clone IDs
|
||||
using StripId = uint32_t;
|
||||
|
||||
const LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
|
||||
const LOT LOT_NULL = -1; //!< A null LOT
|
||||
const int32_t LOOTTYPE_NONE = 0; //!< No loot type available
|
||||
const float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
|
||||
const uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
|
||||
const uint32_t LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
|
||||
const uint16_t LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
|
||||
const uint16_t LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
|
||||
const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
|
||||
constexpr LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
|
||||
constexpr LOT LOT_NULL = -1; //!< A null LOT
|
||||
constexpr int32_t LOOTTYPE_NONE = 0; //!< No loot type available
|
||||
constexpr float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
|
||||
constexpr uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
|
||||
constexpr LWOCLONEID LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
|
||||
constexpr LWOINSTANCEID LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
|
||||
constexpr LWOMAPID LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
|
||||
constexpr uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
|
||||
|
||||
const float PI = 3.14159f;
|
||||
constexpr float PI = 3.14159f;
|
||||
|
||||
//============ STRUCTS ==============
|
||||
|
||||
struct LWOSCENEID {
|
||||
public:
|
||||
LWOSCENEID() { m_sceneID = -1; m_layerID = 0; }
|
||||
LWOSCENEID(int sceneID) { m_sceneID = sceneID; m_layerID = 0; }
|
||||
LWOSCENEID(int sceneID, unsigned int layerID) { m_sceneID = sceneID; m_layerID = layerID; }
|
||||
constexpr LWOSCENEID() noexcept { m_sceneID = -1; m_layerID = 0; }
|
||||
constexpr LWOSCENEID(int32_t sceneID) noexcept { m_sceneID = sceneID; m_layerID = 0; }
|
||||
constexpr LWOSCENEID(int32_t sceneID, uint32_t layerID) noexcept { m_sceneID = sceneID; m_layerID = layerID; }
|
||||
|
||||
LWOSCENEID& operator=(const LWOSCENEID& rhs) { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
|
||||
LWOSCENEID& operator=(const int rhs) { m_sceneID = rhs; m_layerID = 0; return *this; }
|
||||
constexpr LWOSCENEID& operator=(const LWOSCENEID& rhs) noexcept { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
|
||||
constexpr LWOSCENEID& operator=(const int32_t rhs) noexcept { m_sceneID = rhs; m_layerID = 0; return *this; }
|
||||
|
||||
bool operator<(const LWOSCENEID& rhs) const { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
|
||||
bool operator<(const int rhs) const { return m_sceneID < rhs; }
|
||||
constexpr bool operator<(const LWOSCENEID& rhs) const noexcept { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
|
||||
constexpr bool operator<(const int32_t rhs) const noexcept { return m_sceneID < rhs; }
|
||||
|
||||
bool operator==(const LWOSCENEID& rhs) const { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
|
||||
bool operator==(const int rhs) const { return m_sceneID == rhs; }
|
||||
constexpr bool operator==(const LWOSCENEID& rhs) const noexcept { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
|
||||
constexpr bool operator==(const int32_t rhs) const noexcept { return m_sceneID == rhs; }
|
||||
|
||||
const int GetSceneID() const { return m_sceneID; }
|
||||
const unsigned int GetLayerID() const { return m_layerID; }
|
||||
constexpr int32_t GetSceneID() const noexcept { return m_sceneID; }
|
||||
constexpr uint32_t GetLayerID() const noexcept { return m_layerID; }
|
||||
|
||||
void SetSceneID(const int sceneID) { m_sceneID = sceneID; }
|
||||
void SetLayerID(const unsigned int layerID) { m_layerID = layerID; }
|
||||
constexpr void SetSceneID(const int32_t sceneID) noexcept { m_sceneID = sceneID; }
|
||||
constexpr void SetLayerID(const uint32_t layerID) noexcept { m_layerID = layerID; }
|
||||
|
||||
private:
|
||||
int m_sceneID;
|
||||
unsigned int m_layerID;
|
||||
int32_t m_sceneID;
|
||||
uint32_t m_layerID;
|
||||
};
|
||||
|
||||
struct LWOZONEID {
|
||||
public:
|
||||
const LWOMAPID& GetMapID() const { return m_MapID; }
|
||||
const LWOINSTANCEID& GetInstanceID() const { return m_InstanceID; }
|
||||
const LWOCLONEID& GetCloneID() const { return m_CloneID; }
|
||||
constexpr const LWOMAPID& GetMapID() const noexcept { return m_MapID; }
|
||||
constexpr const LWOINSTANCEID& GetInstanceID() const noexcept { return m_InstanceID; }
|
||||
constexpr const LWOCLONEID& GetCloneID() const noexcept { return m_CloneID; }
|
||||
|
||||
//In order: def constr, constr, assign op
|
||||
LWOZONEID() { m_MapID = LWOMAPID_INVALID; m_InstanceID = LWOINSTANCEID_INVALID; m_CloneID = LWOCLONEID_INVALID; }
|
||||
LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
|
||||
LWOZONEID(const LWOZONEID& replacement) { *this = replacement; }
|
||||
constexpr LWOZONEID() noexcept = default;
|
||||
constexpr LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) noexcept { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
|
||||
constexpr LWOZONEID(const LWOZONEID& replacement) noexcept { *this = replacement; }
|
||||
|
||||
private:
|
||||
LWOMAPID m_MapID; //1000 for VE, 1100 for AG, etc...
|
||||
LWOINSTANCEID m_InstanceID; //Instances host the same world, but on a different dWorld process.
|
||||
LWOCLONEID m_CloneID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
|
||||
LWOMAPID m_MapID = LWOMAPID_INVALID; //1000 for VE, 1100 for AG, etc...
|
||||
LWOINSTANCEID m_InstanceID = LWOINSTANCEID_INVALID; //Instances host the same world, but on a different dWorld process.
|
||||
LWOCLONEID m_CloneID = LWOCLONEID_INVALID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
|
||||
};
|
||||
|
||||
const LWOSCENEID LWOSCENEID_INVALID = -1;
|
||||
constexpr LWOSCENEID LWOSCENEID_INVALID = -1;
|
||||
|
||||
struct LWONameValue {
|
||||
uint32_t length = 0; //!< The length of the name
|
||||
std::u16string name; //!< The name
|
||||
|
||||
LWONameValue(void) {}
|
||||
LWONameValue() = default;
|
||||
|
||||
LWONameValue(const std::u16string& name) {
|
||||
this->name = name;
|
||||
this->length = static_cast<uint32_t>(name.length());
|
||||
}
|
||||
|
||||
~LWONameValue(void) {}
|
||||
};
|
||||
|
||||
struct FriendData {
|
||||
|
||||
@@ -629,7 +629,7 @@ enum class eGameMessageType : uint16_t {
|
||||
GET_INSTRUCTION_COUNT = 676,
|
||||
GET_IS_NPC = 677,
|
||||
ACTIVATE_BUBBLE_BUFF = 678,
|
||||
DECTIVATE_BUBBLE_BUFF = 679, // thanks netdevil
|
||||
DECTIVATE_BUBBLE_BUFF = 679, // This is spelled wrong in the client, so we misspell it here.
|
||||
EXHIBIT_VOTE = 680,
|
||||
ADD_PET_TO_PLAYER = 681,
|
||||
REMOVE_PET_FROM_PLAYER = 682,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef __EPETABILITYTYPE__H__
|
||||
#define __EPETABILITYTYPE__H__
|
||||
|
||||
enum class ePetAbilityType : int32_t {
|
||||
#include <cstdint>
|
||||
|
||||
enum class ePetAbilityType : uint32_t {
|
||||
Invalid,
|
||||
GoToObject,
|
||||
JumpOnObject,
|
||||
|
||||
Reference in New Issue
Block a user