Compare commits

..

2 Commits

Author SHA1 Message Date
David Markowitz
186a5027ec Merge branch 'main' into md5-out-of-common 2024-02-08 03:55:22 -08:00
David Markowitz
19103a7e0e remove sha512, move md5 to thirdparty
title.

Tested that Auth runs and I can login still.
2024-02-02 21:16:20 -08:00
209 changed files with 1893 additions and 1709 deletions

View File

@@ -82,11 +82,11 @@ int main(int argc, char** argv) {
Game::randomEngine = std::mt19937(time(0));
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
std::string ourIP = "localhost";
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
//LU client is hardcoded to use this for auth port, so I'm making it the default.
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("auth_server_port")).value_or(1001);
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;

View File

@@ -99,15 +99,18 @@ int main(int argc, char** argv) {
masterPort = masterInfo->port;
}
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 999;
uint32_t ourPort = 1501;
std::string ourIP = "localhost";
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("chat_server_port")).value_or(1501);
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
GeneralUtils::TryParse(Game::config->GetValue("chat_server_port"), ourPort);
const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString;
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
bool dontGenerateDCF = false;
GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
Game::randomEngine = std::mt19937(time(0));

View File

@@ -10,14 +10,21 @@
#include "Database.h"
#include "eConnectionType.h"
#include "eChatInternalMessageType.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h"
#include "dConfig.h"
void PlayerContainer::Initialize() {
m_MaxNumberOfBestFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends")).value_or(m_MaxNumberOfBestFriends);
m_MaxNumberOfFriends =
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends")).value_or(m_MaxNumberOfFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends);
}
PlayerContainer::~PlayerContainer() {
m_Players.clear();
}
PlayerData::PlayerData() {
gmLevel = eGameMasterLevel::CIVILIAN;
}
TeamData::TeamData() {

View File

@@ -10,7 +10,7 @@
enum class eGameMasterLevel : uint8_t;
struct IgnoreData {
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName{ name }, playerId{ id } {}
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName(name), playerId(id) {}
inline bool operator==(const std::string& other) const noexcept {
return playerName == other;
}
@@ -24,6 +24,7 @@ struct IgnoreData {
};
struct PlayerData {
PlayerData();
operator bool() const noexcept {
return playerID != LWOOBJID_EMPTY;
}
@@ -44,7 +45,7 @@ struct PlayerData {
std::string playerName;
std::vector<FriendData> friends;
std::vector<IgnoreData> ignoredPlayers;
eGameMasterLevel gmLevel = static_cast<eGameMasterLevel>(0); // CIVILLIAN
eGameMasterLevel gmLevel;
bool isFTP = false;
};
@@ -60,6 +61,8 @@ struct TeamData {
class PlayerContainer {
public:
~PlayerContainer();
void Initialize();
void InsertPlayer(Packet* packet);
void RemovePlayer(Packet* packet);

View File

@@ -31,68 +31,54 @@ enum class eAmf : uint8_t {
class AMFBaseValue {
public:
[[nodiscard]] constexpr virtual eAmf GetValueType() const noexcept { return eAmf::Undefined; }
constexpr AMFBaseValue() noexcept = default;
constexpr virtual ~AMFBaseValue() noexcept = default;
virtual eAmf GetValueType() { return eAmf::Undefined; };
AMFBaseValue() {};
virtual ~AMFBaseValue() {};
};
// AMFValue template class instantiations
template <typename ValueType>
template<typename ValueType>
class AMFValue : public AMFBaseValue {
public:
AMFValue() = default;
AMFValue(const ValueType value) { m_Data = value; }
virtual ~AMFValue() override = default;
AMFValue() {};
AMFValue(ValueType value) { SetValue(value); };
virtual ~AMFValue() override {};
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override;
[[nodiscard]] const ValueType& GetValue() const { return m_Data; }
void SetValue(const ValueType value) { m_Data = value; }
eAmf GetValueType() override { return eAmf::Undefined; };
const ValueType& GetValue() { return data; };
void SetValue(ValueType value) { data = value; };
protected:
ValueType m_Data;
ValueType 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() = default;
AMFValue(const char* value) { m_Data = value; }
virtual ~AMFValue() override = default;
AMFValue() {};
AMFValue(const char* value) { SetValue(std::string(value)); };
virtual ~AMFValue() override {};
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::String; }
eAmf GetValueType() override { return eAmf::String; };
[[nodiscard]] const std::string& GetValue() const { return m_Data; }
void SetValue(const std::string& value) { m_Data = value; }
const std::string& GetValue() { return data; };
void SetValue(std::string value) { data = value; };
protected:
std::string m_Data;
std::string data;
};
using AMFNullValue = AMFValue<std::nullptr_t>;
using AMFBoolValue = AMFValue<bool>;
using AMFIntValue = AMFValue<int32_t>;
using AMFStringValue = AMFValue<std::string>;
using AMFDoubleValue = AMFValue<double>;
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; };
/**
* The AMFArrayValue object holds 2 types of lists:
@@ -103,11 +89,12 @@ using AMFDoubleValue = AMFValue<double>;
* and are not to be deleted by a caller.
*/
class AMFArrayValue : public AMFBaseValue {
using AMFAssociative = std::unordered_map<std::string, AMFBaseValue*>;
using AMFDense = std::vector<AMFBaseValue*>;
typedef std::unordered_map<std::string, AMFBaseValue*> AMFAssociative;
typedef std::vector<AMFBaseValue*> AMFDense;
public:
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; }
eAmf GetValueType() override { return eAmf::Array; };
~AMFArrayValue() override {
for (auto valueToDelete : GetDense()) {
@@ -122,17 +109,17 @@ public:
valueToDelete.second = nullptr;
}
}
}
};
/**
* Returns the Associative portion of the object
*/
[[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return this->associative; }
inline AMFAssociative& GetAssociative() { return this->associative; };
/**
* Returns the dense portion of the object
*/
[[nodiscard]] inline const AMFDense& GetDense() const noexcept { return this->dense; }
inline AMFDense& GetDense() { return this->dense; };
/**
* Inserts an AMFValue into the associative portion with the given key.
@@ -148,8 +135,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>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, const ValueType value) {
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, ValueType value) {
auto element = associative.find(key);
AMFValue<ValueType>* val = nullptr;
bool found = true;
@@ -161,10 +148,10 @@ public:
found = false;
}
return std::make_pair(val, found);
}
};
// Associates an array with a string key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
auto element = associative.find(key);
AMFArrayValue* val = nullptr;
bool found = true;
@@ -176,10 +163,10 @@ public:
found = false;
}
return std::make_pair(val, found);
}
};
// Associates an array with an integer key
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) {
std::pair<AMFBaseValue*, bool> Insert(const uint32_t& index) {
AMFArrayValue* val = nullptr;
bool inserted = false;
if (index >= dense.size()) {
@@ -189,7 +176,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.
@@ -201,8 +188,8 @@ public:
* @return The inserted element, or nullptr if the type did not match
* what was at the index.
*/
template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) {
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const uint32_t& index, ValueType value) {
AMFValue<ValueType>* val = nullptr;
bool inserted = false;
if (index >= this->dense.size()) {
@@ -212,7 +199,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.
@@ -223,7 +210,7 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const std::string& key, AMFBaseValue* const value) {
void Insert(const std::string& key, AMFBaseValue* value) {
auto element = associative.find(key);
if (element != associative.end() && element->second) {
delete element->second;
@@ -231,7 +218,7 @@ public:
} else {
associative.insert(std::make_pair(key, value));
}
}
};
/**
* Inserts an AMFValue into the associative portion with the given index.
@@ -242,7 +229,7 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const size_t index, AMFBaseValue* const value) {
void Insert(const uint32_t index, AMFBaseValue* value) {
if (index < dense.size()) {
AMFDense::iterator itr = dense.begin() + index;
if (*itr) delete dense.at(index);
@@ -250,7 +237,7 @@ public:
dense.resize(index + 1);
}
dense.at(index) = value;
}
};
/**
* Pushes an AMFValue into the back of the dense portion.
@@ -262,10 +249,10 @@ public:
*
* @return The inserted pointer, or nullptr should the key already be in use.
*/
template <typename ValueType>
[[maybe_unused]] inline AMFValue<ValueType>* Push(const ValueType value) {
template<typename ValueType>
inline AMFValue<ValueType>* Push(ValueType value) {
return Insert(this->dense.size(), value).first;
}
};
/**
* Removes the key from the associative portion
@@ -274,7 +261,7 @@ public:
*
* @param key The key to remove from the associative portion
*/
void Remove(const std::string& key, const bool deleteValue = true) {
void Remove(const std::string& key, bool deleteValue = true) {
AMFAssociative::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
if (deleteValue) delete it->second;
@@ -285,7 +272,7 @@ public:
/**
* Pops the last element in the dense portion, deleting it in the process.
*/
void Remove(const size_t index) {
void Remove(const uint32_t index) {
if (!this->dense.empty() && index < this->dense.size()) {
auto itr = this->dense.begin() + index;
if (*itr) delete (*itr);
@@ -297,29 +284,29 @@ public:
if (!this->dense.empty()) Remove(this->dense.size() - 1);
}
[[nodiscard]] AMFArrayValue* GetArray(const std::string& key) const {
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;
}
};
[[nodiscard]] AMFArrayValue* GetArray(const size_t index) const {
AMFArrayValue* GetArray(const uint32_t index) {
return index >= this->dense.size() ? nullptr : dynamic_cast<AMFArrayValue*>(this->dense.at(index));
}
};
[[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) {
inline AMFArrayValue* InsertArray(const std::string& key) {
return static_cast<AMFArrayValue*>(Insert(key).first);
}
};
[[maybe_unused]] inline AMFArrayValue* InsertArray(const size_t index) {
inline AMFArrayValue* InsertArray(const uint32_t index) {
return static_cast<AMFArrayValue*>(Insert(index).first);
}
};
[[maybe_unused]] inline AMFArrayValue* PushArray() {
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
@@ -331,18 +318,18 @@ public:
* @return The AMFValue
*/
template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const std::string& key) const {
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
[[nodiscard]] AMFBaseValue* Get(const std::string& key) const {
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.
@@ -354,17 +341,16 @@ public:
* @return The casted object, or nullptr.
*/
template <typename AmfType>
[[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const {
AMFValue<AmfType>* Get(uint32_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
[[nodiscard]] AMFBaseValue* Get(const size_t index) const {
AMFBaseValue* Get(const uint32_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.

View File

@@ -319,3 +319,7 @@ 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);
}

View File

@@ -1,20 +1,17 @@
#pragma once
// C++
#include <charconv>
#include <cstdint>
#include <stdint.h>
#include <random>
#include <ctime>
#include <time.h>
#include <string>
#include <string_view>
#include <optional>
#include <type_traits>
#include <functional>
#include <type_traits>
#include <stdexcept>
#include "BitStream.h"
#include "NiPoint3.h"
#include "dPlatforms.h"
#include "Game.h"
#include "Logger.h"
@@ -126,125 +123,90 @@ namespace GeneralUtils {
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);
// Concept constraining to enum types
template <typename T>
concept Enum = std::is_enum_v<T>;
T Parse(const char* value);
// Concept constraining to numeric types
template <typename T>
concept Numeric = std::integral<T> || Enum<T> || std::floating_point<T>;
// 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>{};
template <>
inline bool Parse(const char* value) {
return std::stoi(value);
}
#ifdef DARKFLAME_PLATFORM_MACOS
template <>
inline int32_t Parse(const char* value) {
return std::stoi(value);
}
// Anonymous namespace containing MacOS floating-point parse function specializations
namespace {
template <std::floating_point T>
[[nodiscard]] T Parse(const std::string_view str, size_t* parseNum);
template <>
inline int64_t Parse(const char* value) {
return std::stoll(value);
}
template <>
[[nodiscard]] float Parse<float>(const std::string_view str, size_t* parseNum) {
return std::stof(std::string{ str }, parseNum);
}
template <>
inline float Parse(const char* value) {
return std::stof(value);
}
template <>
[[nodiscard]] double Parse<double>(const std::string_view str, size_t* parseNum) {
return std::stod(std::string{ str }, parseNum);
}
template <>
inline double Parse(const char* value) {
return std::stod(value);
}
template <>
[[nodiscard]] long double Parse<long double>(const std::string_view str, size_t* parseNum) {
return std::stold(std::string{ str }, parseNum);
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));
}
template <typename T>
bool TryParse(const char* value, T& dst) {
try {
dst = Parse<T>(value);
return true;
} catch (...) {
return false;
}
}
/**
* 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>
[[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;
T Parse(const std::string& value) {
return Parse<T>(value.c_str());
}
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>
constexpr void hash_combine(std::size_t& s, const T& v) {
void hash_combine(std::size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
@@ -277,8 +239,10 @@ namespace GeneralUtils {
* @param entry Enum entry to cast
* @returns The enum entry's value in its underlying type
*/
template <Enum eType>
constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) noexcept {
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");
return static_cast<typename std::underlying_type_t<eType>>(entry);
}

View File

@@ -61,33 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_S32: {
const auto data = GeneralUtils::TryParse<int32_t>(ldfTypeAndValue.second);
if (!data) {
int32_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), 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.value());
returnValue = new LDFData<int32_t>(key, data);
break;
}
case LDF_TYPE_FLOAT: {
const auto data = GeneralUtils::TryParse<float>(ldfTypeAndValue.second);
if (!data) {
float data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), 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.value());
returnValue = new LDFData<float>(key, data);
break;
}
case LDF_TYPE_DOUBLE: {
const auto data = GeneralUtils::TryParse<double>(ldfTypeAndValue.second);
if (!data) {
double data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), 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.value());
returnValue = new LDFData<double>(key, data);
break;
}
@@ -100,12 +100,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = 0;
} else {
const auto dataOptional = GeneralUtils::TryParse<uint32_t>(ldfTypeAndValue.second);
if (!dataOptional) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
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);
@@ -120,12 +118,10 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = false;
} else {
const auto dataOptional = GeneralUtils::TryParse<bool>(ldfTypeAndValue.second);
if (!dataOptional) {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
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);
@@ -133,22 +129,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_U64: {
const auto data = GeneralUtils::TryParse<uint64_t>(ldfTypeAndValue.second);
if (!data) {
uint64_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), 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.value());
returnValue = new LDFData<uint64_t>(key, data);
break;
}
case LDF_TYPE_OBJID: {
const auto data = GeneralUtils::TryParse<LWOOBJID>(ldfTypeAndValue.second);
if (!data) {
LWOOBJID data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), 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.value());
returnValue = new LDFData<LWOOBJID>(key, data);
break;
}

View File

@@ -162,7 +162,7 @@ public:
return new LDFData<T>(key, value);
}
inline static const T Default = {};
inline static T Default = {};
};
// LDF Types

View File

@@ -1,6 +1,6 @@
set(DCOMMON_DCLIENT_SOURCES
"AssetManager.cpp"
"PackIndex.cpp"
"Pack.cpp"
"AssetManager.cpp"
PARENT_SCOPE
)

View File

@@ -1,12 +0,0 @@
#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__

View File

@@ -39,84 +39,86 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
//=========== TYPEDEFS ==========
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;
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;
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 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 float PI = 3.14159f;
const float PI = 3.14159f;
//============ STRUCTS ==============
struct LWOSCENEID {
public:
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() { 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& 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; }
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 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_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; }
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 int32_t GetSceneID() const noexcept { return m_sceneID; }
constexpr uint32_t GetLayerID() const noexcept { return m_layerID; }
const int GetSceneID() const { return m_sceneID; }
const unsigned int GetLayerID() const { return m_layerID; }
constexpr void SetSceneID(const int32_t sceneID) noexcept { m_sceneID = sceneID; }
constexpr void SetLayerID(const uint32_t layerID) noexcept { m_layerID = layerID; }
void SetSceneID(const int sceneID) { m_sceneID = sceneID; }
void SetLayerID(const unsigned int layerID) { m_layerID = layerID; }
private:
int32_t m_sceneID;
uint32_t m_layerID;
int m_sceneID;
unsigned int m_layerID;
};
struct LWOZONEID {
public:
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; }
const LWOMAPID& GetMapID() const { return m_MapID; }
const LWOINSTANCEID& GetInstanceID() const { return m_InstanceID; }
const LWOCLONEID& GetCloneID() const { return m_CloneID; }
//In order: def constr, constr, assign op
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; }
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; }
private:
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.
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.
};
constexpr LWOSCENEID LWOSCENEID_INVALID = -1;
const LWOSCENEID LWOSCENEID_INVALID = -1;
struct LWONameValue {
uint32_t length = 0; //!< The length of the name
std::u16string name; //!< The name
LWONameValue() = default;
LWONameValue(void) {}
LWONameValue(const std::u16string& name) {
this->name = name;
this->length = static_cast<uint32_t>(name.length());
}
~LWONameValue(void) {}
};
struct FriendData {

View File

@@ -39,7 +39,6 @@
#include "CDFeatureGatingTable.h"
#include "CDRailActivatorComponent.h"
#include "CDRewardCodesTable.h"
#include "CDPetComponentTable.h"
#include <exception>
@@ -62,55 +61,6 @@ public:
}
};
// Using a macro to reduce repetitive code and issues from copy and paste.
// As a note, ## in a macro is used to concatenate two tokens together.
#define SPECIALIZE_TABLE_STORAGE(table) \
template<> typename table::StorageType& CDClientManager::GetEntriesMutable<table>() { return table##Entries; };
#define DEFINE_TABLE_STORAGE(table) namespace { table::StorageType table##Entries; }; SPECIALIZE_TABLE_STORAGE(table)
DEFINE_TABLE_STORAGE(CDActivityRewardsTable);
DEFINE_TABLE_STORAGE(CDActivitiesTable);
DEFINE_TABLE_STORAGE(CDAnimationsTable);
DEFINE_TABLE_STORAGE(CDBehaviorParameterTable);
DEFINE_TABLE_STORAGE(CDBehaviorTemplateTable);
DEFINE_TABLE_STORAGE(CDBrickIDTableTable);
DEFINE_TABLE_STORAGE(CDComponentsRegistryTable);
DEFINE_TABLE_STORAGE(CDCurrencyTableTable);
DEFINE_TABLE_STORAGE(CDDestructibleComponentTable);
DEFINE_TABLE_STORAGE(CDEmoteTableTable);
DEFINE_TABLE_STORAGE(CDFeatureGatingTable);
DEFINE_TABLE_STORAGE(CDInventoryComponentTable);
DEFINE_TABLE_STORAGE(CDItemComponentTable);
DEFINE_TABLE_STORAGE(CDItemSetSkillsTable);
DEFINE_TABLE_STORAGE(CDItemSetsTable);
DEFINE_TABLE_STORAGE(CDLevelProgressionLookupTable);
DEFINE_TABLE_STORAGE(CDLootMatrixTable);
DEFINE_TABLE_STORAGE(CDLootTableTable);
DEFINE_TABLE_STORAGE(CDMissionEmailTable);
DEFINE_TABLE_STORAGE(CDMissionNPCComponentTable);
DEFINE_TABLE_STORAGE(CDMissionTasksTable);
DEFINE_TABLE_STORAGE(CDMissionsTable);
DEFINE_TABLE_STORAGE(CDMovementAIComponentTable);
DEFINE_TABLE_STORAGE(CDObjectSkillsTable);
DEFINE_TABLE_STORAGE(CDObjectsTable);
DEFINE_TABLE_STORAGE(CDPhysicsComponentTable);
DEFINE_TABLE_STORAGE(CDPackageComponentTable);
DEFINE_TABLE_STORAGE(CDPetComponentTable);
DEFINE_TABLE_STORAGE(CDProximityMonitorComponentTable);
DEFINE_TABLE_STORAGE(CDPropertyEntranceComponentTable);
DEFINE_TABLE_STORAGE(CDPropertyTemplateTable);
DEFINE_TABLE_STORAGE(CDRailActivatorComponentTable);
DEFINE_TABLE_STORAGE(CDRarityTableTable);
DEFINE_TABLE_STORAGE(CDRebuildComponentTable);
DEFINE_TABLE_STORAGE(CDRewardCodesTable);
DEFINE_TABLE_STORAGE(CDRewardsTable);
DEFINE_TABLE_STORAGE(CDScriptComponentTable);
DEFINE_TABLE_STORAGE(CDSkillBehaviorTable);
DEFINE_TABLE_STORAGE(CDVendorComponentTable);
DEFINE_TABLE_STORAGE(CDZoneTableTable);
void CDClientManager::LoadValuesFromDatabase() {
if (!CDClientDatabase::isConnected) throw CDClientConnectionException();

View File

@@ -1,12 +1,18 @@
#ifndef __CDCLIENTMANAGER__H__
#define __CDCLIENTMANAGER__H__
#pragma once
#include "CDTable.h"
#include "Singleton.h"
#define UNUSED_TABLE(v)
/**
* Initialize the CDClient tables so they are all loaded into memory.
*/
namespace CDClientManager {
class CDClientManager : public Singleton<CDClientManager> {
public:
CDClientManager() = default;
void LoadValuesFromDatabase();
void LoadValuesFromDefaults();
@@ -17,28 +23,7 @@ namespace CDClientManager {
* @return A pointer to the requested table.
*/
template<typename T>
T* GetTable();
/**
* Fetch a table from CDClient
* Note: Calling this function without a template specialization in CDClientManager.cpp will cause a linker error.
*
* @tparam Table type to fetch
* @return A pointer to the requested table.
*/
template<typename T>
typename T::StorageType& GetEntriesMutable();
T* GetTable() {
return &T::Instance();
}
};
// These are included after the CDClientManager namespace declaration as CDTable as of Jan 29 2024 relies on CDClientManager in Templated code.
#include "CDTable.h"
#include "Singleton.h"
template<typename T>
T* CDClientManager::GetTable() {
return &T::Instance();
};
#endif //!__CDCLIENTMANAGER__H__

View File

@@ -1,6 +1,5 @@
#include "CDActivitiesTable.h"
void CDActivitiesTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
@@ -14,8 +13,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities");
@@ -41,7 +39,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1);
entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -50,7 +48,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActivities)> predicate) {
std::vector<CDActivities> data = cpplinq::from(GetEntries())
std::vector<CDActivities> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();

View File

@@ -25,10 +25,15 @@ struct CDActivities {
float optionalPercentage;
};
class CDActivitiesTable : public CDTable<CDActivitiesTable, std::vector<CDActivities>> {
class CDActivitiesTable : public CDTable<CDActivitiesTable> {
private:
std::vector<CDActivities> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDActivities> Query(std::function<bool(CDActivities)> predicate);
const std::vector<CDActivities>& GetEntries() const { return this->entries; }
};

View File

@@ -1,6 +1,5 @@
#include "CDActivityRewardsTable.h"
void CDActivityRewardsTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -15,8 +14,7 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
@@ -30,7 +28,7 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {
entry.ChallengeRating = tableData.getIntField("ChallengeRating", -1);
entry.description = tableData.getStringField("description", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -39,7 +37,7 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {
std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(CDActivityRewards)> predicate) {
std::vector<CDActivityRewards> data = cpplinq::from(GetEntries())
std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();

View File

@@ -13,9 +13,15 @@ struct CDActivityRewards {
std::string description; //!< The description
};
class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable, std::vector<CDActivityRewards>> {
class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable> {
private:
std::vector<CDActivityRewards> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
std::vector<CDActivityRewards> GetEntries() const;
};

View File

@@ -5,7 +5,6 @@
void CDAnimationsTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
auto& animations = GetEntriesMutable();
while (!tableData.eof()) {
std::string animation_type = tableData.getStringField("animation_type", "");
DluAssert(!animation_type.empty());
@@ -25,7 +24,7 @@ void CDAnimationsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
}
@@ -36,7 +35,6 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
auto tableData = queryToCache.execQuery();
// If we received a bad lookup, cache it anyways so we do not run the query again.
if (tableData.eof()) return false;
auto& animations = GetEntriesMutable();
do {
std::string animation_type = tableData.getStringField("animation_type", "");
@@ -57,7 +55,7 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
} while (!tableData.eof());
@@ -70,17 +68,15 @@ void CDAnimationsTable::CacheAnimations(const CDAnimationKey animationKey) {
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ? and animation_type = ?");
query.bind(1, static_cast<int32_t>(animationKey.second));
query.bind(2, animationKey.first.c_str());
auto& animations = GetEntriesMutable();
// If we received a bad lookup, cache it anyways so we do not run the query again.
if (!CacheData(query)) {
animations[animationKey];
this->animations[animationKey];
}
}
void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {
auto& animations = GetEntriesMutable();
auto animationEntryCached = animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != animations.end()) {
auto animationEntryCached = this->animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != this->animations.end()) {
return;
}
@@ -89,29 +85,28 @@ void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {
// Cache the query so we don't run the query again.
CacheData(query);
animations[CDAnimationKey("", animationGroupID)];
this->animations[CDAnimationKey("", animationGroupID)];
}
std::optional<CDAnimation> CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
auto& animations = GetEntriesMutable();
CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
CDAnimationKey animationKey(animationType, animationGroupID);
auto animationEntryCached = animations.find(animationKey);
if (animationEntryCached == animations.end()) {
auto animationEntryCached = this->animations.find(animationKey);
if (animationEntryCached == this->animations.end()) {
this->CacheAnimations(animationKey);
}
auto animationEntry = animations.find(animationKey);
auto animationEntry = this->animations.find(animationKey);
// If we have only one animation, return it regardless of the chance to play.
if (animationEntry->second.size() == 1) {
return animationEntry->second.front();
return CDAnimationLookupResult(animationEntry->second.front());
}
auto randomAnimation = GeneralUtils::GenerateRandomNumber<float>(0, 1);
for (auto& animationEntry : animationEntry->second) {
randomAnimation -= animationEntry.chance_to_play;
// This is how the client gets the random animation.
if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return animationEntry;
if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return CDAnimationLookupResult(animationEntry);
}
return std::nullopt;
return CDAnimationLookupResult();
}

View File

@@ -2,11 +2,6 @@
#include "CDTable.h"
#include <list>
#include <optional>
typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;
struct CDAnimation {
// uint32_t animationGroupID;
@@ -25,7 +20,12 @@ struct CDAnimation {
UNUSED_COLUMN(float blendTime;) //!< The blend time
};
class CDAnimationsTable : public CDTable<CDAnimationsTable, std::map<CDAnimationKey, std::list<CDAnimation>>> {
typedef LookupResult<CDAnimation> CDAnimationLookupResult;
class CDAnimationsTable : public CDTable<CDAnimationsTable> {
typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;
public:
void LoadValuesFromDatabase();
/**
@@ -38,7 +38,7 @@ public:
* @param animationGroupID The animationGroupID to lookup
* @return CDAnimationLookupResult
*/
[[nodiscard]] std::optional<CDAnimation> GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);
[[nodiscard]] CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);
/**
* Cache a full AnimationGroup by its ID.
@@ -58,4 +58,10 @@ private:
* @return false
*/
bool CacheData(CppSQLite3Statement& queryToCache);
/**
* Each animation is key'd by its animationName and its animationGroupID. Each
* animation has a possible list of animations. This is because there can be animations have a percent chance to play so one is selected at random.
*/
std::map<CDAnimationKey, std::list<CDAnimation>> animations;
};

View File

@@ -1,10 +1,6 @@
#include "CDBehaviorParameterTable.h"
#include "GeneralUtils.h"
namespace {
std::unordered_map<std::string, uint32_t> m_ParametersList;
};
uint64_t GetKey(const uint32_t behaviorID, const uint32_t parameterID) {
uint64_t key = behaviorID;
key <<= 31U;
@@ -15,7 +11,6 @@ uint64_t GetKey(const uint32_t behaviorID, const uint32_t parameterID) {
void CDBehaviorParameterTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
uint32_t behaviorID = tableData.getIntField("behaviorID", -1);
auto candidateStringToAdd = std::string(tableData.getStringField("parameterID", ""));
@@ -29,7 +24,7 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
uint64_t hash = GetKey(behaviorID, parameterId);
float value = tableData.getFloatField("value", -1.0f);
entries.insert(std::make_pair(hash, value));
m_Entries.insert(std::make_pair(hash, value));
tableData.nextRow();
}
@@ -37,24 +32,22 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
}
float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
auto parameterID = m_ParametersList.find(name);
if (parameterID == m_ParametersList.end()) return defaultValue;
auto parameterID = this->m_ParametersList.find(name);
if (parameterID == this->m_ParametersList.end()) return defaultValue;
auto hash = GetKey(behaviorID, parameterID->second);
// Search for specific parameter
auto& entries = GetEntriesMutable();
auto it = entries.find(hash);
return it != entries.end() ? it->second : defaultValue;
auto it = m_Entries.find(hash);
return it != m_Entries.end() ? it->second : defaultValue;
}
std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) {
auto& entries = GetEntriesMutable();
uint64_t hashBase = behaviorID;
std::map<std::string, float> returnInfo;
for (auto& [parameterString, parameterId] : m_ParametersList) {
uint64_t hash = GetKey(hashBase, parameterId);
auto infoCandidate = entries.find(hash);
if (infoCandidate != entries.end()) {
auto infoCandidate = m_Entries.find(hash);
if (infoCandidate != m_Entries.end()) {
returnInfo.insert(std::make_pair(parameterString, infoCandidate->second));
}
}

View File

@@ -5,10 +5,12 @@
#include <unordered_map>
#include <unordered_set>
typedef uint64_t BehaviorParameterHash;
typedef float BehaviorParameterValue;
class CDBehaviorParameterTable : public CDTable<CDBehaviorParameterTable, std::unordered_map<BehaviorParameterHash, BehaviorParameterValue>> {
class CDBehaviorParameterTable : public CDTable<CDBehaviorParameterTable> {
private:
typedef uint64_t BehaviorParameterHash;
typedef float BehaviorParameterValue;
std::unordered_map<BehaviorParameterHash, BehaviorParameterValue> m_Entries;
std::unordered_map<std::string, uint32_t> m_ParametersList;
public:
void LoadValuesFromDatabase();

View File

@@ -1,9 +1,5 @@
#include "CDBehaviorTemplateTable.h"
namespace {
std::unordered_set<std::string> m_EffectHandles;
};
void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -17,9 +13,11 @@ void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDBehaviorTemplate entry;
entry.behaviorID = tableData.getIntField("behaviorID", -1);
@@ -33,17 +31,30 @@ void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first;
}
entries.insert(std::make_pair(entry.behaviorID, entry));
this->entries.push_back(entry);
this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry));
tableData.nextRow();
}
tableData.finalize();
}
std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<bool(CDBehaviorTemplate)> predicate) {
std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDBehaviorTemplate>& CDBehaviorTemplateTable::GetEntries() const {
return this->entries;
}
const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behaviorID) {
auto& entries = GetEntriesMutable();
auto entry = entries.find(behaviorID);
if (entry == entries.end()) {
auto entry = this->entriesMappedByBehaviorID.find(behaviorID);
if (entry == this->entriesMappedByBehaviorID.end()) {
CDBehaviorTemplate entryToReturn;
entryToReturn.behaviorID = 0;
entryToReturn.effectHandle = m_EffectHandles.end();

View File

@@ -12,9 +12,19 @@ struct CDBehaviorTemplate {
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
};
class CDBehaviorTemplateTable : public CDTable<CDBehaviorTemplateTable, std::unordered_map<uint32_t, CDBehaviorTemplate>> {
class CDBehaviorTemplateTable : public CDTable<CDBehaviorTemplateTable> {
private:
std::vector<CDBehaviorTemplate> entries;
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
std::unordered_set<std::string> m_EffectHandles;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
const std::vector<CDBehaviorTemplate>& GetEntries(void) const;
const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID);
};

View File

@@ -14,8 +14,7 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BrickIDTable");
@@ -24,7 +23,7 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
entry.NDObjectID = tableData.getIntField("NDObjectID", -1);
entry.LEGOBrickID = tableData.getIntField("LEGOBrickID", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -32,9 +31,15 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
}
std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBrickIDTable)> predicate) {
std::vector<CDBrickIDTable> data = cpplinq::from(GetEntries())
std::vector<CDBrickIDTable> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDBrickIDTable>& CDBrickIDTableTable::GetEntries() const {
return this->entries;
}

View File

@@ -16,9 +16,14 @@ struct CDBrickIDTable {
//! BrickIDTable table
class CDBrickIDTableTable : public CDTable<CDBrickIDTableTable, std::vector<CDBrickIDTable>> {
class CDBrickIDTableTable : public CDTable<CDBrickIDTableTable> {
private:
std::vector<CDBrickIDTable> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDBrickIDTable> Query(std::function<bool(CDBrickIDTable)> predicate);
const std::vector<CDBrickIDTable>& GetEntries() const;
};

View File

@@ -4,15 +4,14 @@
void CDComponentsRegistryTable::LoadValuesFromDatabase() {
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDComponentsRegistry entry;
entry.id = tableData.getIntField("id", -1);
entry.component_type = static_cast<eReplicaComponentType>(tableData.getIntField("component_type", 0));
entry.component_id = tableData.getIntField("component_id", -1);
entries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
entries.insert_or_assign(entry.id, 0);
this->mappedEntries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
this->mappedEntries.insert_or_assign(entry.id, 0);
tableData.nextRow();
}
@@ -21,11 +20,10 @@ void CDComponentsRegistryTable::LoadValuesFromDatabase() {
}
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) {
auto& entries = GetEntriesMutable();
auto exists = entries.find(id);
if (exists != entries.end()) {
auto iter = entries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
return iter == entries.end() ? defaultValue : iter->second;
auto exists = mappedEntries.find(id);
if (exists != mappedEntries.end()) {
auto iter = mappedEntries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
return iter == mappedEntries.end() ? defaultValue : iter->second;
}
// Now get the data. Get all components of this entity so we dont do a query for each component
@@ -40,14 +38,14 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponent
entry.component_type = static_cast<eReplicaComponentType>(tableData.getIntField("component_type", 0));
entry.component_id = tableData.getIntField("component_id", -1);
entries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
this->mappedEntries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
tableData.nextRow();
}
entries.insert_or_assign(id, 0);
mappedEntries.insert_or_assign(id, 0);
auto iter = entries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
auto iter = this->mappedEntries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
return iter == entries.end() ? defaultValue : iter->second;
return iter == this->mappedEntries.end() ? defaultValue : iter->second;
}

View File

@@ -13,7 +13,10 @@ struct CDComponentsRegistry {
};
class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable, std::unordered_map<uint64_t, uint32_t>> {
class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable> {
private:
std::unordered_map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
public:
void LoadValuesFromDatabase();
int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0);

View File

@@ -15,8 +15,7 @@ void CDCurrencyTableTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
@@ -28,7 +27,7 @@ void CDCurrencyTableTable::LoadValuesFromDatabase() {
entry.maxvalue = tableData.getIntField("maxvalue", -1);
entry.id = tableData.getIntField("id", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -36,9 +35,15 @@ void CDCurrencyTableTable::LoadValuesFromDatabase() {
}
std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCurrencyTable)> predicate) {
std::vector<CDCurrencyTable> data = cpplinq::from(GetEntries())
std::vector<CDCurrencyTable> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDCurrencyTable>& CDCurrencyTableTable::GetEntries() const {
return this->entries;
}

View File

@@ -18,9 +18,14 @@ struct CDCurrencyTable {
};
//! CurrencyTable table
class CDCurrencyTableTable : public CDTable<CDCurrencyTableTable, std::vector<CDCurrencyTable>> {
class CDCurrencyTableTable : public CDTable<CDCurrencyTableTable> {
private:
std::vector<CDCurrencyTable> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
const std::vector<CDCurrencyTable>& GetEntries() const;
};

View File

@@ -13,8 +13,7 @@ void CDDestructibleComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
@@ -35,7 +34,7 @@ void CDDestructibleComponentTable::LoadValuesFromDatabase() {
entry.isSmashable = tableData.getIntField("isSmashable", -1) == 1 ? true : false;
entry.difficultyLevel = tableData.getIntField("difficultyLevel", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -43,9 +42,15 @@ void CDDestructibleComponentTable::LoadValuesFromDatabase() {
}
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::function<bool(CDDestructibleComponent)> predicate) {
std::vector<CDDestructibleComponent> data = cpplinq::from(GetEntries())
std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDDestructibleComponent>& CDDestructibleComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -20,9 +20,14 @@ struct CDDestructibleComponent {
int32_t difficultyLevel; //!< ???
};
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable, std::vector<CDDestructibleComponent>> {
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> {
private:
std::vector<CDDestructibleComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
const std::vector<CDDestructibleComponent>& GetEntries(void) const;
};

View File

@@ -2,7 +2,6 @@
void CDEmoteTableTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDEmoteTable entry;
entry.ID = tableData.getIntField("id", -1);
@@ -22,7 +21,6 @@ void CDEmoteTableTable::LoadValuesFromDatabase() {
}
CDEmoteTable* CDEmoteTableTable::GetEmote(int32_t id) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(id);
return itr != entries.end() ? &itr->second : nullptr;
}

View File

@@ -26,7 +26,10 @@ struct CDEmoteTable {
std::string gateVersion;
};
class CDEmoteTableTable : public CDTable<CDEmoteTableTable, std::map<int, CDEmoteTable>> {
class CDEmoteTableTable : public CDTable<CDEmoteTableTable> {
private:
std::map<int, CDEmoteTable> entries;
public:
void LoadValuesFromDatabase();
// Returns an emote by ID

View File

@@ -14,8 +14,7 @@ void CDFeatureGatingTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM FeatureGating");
@@ -27,7 +26,7 @@ void CDFeatureGatingTable::LoadValuesFromDatabase() {
entry.minor = tableData.getIntField("minor", -1);
entry.description = tableData.getStringField("description", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -36,8 +35,7 @@ void CDFeatureGatingTable::LoadValuesFromDatabase() {
std::vector<CDFeatureGating> CDFeatureGatingTable::Query(std::function<bool(CDFeatureGating)> predicate) {
auto& entries = GetEntriesMutable();
std::vector<CDFeatureGating> data = cpplinq::from(entries)
std::vector<CDFeatureGating> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
@@ -45,7 +43,6 @@ std::vector<CDFeatureGating> CDFeatureGatingTable::Query(std::function<bool(CDFe
}
bool CDFeatureGatingTable::FeatureUnlocked(const CDFeatureGating& feature) const {
auto& entries = GetEntriesMutable();
for (const auto& entry : entries) {
if (entry.featureName == feature.featureName && feature >= entry) {
return true;
@@ -54,3 +51,8 @@ bool CDFeatureGatingTable::FeatureUnlocked(const CDFeatureGating& feature) const
return false;
}
const std::vector<CDFeatureGating>& CDFeatureGatingTable::GetEntries() const {
return this->entries;
}

View File

@@ -17,7 +17,10 @@ struct CDFeatureGating {
}
};
class CDFeatureGatingTable : public CDTable<CDFeatureGatingTable, std::vector<CDFeatureGating>> {
class CDFeatureGatingTable : public CDTable<CDFeatureGatingTable> {
private:
std::vector<CDFeatureGating> entries;
public:
void LoadValuesFromDatabase();
@@ -25,4 +28,6 @@ public:
std::vector<CDFeatureGating> Query(std::function<bool(CDFeatureGating)> predicate);
bool FeatureUnlocked(const CDFeatureGating& feature) const;
const std::vector<CDFeatureGating>& GetEntries(void) const;
};

View File

@@ -14,8 +14,7 @@ void CDInventoryComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM InventoryComponent");
@@ -26,7 +25,7 @@ void CDInventoryComponentTable::LoadValuesFromDatabase() {
entry.count = tableData.getIntField("count", -1);
entry.equip = tableData.getIntField("equip", -1) == 1 ? true : false;
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -34,9 +33,15 @@ void CDInventoryComponentTable::LoadValuesFromDatabase() {
}
std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function<bool(CDInventoryComponent)> predicate) {
std::vector<CDInventoryComponent> data = cpplinq::from(GetEntries())
std::vector<CDInventoryComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDInventoryComponent>& CDInventoryComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -10,9 +10,14 @@ struct CDInventoryComponent {
bool equip; //!< Whether or not to equip the item
};
class CDInventoryComponentTable : public CDTable<CDInventoryComponentTable, std::vector<CDInventoryComponent>> {
class CDInventoryComponentTable : public CDTable<CDInventoryComponentTable> {
private:
std::vector<CDInventoryComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDInventoryComponent> Query(std::function<bool(CDInventoryComponent)> predicate);
const std::vector<CDInventoryComponent>& GetEntries() const;
};

View File

@@ -17,7 +17,6 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemComponent");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDItemComponent entry;
entry.id = tableData.getIntField("id", -1);
@@ -63,7 +62,7 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
entry.forgeType = tableData.getIntField("forgeType", -1);
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
entries.insert(std::make_pair(entry.id, entry));
this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -71,9 +70,8 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
}
const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skillID) {
auto& entries = GetEntriesMutable();
const auto& it = entries.find(skillID);
if (it != entries.end()) {
const auto& it = this->entries.find(skillID);
if (it != this->entries.end()) {
return it->second;
}
@@ -131,12 +129,12 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skill
entry.forgeType = tableData.getIntField("forgeType", -1);
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
entries.insert(std::make_pair(entry.id, entry));
this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
const auto& it2 = entries.find(skillID);
if (it2 != entries.end()) {
const auto& it2 = this->entries.find(skillID);
if (it2 != this->entries.end()) {
return it2->second;
}

View File

@@ -49,7 +49,10 @@ struct CDItemComponent {
float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced)
};
class CDItemComponentTable : public CDTable<CDItemComponentTable, std::map<uint32_t, CDItemComponent>> {
class CDItemComponentTable : public CDTable<CDItemComponentTable> {
private:
std::map<uint32_t, CDItemComponent> entries;
public:
void LoadValuesFromDatabase();
static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent);

View File

@@ -14,8 +14,7 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSetSkills");
@@ -25,7 +24,7 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
entry.SkillID = tableData.getIntField("SkillID", -1);
entry.SkillCastType = tableData.getIntField("SkillCastType", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -33,17 +32,22 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
}
std::vector<CDItemSetSkills> CDItemSetSkillsTable::Query(std::function<bool(CDItemSetSkills)> predicate) {
std::vector<CDItemSetSkills> data = cpplinq::from(GetEntries())
std::vector<CDItemSetSkills> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDItemSetSkills>& CDItemSetSkillsTable::GetEntries() const {
return this->entries;
}
std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(uint32_t SkillSetID) {
std::vector<CDItemSetSkills> toReturn;
for (const auto& entry : GetEntries()) {
for (CDItemSetSkills entry : this->entries) {
if (entry.SkillSetID == SkillSetID) toReturn.push_back(entry);
if (entry.SkillSetID > SkillSetID) return toReturn; //stop seeking in the db if it's not needed.
}

View File

@@ -9,11 +9,16 @@ struct CDItemSetSkills {
uint32_t SkillCastType; //!< The skill cast type
};
class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable, std::vector<CDItemSetSkills>> {
class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable> {
private:
std::vector<CDItemSetSkills> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDItemSetSkills> Query(std::function<bool(CDItemSetSkills)> predicate);
const std::vector<CDItemSetSkills>& GetEntries() const;
std::vector<CDItemSetSkills> GetBySkillID(uint32_t SkillSetID);
};

View File

@@ -14,8 +14,7 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSets");
@@ -37,7 +36,7 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
entry.kitID = tableData.getIntField("kitID", -1);
entry.priority = tableData.getFloatField("priority", -1.0f);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -46,9 +45,14 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> predicate) {
std::vector<CDItemSets> data = cpplinq::from(GetEntries())
std::vector<CDItemSets> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDItemSets>& CDItemSetsTable::GetEntries() const {
return this->entries;
}

View File

@@ -21,10 +21,15 @@ struct CDItemSets {
float priority; //!< The priority
};
class CDItemSetsTable : public CDTable<CDItemSetsTable, std::vector<CDItemSets>> {
class CDItemSetsTable : public CDTable<CDItemSetsTable> {
private:
std::vector<CDItemSets> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDItemSets> Query(std::function<bool(CDItemSets)> predicate);
const std::vector<CDItemSets>& GetEntries(void) const;
};

View File

@@ -14,8 +14,7 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LevelProgressionLookup");
@@ -25,7 +24,7 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
entry.requiredUScore = tableData.getIntField("requiredUScore", -1);
entry.BehaviorEffect = tableData.getStringField("BehaviorEffect", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -34,9 +33,14 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::function<bool(CDLevelProgressionLookup)> predicate) {
std::vector<CDLevelProgressionLookup> data = cpplinq::from(GetEntries())
std::vector<CDLevelProgressionLookup> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDLevelProgressionLookup>& CDLevelProgressionLookupTable::GetEntries() const {
return this->entries;
}

View File

@@ -9,10 +9,15 @@ struct CDLevelProgressionLookup {
std::string BehaviorEffect; //!< The behavior effect attached to this
};
class CDLevelProgressionLookupTable : public CDTable<CDLevelProgressionLookupTable, std::vector<CDLevelProgressionLookup>> {
class CDLevelProgressionLookupTable : public CDTable<CDLevelProgressionLookupTable> {
private:
std::vector<CDLevelProgressionLookup> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDLevelProgressionLookup> Query(std::function<bool(CDLevelProgressionLookup)> predicate);
const std::vector<CDLevelProgressionLookup>& GetEntries() const;
};

View File

@@ -25,8 +25,7 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
}
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix");
@@ -34,15 +33,14 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
CDLootMatrix entry;
uint32_t lootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
entries[lootMatrixIndex].push_back(ReadRow(tableData));
this->entries[lootMatrixIndex].push_back(ReadRow(tableData));
tableData.nextRow();
}
}
const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(matrixId);
if (itr != entries.end()) {
auto itr = this->entries.find(matrixId);
if (itr != this->entries.end()) {
return itr->second;
}
@@ -51,10 +49,10 @@ const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) {
auto tableData = query.execQuery();
while (!tableData.eof()) {
entries[matrixId].push_back(ReadRow(tableData));
this->entries[matrixId].push_back(ReadRow(tableData));
tableData.nextRow();
}
return entries[matrixId];
return this->entries[matrixId];
}

View File

@@ -16,7 +16,7 @@ struct CDLootMatrix {
typedef uint32_t LootMatrixIndex;
typedef std::vector<CDLootMatrix> LootMatrixEntries;
class CDLootMatrixTable : public CDTable<CDLootMatrixTable, std::unordered_map<LootMatrixIndex, LootMatrixEntries>> {
class CDLootMatrixTable : public CDTable<CDLootMatrixTable> {
public:
void LoadValuesFromDatabase();
@@ -24,5 +24,6 @@ public:
const LootMatrixEntries& GetMatrix(uint32_t matrixId);
private:
CDLootMatrix ReadRow(CppSQLite3Query& tableData) const;
std::unordered_map<LootMatrixIndex, LootMatrixEntries> entries;
};

View File

@@ -6,8 +6,8 @@
// Sort the tables by their rarity so the highest rarity items are first.
void SortTable(LootTableEntries& table) {
auto* componentsRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
auto* componentsRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>();
// We modify the table in place so the outer loop keeps track of what is sorted
// and the inner loop finds the highest rarity item and swaps it with the current position
// of the outer loop.
@@ -49,8 +49,7 @@ void CDLootTableTable::LoadValuesFromDatabase() {
}
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable");
@@ -58,18 +57,17 @@ void CDLootTableTable::LoadValuesFromDatabase() {
CDLootTable entry;
uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1);
entries[lootTableIndex].push_back(ReadRow(tableData));
this->entries[lootTableIndex].push_back(ReadRow(tableData));
tableData.nextRow();
}
for (auto& [id, table] : entries) {
for (auto& [id, table] : this->entries) {
SortTable(table);
}
}
const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(tableId);
if (itr != entries.end()) {
auto itr = this->entries.find(tableId);
if (itr != this->entries.end()) {
return itr->second;
}
@@ -79,10 +77,10 @@ const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) {
while (!tableData.eof()) {
CDLootTable entry;
entries[tableId].push_back(ReadRow(tableData));
this->entries[tableId].push_back(ReadRow(tableData));
tableData.nextRow();
}
SortTable(entries[tableId]);
SortTable(this->entries[tableId]);
return entries[tableId];
return this->entries[tableId];
}

View File

@@ -13,9 +13,10 @@ struct CDLootTable {
typedef uint32_t LootTableIndex;
typedef std::vector<CDLootTable> LootTableEntries;
class CDLootTableTable : public CDTable<CDLootTableTable, std::unordered_map<LootTableIndex, LootTableEntries>> {
class CDLootTableTable : public CDTable<CDLootTableTable> {
private:
CDLootTable ReadRow(CppSQLite3Query& tableData) const;
std::unordered_map<LootTableIndex, LootTableEntries> entries;
public:
void LoadValuesFromDatabase();

View File

@@ -1,7 +1,7 @@
#include "CDMissionEmailTable.h"
void CDMissionEmailTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionEmail");
@@ -14,8 +14,7 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail");
@@ -30,7 +29,7 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
entry.locStatus = tableData.getIntField("locStatus", -1);
entry.gate_version = tableData.getStringField("gate_version", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -39,9 +38,15 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
//! Queries the table with a custom "where" clause
std::vector<CDMissionEmail> CDMissionEmailTable::Query(std::function<bool(CDMissionEmail)> predicate) {
std::vector<CDMissionEmail> data = cpplinq::from(GetEntries())
std::vector<CDMissionEmail> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
const std::vector<CDMissionEmail>& CDMissionEmailTable::GetEntries() const {
return this->entries;
}

View File

@@ -15,9 +15,14 @@ struct CDMissionEmail {
};
class CDMissionEmailTable : public CDTable<CDMissionEmailTable, std::vector<CDMissionEmail>> {
class CDMissionEmailTable : public CDTable<CDMissionEmailTable> {
private:
std::vector<CDMissionEmail> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDMissionEmail> Query(std::function<bool(CDMissionEmail)> predicate);
const std::vector<CDMissionEmail>& GetEntries() const;
};

View File

@@ -14,8 +14,7 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent");
@@ -27,7 +26,7 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false;
entry.gate_version = tableData.getStringField("gate_version", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -37,9 +36,15 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
//! Queries the table with a custom "where" clause
std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::Query(std::function<bool(CDMissionNPCComponent)> predicate) {
std::vector<CDMissionNPCComponent> data = cpplinq::from(GetEntries())
std::vector<CDMissionNPCComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
const std::vector<CDMissionNPCComponent>& CDMissionNPCComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -11,10 +11,17 @@ struct CDMissionNPCComponent {
std::string gate_version; //!< The gate version
};
class CDMissionNPCComponentTable : public CDTable<CDMissionNPCComponentTable, std::vector<CDMissionNPCComponent>> {
class CDMissionNPCComponentTable : public CDTable<CDMissionNPCComponentTable> {
private:
std::vector<CDMissionNPCComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate);
// Gets all the entries in the table
const std::vector<CDMissionNPCComponent>& GetEntries() const;
};

View File

@@ -14,8 +14,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks");
@@ -35,7 +34,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false);
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -44,7 +43,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMissionTasks)> predicate) {
std::vector<CDMissionTasks> data = cpplinq::from(GetEntries())
std::vector<CDMissionTasks> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
@@ -54,8 +53,7 @@ std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMiss
std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missionID) {
std::vector<CDMissionTasks*> tasks;
// TODO: this should not be linear(?) and also shouldnt need to be a pointer
for (auto& entry : GetEntriesMutable()) {
for (auto& entry : this->entries) {
if (entry.id == missionID) {
tasks.push_back(&entry);
}
@@ -64,6 +62,7 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio
return tasks;
}
const typename CDMissionTasksTable::StorageType& CDMissionTasksTable::GetEntries() const {
return CDTable::GetEntries();
const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries() const {
return this->entries;
}

View File

@@ -19,7 +19,10 @@ struct CDMissionTasks {
UNUSED(std::string gate_version); //!< ???
};
class CDMissionTasksTable : public CDTable<CDMissionTasksTable, std::vector<CDMissionTasks>> {
class CDMissionTasksTable : public CDTable<CDMissionTasksTable> {
private:
std::vector<CDMissionTasks> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
@@ -27,7 +30,6 @@ public:
std::vector<CDMissionTasks*> GetByMissionID(uint32_t missionID);
// TODO: Remove this and replace it with a proper lookup function.
const CDTable::StorageType& GetEntries() const;
const std::vector<CDMissionTasks>& GetEntries() const;
};

View File

@@ -16,8 +16,7 @@ void CDMissionsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions");
@@ -76,7 +75,7 @@ void CDMissionsTable::LoadValuesFromDatabase() {
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -87,15 +86,19 @@ void CDMissionsTable::LoadValuesFromDatabase() {
std::vector<CDMissions> CDMissionsTable::Query(std::function<bool(CDMissions)> predicate) {
std::vector<CDMissions> data = cpplinq::from(GetEntries())
std::vector<CDMissions> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDMissions>& CDMissionsTable::GetEntries(void) const {
return this->entries;
}
const CDMissions* CDMissionsTable::GetPtrByMissionID(uint32_t missionID) const {
for (const auto& entry : GetEntries()) {
for (const auto& entry : entries) {
if (entry.id == missionID) {
return const_cast<CDMissions*>(&entry);
}
@@ -105,7 +108,7 @@ const CDMissions* CDMissionsTable::GetPtrByMissionID(uint32_t missionID) const {
}
const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& found) const {
for (const auto& entry : GetEntries()) {
for (const auto& entry : entries) {
if (entry.id == missionID) {
found = true;

View File

@@ -60,12 +60,18 @@ struct CDMissions {
int32_t reward_bankinventory; //!< The amount of bank space this mission rewards
};
class CDMissionsTable : public CDTable<CDMissionsTable, std::vector<CDMissions>> {
class CDMissionsTable : public CDTable<CDMissionsTable> {
private:
std::vector<CDMissions> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDMissions> Query(std::function<bool(CDMissions)> predicate);
// Gets all the entries in the table
const std::vector<CDMissions>& GetEntries() const;
const CDMissions* GetPtrByMissionID(uint32_t missionID) const;
const CDMissions& GetByMissionID(uint32_t missionID, bool& found) const;

View File

@@ -14,8 +14,7 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent");
@@ -30,7 +29,7 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
entry.WanderRadius = tableData.getFloatField("WanderRadius", -1.0f);
entry.attachedPath = tableData.getStringField("attachedPath", "");
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -39,9 +38,14 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) {
std::vector<CDMovementAIComponent> data = cpplinq::from(GetEntries())
std::vector<CDMovementAIComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDMovementAIComponent>& CDMovementAIComponentTable::GetEntries(void) const {
return this->entries;
}

View File

@@ -14,9 +14,15 @@ struct CDMovementAIComponent {
std::string attachedPath;
};
class CDMovementAIComponentTable : public CDTable<CDMovementAIComponentTable, std::vector<CDMovementAIComponent>> {
class CDMovementAIComponentTable : public CDTable<CDMovementAIComponentTable> {
private:
std::vector<CDMovementAIComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDMovementAIComponent> Query(std::function<bool(CDMovementAIComponent)> predicate);
// Gets all the entries in the table
const std::vector<CDMovementAIComponent>& GetEntries() const;
};

View File

@@ -14,8 +14,7 @@ void CDObjectSkillsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ObjectSkills");
@@ -26,7 +25,7 @@ void CDObjectSkillsTable::LoadValuesFromDatabase() {
entry.castOnType = tableData.getIntField("castOnType", -1);
entry.AICombatWeight = tableData.getIntField("AICombatWeight", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -35,9 +34,13 @@ void CDObjectSkillsTable::LoadValuesFromDatabase() {
std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) {
std::vector<CDObjectSkills> data = cpplinq::from(GetEntries())
std::vector<CDObjectSkills> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDObjectSkills>& CDObjectSkillsTable::GetEntries() const {
return this->entries;
}

View File

@@ -10,10 +10,17 @@ struct CDObjectSkills {
uint32_t AICombatWeight; //!< ???
};
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable, std::vector<CDObjectSkills>> {
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> {
private:
std::vector<CDObjectSkills> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDObjectSkills> Query(std::function<bool(CDObjectSkills)> predicate);
// Gets all the entries in the table
const std::vector<CDObjectSkills>& GetEntries() const;
};

View File

@@ -1,9 +1,5 @@
#include "CDObjectsTable.h"
namespace {
CDObjects m_default;
};
void CDObjectsTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
@@ -18,7 +14,6 @@ void CDObjectsTable::LoadValuesFromDatabase() {
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Objects");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDObjects entry;
entry.id = tableData.getIntField("id", -1);
@@ -36,7 +31,7 @@ void CDObjectsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "");)
UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1);)
entries.insert(std::make_pair(entry.id, entry));
this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -46,9 +41,8 @@ void CDObjectsTable::LoadValuesFromDatabase() {
}
const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
auto& entries = GetEntriesMutable();
const auto& it = entries.find(LOT);
if (it != entries.end()) {
const auto& it = this->entries.find(LOT);
if (it != this->entries.end()) {
return it->second;
}
@@ -57,7 +51,7 @@ const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
auto tableData = query.execQuery();
if (tableData.eof()) {
entries.insert(std::make_pair(LOT, m_default));
this->entries.insert(std::make_pair(LOT, m_default));
return m_default;
}
@@ -79,7 +73,7 @@ const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1));
entries.insert(std::make_pair(entry.id, entry));
this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}

View File

@@ -20,7 +20,11 @@ struct CDObjects {
UNUSED(uint32_t HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com
};
class CDObjectsTable : public CDTable<CDObjectsTable, std::map<uint32_t, CDObjects>> {
class CDObjectsTable : public CDTable<CDObjectsTable> {
private:
std::map<uint32_t, CDObjects> entries;
CDObjects m_default;
public:
void LoadValuesFromDatabase();
// Gets an entry by ID

View File

@@ -13,8 +13,8 @@ void CDPackageComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PackageComponent");
@@ -24,7 +24,7 @@ void CDPackageComponentTable::LoadValuesFromDatabase() {
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
entry.packageType = tableData.getIntField("packageType", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -34,9 +34,15 @@ void CDPackageComponentTable::LoadValuesFromDatabase() {
//! Queries the table with a custom "where" clause
std::vector<CDPackageComponent> CDPackageComponentTable::Query(std::function<bool(CDPackageComponent)> predicate) {
std::vector<CDPackageComponent> data = cpplinq::from(GetEntries())
std::vector<CDPackageComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
const std::vector<CDPackageComponent>& CDPackageComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -9,9 +9,14 @@ struct CDPackageComponent {
uint32_t packageType;
};
class CDPackageComponentTable : public CDTable<CDPackageComponentTable, std::vector<CDPackageComponent>> {
class CDPackageComponentTable : public CDTable<CDPackageComponentTable> {
private:
std::vector<CDPackageComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDPackageComponent> Query(std::function<bool(CDPackageComponent)> predicate);
const std::vector<CDPackageComponent>& GetEntries() const;
};

View File

@@ -23,12 +23,10 @@ namespace {
void CDPetComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PetComponent");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
const uint32_t componentID = tableData.getIntField("id", defaultEntry.id);
auto& entry = entries[componentID];
auto& entry = m_Entries[componentID];
entry.id = componentID;
UNUSED_COLUMN(entry.minTameUpdateTime = tableData.getFloatField("minTameUpdateTime", defaultEntry.minTameUpdateTime));
UNUSED_COLUMN(entry.maxTameUpdateTime = tableData.getFloatField("maxTameUpdateTime", defaultEntry.maxTameUpdateTime));
@@ -50,13 +48,12 @@ void CDPetComponentTable::LoadValuesFromDatabase() {
}
void CDPetComponentTable::LoadValuesFromDefaults() {
GetEntriesMutable().insert(std::make_pair(defaultEntry.id, defaultEntry));
m_Entries.insert(std::make_pair(defaultEntry.id, defaultEntry));
}
CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID);
if (itr == entries.end()) {
auto itr = m_Entries.find(componentID);
if (itr == m_Entries.end()) {
LOG("Unable to load pet component (ID %i) values from database! Using default values instead.", componentID);
return defaultEntry;
}

View File

@@ -21,7 +21,7 @@ struct CDPetComponent {
UNUSED_COLUMN(std::string buffIDs;)
};
class CDPetComponentTable : public CDTable<CDPetComponentTable, std::map<uint32_t, CDPetComponent>> {
class CDPetComponentTable : public CDTable<CDPetComponentTable> {
public:
/**
@@ -39,4 +39,7 @@ public:
* @returns A reference to the corresponding table, or the default if one could not be found
*/
CDPetComponent& GetByID(const uint32_t componentID);
private:
std::map<uint32_t, CDPetComponent> m_Entries;
};

View File

@@ -2,7 +2,6 @@
void CDPhysicsComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDPhysicsComponent entry;
entry.id = tableData.getIntField("id", -1);
@@ -22,7 +21,7 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
UNUSED(entry->friction = tableData.getFloatField("friction"));
UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset"));
entries.insert(std::make_pair(entry.id, entry));
m_entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -30,8 +29,7 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
}
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(uint32_t componentID) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID);
return itr != entries.end() ? &itr->second : nullptr;
auto itr = m_entries.find(componentID);
return itr != m_entries.end() ? &itr->second : nullptr;
}

View File

@@ -21,10 +21,13 @@ struct CDPhysicsComponent {
UNUSED(std::string gravityVolumeAsset);
};
class CDPhysicsComponentTable : public CDTable<CDPhysicsComponentTable, std::map<uint32_t, CDPhysicsComponent>> {
class CDPhysicsComponentTable : public CDTable<CDPhysicsComponentTable> {
public:
void LoadValuesFromDatabase();
static const std::string GetTableName() { return "PhysicsComponent"; };
CDPhysicsComponent* GetByID(uint32_t componentID);
private:
std::map<uint32_t, CDPhysicsComponent> m_entries;
};

View File

@@ -1,9 +1,5 @@
#include "CDPropertyEntranceComponentTable.h"
namespace {
CDPropertyEntranceComponent defaultEntry{};
};
void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -16,8 +12,7 @@ void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyEntranceComponent;");
while (!tableData.eof()) {
@@ -29,7 +24,7 @@ void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() {
tableData.getStringField("groupType", "")
};
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -37,10 +32,11 @@ void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() {
}
CDPropertyEntranceComponent CDPropertyEntranceComponentTable::GetByID(uint32_t id) {
for (const auto& entry : GetEntries()) {
for (const auto& entry : entries) {
if (entry.id == id)
return entry;
}
return defaultEntry;
}

View File

@@ -9,9 +9,15 @@ struct CDPropertyEntranceComponent {
std::string groupType;
};
class CDPropertyEntranceComponentTable : public CDTable<CDPropertyEntranceComponentTable, std::vector<CDPropertyEntranceComponent>> {
class CDPropertyEntranceComponentTable : public CDTable<CDPropertyEntranceComponentTable> {
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
CDPropertyEntranceComponent GetByID(uint32_t id);
// Gets all the entries in the table
[[nodiscard]] const std::vector<CDPropertyEntranceComponent>& GetEntries() const { return entries; }
private:
std::vector<CDPropertyEntranceComponent> entries{};
CDPropertyEntranceComponent defaultEntry{};
};

View File

@@ -1,9 +1,5 @@
#include "CDPropertyTemplateTable.h"
namespace {
CDPropertyTemplate defaultEntry{};
};
void CDPropertyTemplateTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -16,8 +12,7 @@ void CDPropertyTemplateTable::LoadValuesFromDatabase() {
tableSize.finalize();
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyTemplate;");
while (!tableData.eof()) {
@@ -28,7 +23,7 @@ void CDPropertyTemplateTable::LoadValuesFromDatabase() {
tableData.getStringField("spawnName", "")
};
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -36,7 +31,7 @@ void CDPropertyTemplateTable::LoadValuesFromDatabase() {
}
CDPropertyTemplate CDPropertyTemplateTable::GetByMapID(uint32_t mapID) {
for (const auto& entry : GetEntries()) {
for (const auto& entry : entries) {
if (entry.mapID == mapID)
return entry;
}

View File

@@ -8,9 +8,13 @@ struct CDPropertyTemplate {
std::string spawnName;
};
class CDPropertyTemplateTable : public CDTable<CDPropertyTemplateTable, std::vector<CDPropertyTemplate>> {
class CDPropertyTemplateTable : public CDTable<CDPropertyTemplateTable> {
public:
void LoadValuesFromDatabase();
static const std::string GetTableName() { return "PropertyTemplate"; };
CDPropertyTemplate GetByMapID(uint32_t mapID);
private:
std::vector<CDPropertyTemplate> entries{};
CDPropertyTemplate defaultEntry{};
};

View File

@@ -14,8 +14,7 @@ void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ProximityMonitorComponent");
@@ -26,7 +25,7 @@ void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
entry.LoadOnClient = tableData.getIntField("LoadOnClient", -1);
entry.LoadOnServer = tableData.getIntField("LoadOnServer", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -35,9 +34,14 @@ void CDProximityMonitorComponentTable::LoadValuesFromDatabase() {
std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query(std::function<bool(CDProximityMonitorComponent)> predicate) {
std::vector<CDProximityMonitorComponent> data = cpplinq::from(GetEntries())
std::vector<CDProximityMonitorComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDProximityMonitorComponent>& CDProximityMonitorComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -10,9 +10,14 @@ struct CDProximityMonitorComponent {
bool LoadOnServer;
};
class CDProximityMonitorComponentTable : public CDTable<CDProximityMonitorComponentTable, std::vector<CDProximityMonitorComponent>> {
class CDProximityMonitorComponentTable : public CDTable<CDProximityMonitorComponentTable> {
private:
std::vector<CDProximityMonitorComponent> entries;
public:
void LoadValuesFromDatabase();
//! Queries the table with a custom "where" clause
std::vector<CDProximityMonitorComponent> Query(std::function<bool(CDProximityMonitorComponent)> predicate);
const std::vector<CDProximityMonitorComponent>& GetEntries() const;
};

View File

@@ -3,7 +3,6 @@
void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RailActivatorComponent;");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDRailActivatorComponent entry;
@@ -37,7 +36,7 @@ void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
entry.showNameBillboard = tableData.getIntField("ShowNameBillboard", 0);
entries.push_back(entry);
m_Entries.push_back(entry);
tableData.nextRow();
}
@@ -45,7 +44,7 @@ void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
}
CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id) const {
for (const auto& entry : GetEntries()) {
for (const auto& entry : m_Entries) {
if (entry.id == id)
return entry;
}
@@ -53,6 +52,10 @@ CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id)
return {};
}
const std::vector<CDRailActivatorComponent>& CDRailActivatorComponentTable::GetEntries() const {
return m_Entries;
}
std::pair<uint32_t, std::u16string> CDRailActivatorComponentTable::EffectPairFromString(std::string& str) {
const auto split = GeneralUtils::SplitString(str, ':');
if (split.size() == 2) {

View File

@@ -20,10 +20,13 @@ struct CDRailActivatorComponent {
bool showNameBillboard;
};
class CDRailActivatorComponentTable : public CDTable<CDRailActivatorComponentTable, std::vector<CDRailActivatorComponent>> {
class CDRailActivatorComponentTable : public CDTable<CDRailActivatorComponentTable> {
public:
void LoadValuesFromDatabase();
static const std::string GetTableName() { return "RailActivatorComponent"; };
[[nodiscard]] CDRailActivatorComponent GetEntryByID(int32_t id) const;
[[nodiscard]] const std::vector<CDRailActivatorComponent>& GetEntries() const;
private:
static std::pair<uint32_t, std::u16string> EffectPairFromString(std::string& str);
std::vector<CDRailActivatorComponent> m_Entries{};
};

View File

@@ -14,8 +14,7 @@ void CDRarityTableTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable order by randmax desc;");
@@ -31,5 +30,5 @@ void CDRarityTableTable::LoadValuesFromDatabase() {
}
const std::vector<CDRarityTable>& CDRarityTableTable::GetRarityTable(uint32_t id) {
return GetEntriesMutable()[id];
return entries[id];
}

View File

@@ -6,13 +6,15 @@
struct CDRarityTable {
float randmax;
uint32_t rarity;
typedef uint32_t Index;
};
typedef std::vector<CDRarityTable> RarityTable;
class CDRarityTableTable : public CDTable<CDRarityTableTable, std::unordered_map<CDRarityTable::Index, std::vector<CDRarityTable>>> {
class CDRarityTableTable : public CDTable<CDRarityTableTable> {
private:
typedef uint32_t RarityTableIndex;
std::unordered_map<RarityTableIndex, std::vector<CDRarityTable>> entries;
public:
void LoadValuesFromDatabase();

View File

@@ -14,8 +14,7 @@ void CDRebuildComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RebuildComponent");
@@ -32,7 +31,7 @@ void CDRebuildComponentTable::LoadValuesFromDatabase() {
entry.post_imagination_cost = tableData.getIntField("post_imagination_cost", -1);
entry.time_before_smash = tableData.getFloatField("time_before_smash", -1.0f);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -41,9 +40,14 @@ void CDRebuildComponentTable::LoadValuesFromDatabase() {
std::vector<CDRebuildComponent> CDRebuildComponentTable::Query(std::function<bool(CDRebuildComponent)> predicate) {
std::vector<CDRebuildComponent> data = cpplinq::from(GetEntries())
std::vector<CDRebuildComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDRebuildComponent>& CDRebuildComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -16,10 +16,15 @@ struct CDRebuildComponent {
float time_before_smash; //!< The time before smash
};
class CDRebuildComponentTable : public CDTable<CDRebuildComponentTable, std::vector<CDRebuildComponent>> {
class CDRebuildComponentTable : public CDTable<CDRebuildComponentTable> {
private:
std::vector<CDRebuildComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDRebuildComponent> Query(std::function<bool(CDRebuildComponent)> predicate);
const std::vector<CDRebuildComponent>& GetEntries() const;
};

View File

@@ -14,8 +14,7 @@ void CDRewardCodesTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RewardCodes");
@@ -27,20 +26,20 @@ void CDRewardCodesTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1));
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", ""));
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
}
LOT CDRewardCodesTable::GetAttachmentLOT(uint32_t rewardCodeId) const {
for (auto const &entry : GetEntries()){
for (auto const &entry : this->entries){
if (rewardCodeId == entry.id) return entry.attachmentLOT;
}
return LOT_NULL;
}
uint32_t CDRewardCodesTable::GetCodeID(std::string code) const {
for (auto const &entry : GetEntries()){
for (auto const &entry : this->entries){
if (code == entry.code) return entry.id;
}
return -1;

View File

@@ -13,9 +13,13 @@ struct CDRewardCode {
};
class CDRewardCodesTable : public CDTable<CDRewardCodesTable, std::vector<CDRewardCode>> {
class CDRewardCodesTable : public CDTable<CDRewardCodesTable> {
private:
std::vector<CDRewardCode> entries;
public:
void LoadValuesFromDatabase();
const std::vector<CDRewardCode>& GetEntries() const;
LOT GetAttachmentLOT(uint32_t rewardCodeId) const;
uint32_t GetCodeID(std::string code) const;
};

View File

@@ -2,7 +2,6 @@
void CDRewardsTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Rewards");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDRewards entry;
entry.id = tableData.getIntField("id", -1);
@@ -12,7 +11,7 @@ void CDRewardsTable::LoadValuesFromDatabase() {
entry.value = tableData.getIntField("value", -1);
entry.count = tableData.getIntField("count", -1);
entries.insert(std::make_pair(entry.id, entry));
m_entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -21,7 +20,7 @@ void CDRewardsTable::LoadValuesFromDatabase() {
std::vector<CDRewards> CDRewardsTable::GetByLevelID(uint32_t levelID) {
std::vector<CDRewards> result{};
for (const auto& e : GetEntries()) {
for (const auto& e : m_entries) {
if (e.second.levelID == levelID) result.push_back(e.second);
}

View File

@@ -11,9 +11,13 @@ struct CDRewards {
int32_t count;
};
class CDRewardsTable : public CDTable<CDRewardsTable, std::map<uint32_t, CDRewards>> {
class CDRewardsTable : public CDTable<CDRewardsTable> {
public:
void LoadValuesFromDatabase();
static const std::string GetTableName() { return "Rewards"; };
std::vector<CDRewards> GetByLevelID(uint32_t levelID);
private:
std::map<uint32_t, CDRewards> m_entries;
};

View File

@@ -1,9 +1,5 @@
#include "CDScriptComponentTable.h"
namespace {
CDScriptComponent m_ToReturnWhenNoneFound;
};
void CDScriptComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -19,14 +15,13 @@ void CDScriptComponentTable::LoadValuesFromDatabase() {
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ScriptComponent");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDScriptComponent entry;
entry.id = tableData.getIntField("id", -1);
entry.script_name = tableData.getStringField("script_name", "");
entry.client_script_name = tableData.getStringField("client_script_name", "");
entries.insert(std::make_pair(entry.id, entry));
this->entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -34,9 +29,8 @@ void CDScriptComponentTable::LoadValuesFromDatabase() {
}
const CDScriptComponent& CDScriptComponentTable::GetByID(uint32_t id) {
auto& entries = GetEntries();
auto it = entries.find(id);
if (it != entries.end()) {
std::map<uint32_t, CDScriptComponent>::iterator it = this->entries.find(id);
if (it != this->entries.end()) {
return it->second;
}

View File

@@ -9,7 +9,11 @@ struct CDScriptComponent {
std::string client_script_name; //!< The client script name
};
class CDScriptComponentTable : public CDTable<CDScriptComponentTable, std::map<uint32_t, CDScriptComponent>> {
class CDScriptComponentTable : public CDTable<CDScriptComponentTable> {
private:
std::map<uint32_t, CDScriptComponent> entries;
CDScriptComponent m_ToReturnWhenNoneFound;
public:
void LoadValuesFromDatabase();
// Gets an entry by scriptID

View File

@@ -1,10 +1,8 @@
#include "CDSkillBehaviorTable.h"
namespace {
CDSkillBehavior m_empty = CDSkillBehavior();
};
void CDSkillBehaviorTable::LoadValuesFromDatabase() {
m_empty = CDSkillBehavior();
// First, get the size of the table
uint32_t size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM SkillBehavior");
@@ -16,7 +14,8 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() {
tableSize.finalize();
auto& entries = GetEntriesMutable();
// Reserve the size
//this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM SkillBehavior");
@@ -42,7 +41,7 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() {
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
UNUSED(entry.cancelType = tableData.getIntField("cancelType", -1));
entries.insert(std::make_pair(entry.skillID, entry));
this->entries.insert(std::make_pair(entry.skillID, entry));
//this->entries.push_back(entry);
tableData.nextRow();
}
@@ -51,9 +50,8 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() {
}
const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(uint32_t skillID) {
auto& entries = GetEntries();
auto it = entries.find(skillID);
if (it != entries.end()) {
std::map<uint32_t, CDSkillBehavior>::iterator it = this->entries.find(skillID);
if (it != this->entries.end()) {
return it->second;
}

View File

@@ -25,7 +25,11 @@ struct CDSkillBehavior {
UNUSED(uint32_t cancelType); //!< The cancel type (?)
};
class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable, std::map<uint32_t, CDSkillBehavior>> {
class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable> {
private:
std::map<uint32_t, CDSkillBehavior> entries;
CDSkillBehavior m_empty;
public:
void LoadValuesFromDatabase();

View File

@@ -1,7 +1,6 @@
#pragma once
#include "CDClientDatabase.h"
#include "CDClientManager.h"
#include "Singleton.h"
#include "DluAssert.h"
@@ -28,23 +27,22 @@
#define UNUSED_ENTRY(v, x)
#pragma warning (disable : 4244) //Disable double to float conversion warnings
// #pragma warning (disable : 4715) //Disable "not all control paths return a value"
#pragma warning (disable : 4715) //Disable "not all control paths return a value"
template<class Table, typename Storage>
template<class Table>
class CDTable : public Singleton<Table> {
public:
typedef Storage StorageType;
protected:
virtual ~CDTable() = default;
// If you need these for a specific table, override it such that there is a public variant.
[[nodiscard]] StorageType& GetEntriesMutable() const {
return CDClientManager::GetEntriesMutable<Table>();
}
// If you need these for a specific table, override it such that there is a public variant.
[[nodiscard]] const StorageType& GetEntries() const {
return GetEntriesMutable();
}
};
template<class T>
class LookupResult {
typedef std::pair<T, bool> DataType;
public:
LookupResult() { m_data.first = T(); m_data.second = false; };
LookupResult(T& data) { m_data.first = data; m_data.second = true; };
inline const T& Data() { return m_data.first; };
inline const bool& FoundData() { return m_data.second; };
private:
DataType m_data;
};

View File

@@ -14,8 +14,7 @@ void CDVendorComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
auto& entries = GetEntriesMutable();
entries.reserve(size);
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM VendorComponent");
@@ -27,7 +26,7 @@ void CDVendorComponentTable::LoadValuesFromDatabase() {
entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f);
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
entries.push_back(entry);
this->entries.push_back(entry);
tableData.nextRow();
}
@@ -37,9 +36,15 @@ void CDVendorComponentTable::LoadValuesFromDatabase() {
//! Queries the table with a custom "where" clause
std::vector<CDVendorComponent> CDVendorComponentTable::Query(std::function<bool(CDVendorComponent)> predicate) {
std::vector<CDVendorComponent> data = cpplinq::from(GetEntries())
std::vector<CDVendorComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
const std::vector<CDVendorComponent>& CDVendorComponentTable::GetEntries() const {
return this->entries;
}

View File

@@ -11,10 +11,15 @@ struct CDVendorComponent {
uint32_t LootMatrixIndex; //!< LootMatrixIndex of the vendor's items
};
class CDVendorComponentTable : public CDTable<CDVendorComponentTable, std::vector<CDVendorComponent>> {
class CDVendorComponentTable : public CDTable<CDVendorComponentTable> {
private:
std::vector<CDVendorComponent> entries;
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDVendorComponent> Query(std::function<bool(CDVendorComponent)> predicate);
const std::vector<CDVendorComponent>& GetEntries(void) const;
};

View File

@@ -15,7 +15,6 @@ void CDZoneTableTable::LoadValuesFromDatabase() {
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ZoneTable");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDZoneTable entry;
entry.zoneID = tableData.getIntField("zoneID", -1);
@@ -46,7 +45,7 @@ void CDZoneTableTable::LoadValuesFromDatabase() {
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false;
entries.insert(std::make_pair(entry.zoneID, entry));
this->m_Entries.insert(std::make_pair(entry.zoneID, entry));
tableData.nextRow();
}
@@ -55,7 +54,6 @@ void CDZoneTableTable::LoadValuesFromDatabase() {
//! Queries the table with a zoneID to find.
const CDZoneTable* CDZoneTableTable::Query(uint32_t zoneID) {
auto& m_Entries = GetEntries();
const auto& iter = m_Entries.find(zoneID);
if (iter != m_Entries.end()) {

View File

@@ -33,7 +33,10 @@ struct CDZoneTable {
bool mountsAllowed; //!< Whether or not mounts are allowed
};
class CDZoneTableTable : public CDTable<CDZoneTableTable, std::map<uint32_t, CDZoneTable>> {
class CDZoneTableTable : public CDTable<CDZoneTableTable> {
private:
std::map<uint32_t, CDZoneTable> m_Entries;
public:
void LoadValuesFromDatabase();

View File

@@ -215,7 +215,7 @@ void Entity::Initialize() {
}
// Get the registry table
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
/**
* Special case for BBB models. They have components not corresponding to the registry.
@@ -369,7 +369,7 @@ void Entity::Initialize() {
if (quickBuildComponentID > 0) componentID = quickBuildComponentID;
if (buffComponentID > 0) componentID = buffComponentID;
CDDestructibleComponentTable* destCompTable = CDClientManager::GetTable<CDDestructibleComponentTable>();
CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>();
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
bool isSmashable = GetVarAs<int32_t>(u"is_smashable") != 0;
@@ -404,7 +404,7 @@ void Entity::Initialize() {
uint32_t npcMinLevel = destCompData[0].level;
uint32_t currencyIndex = destCompData[0].CurrencyIndex;
CDCurrencyTableTable* currencyTable = CDClientManager::GetTable<CDCurrencyTableTable>();
CDCurrencyTableTable* currencyTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>();
std::vector<CDCurrencyTable> currencyValues = currencyTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == currencyIndex && entry.npcminlevel == npcMinLevel); });
if (currencyValues.size() > 0) {
@@ -452,10 +452,10 @@ void Entity::Initialize() {
if (!setFaction.empty()) {
// TODO also split on space here however we do not have a general util for splitting on multiple characters yet.
std::vector<std::string> factionsToAdd = GeneralUtils::SplitString(setFaction, ';');
int32_t factionToAdd;
for (const auto faction : factionsToAdd) {
const auto factionToAdd = GeneralUtils::TryParse<int32_t>(faction);
if (factionToAdd) {
comp->AddFaction(factionToAdd.value(), true);
if (GeneralUtils::TryParse(faction, factionToAdd)) {
comp->AddFaction(factionToAdd, true);
}
}
}
@@ -489,7 +489,7 @@ void Entity::Initialize() {
* This is a bit of a mess
*/
CDScriptComponentTable* scriptCompTable = CDClientManager::GetTable<CDScriptComponentTable>();
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>();
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPT, -1);
std::string scriptName = "";
@@ -538,7 +538,7 @@ void Entity::Initialize() {
// ZoneControl script
if (m_TemplateID == 2365) {
CDZoneTableTable* zoneTable = CDClientManager::GetTable<CDZoneTableTable>();
CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>();
const auto zoneID = Game::zoneManager->GetZoneID();
const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID());
@@ -561,7 +561,7 @@ void Entity::Initialize() {
if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) {
auto* quickBuildComponent = AddComponent<QuickBuildComponent>();
CDRebuildComponentTable* rebCompTable = CDClientManager::GetTable<CDRebuildComponentTable>();
CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>();
std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == quickBuildComponentID); });
if (rebCompData.size() > 0) {
@@ -685,7 +685,7 @@ void Entity::Initialize() {
int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI);
if (movementAIID > 0) {
CDMovementAIComponentTable* moveAITable = CDClientManager::GetTable<CDMovementAIComponentTable>();
CDMovementAIComponentTable* moveAITable = CDClientManager::Instance().GetTable<CDMovementAIComponentTable>();
std::vector<CDMovementAIComponent> moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); });
if (moveAIComp.size() > 0) {
@@ -749,7 +749,7 @@ void Entity::Initialize() {
int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR);
if (proximityMonitorID > 0) {
CDProximityMonitorComponentTable* proxCompTable = CDClientManager::GetTable<CDProximityMonitorComponentTable>();
CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance().GetTable<CDProximityMonitorComponentTable>();
std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); });
if (proxCompData.size() > 0) {
std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ',');
@@ -1665,7 +1665,7 @@ void Entity::PickupItem(const LWOOBJID& objectID) {
auto* characterComponent = GetComponent<CharacterComponent>();
if (!inv || !characterComponent) return;
CDObjectsTable* objectsTable = CDClientManager::GetTable<CDObjectsTable>();
CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>();
auto& droppedLoot = characterComponent->GetDroppedLoot();
@@ -1678,13 +1678,13 @@ void Entity::PickupItem(const LWOOBJID& objectID) {
const CDObjects& object = objectsTable->GetByID(p.second.lot);
if (object.id != 0 && object.type == "Powerup") {
CDObjectSkillsTable* skillsTable = CDClientManager::GetTable<CDObjectSkillsTable>();
CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>();
std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == p.second.lot); });
for (CDObjectSkills skill : skills) {
CDSkillBehaviorTable* skillBehTable = CDClientManager::GetTable<CDSkillBehaviorTable>();
CDSkillBehaviorTable* skillBehTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
CDSkillBehavior behaviorData = skillBehTable->GetSkillByID(skill.skillID);
auto* skillComponent = GetComponent<SkillComponent>();
if (skillComponent) skillComponent->CastSkill(skill.skillID, GetObjectID(), GetObjectID());
SkillComponent::HandleUnmanaged(behaviorData.behaviorID, GetObjectID());
auto* missionComponent = GetComponent<MissionComponent>();

View File

@@ -395,8 +395,14 @@ const T& Entity::GetVar(const std::u16string& name) const {
template<typename T>
T Entity::GetVarAs(const std::u16string& name) const {
const auto data = GetVarAsString(name);
return GeneralUtils::TryParse<T>(data).value_or(LDFData<T>::Default);
T value;
if (!GeneralUtils::TryParse(data, value)) {
return LDFData<T>::Default;
}
return value;
}
template<typename T>

View File

@@ -24,7 +24,6 @@
#include "eReplicaPacketType.h"
#include "PlayerManager.h"
#include "GhostComponent.h"
#include <ranges>
// Configure which zones have ghosting disabled, mostly small worlds.
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
@@ -166,8 +165,8 @@ void EntityManager::DestroyEntity(Entity* entity) {
}
void EntityManager::SerializeEntities() {
for (size_t i = 0; i < m_EntitiesToSerialize.size(); i++) {
const LWOOBJID toSerialize = m_EntitiesToSerialize[i];
for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) {
const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i);
auto* entity = GetEntity(toSerialize);
if (!entity) continue;
@@ -196,8 +195,8 @@ void EntityManager::SerializeEntities() {
}
void EntityManager::KillEntities() {
for (size_t i = 0; i < m_EntitiesToKill.size(); i++) {
const LWOOBJID toKill = m_EntitiesToKill[i];
for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) {
const LWOOBJID toKill = m_EntitiesToKill.at(i);
auto* entity = GetEntity(toKill);
if (!entity) {
@@ -215,8 +214,8 @@ void EntityManager::KillEntities() {
}
void EntityManager::DeleteEntities() {
for (size_t i = 0; i < m_EntitiesToDelete.size(); i++) {
const LWOOBJID toDelete = m_EntitiesToDelete[i];
for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) {
const LWOOBJID toDelete = m_EntitiesToDelete.at(i);
auto entityToDelete = GetEntity(toDelete);
if (entityToDelete) {
// Get all this info first before we delete the player.
@@ -239,8 +238,8 @@ void EntityManager::DeleteEntities() {
}
void EntityManager::UpdateEntities(const float deltaTime) {
for (auto* entity : m_Entities | std::views::values) {
entity->Update(deltaTime);
for (const auto& e : m_Entities) {
e.second->Update(deltaTime);
}
SerializeEntities();
@@ -260,10 +259,10 @@ Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const {
std::vector<Entity*> EntityManager::GetEntitiesInGroup(const std::string& group) {
std::vector<Entity*> entitiesInGroup;
for (auto* entity : m_Entities | std::views::values) {
for (const auto& entityGroup : entity->GetGroups()) {
for (const auto& entity : m_Entities) {
for (const auto& entityGroup : entity.second->GetGroups()) {
if (entityGroup == group) {
entitiesInGroup.push_back(entity);
entitiesInGroup.push_back(entity.second);
}
}
}
@@ -273,12 +272,10 @@ std::vector<Entity*> EntityManager::GetEntitiesInGroup(const std::string& group)
std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaComponentType componentType) const {
std::vector<Entity*> withComp;
if (componentType != eReplicaComponentType::INVALID) {
for (auto* entity : m_Entities | std::views::values) {
if (!entity->HasComponent(componentType)) continue;
for (const auto& entity : m_Entities) {
if (componentType != eReplicaComponentType::INVALID && !entity.second->HasComponent(componentType)) continue;
withComp.push_back(entity);
}
withComp.push_back(entity.second);
}
return withComp;
}
@@ -286,19 +283,19 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaCompone
std::vector<Entity*> EntityManager::GetEntitiesByLOT(const LOT& lot) const {
std::vector<Entity*> entities;
for (auto* entity : m_Entities | std::views::values) {
if (entity->GetLOT() == lot) entities.push_back(entity);
for (const auto& entity : m_Entities) {
if (entity.second->GetLOT() == lot)
entities.push_back(entity.second);
}
return entities;
}
std::vector<Entity*> EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const {
std::vector<Entity*> entities;
if (radius <= 1000.0f) { // The client has a 1000 unit limit on this same logic, so we'll use the same limit
for (auto* entity : m_Entities | std::views::values) {
if (NiPoint3::Distance(reference, entity->GetPosition()) <= radius) entities.push_back(entity);
}
std::vector<Entity*> EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const{
std::vector<Entity*> entities = {};
if (radius > 1000.0f) return entities;
for (const auto& entity : m_Entities) {
if (NiPoint3::Distance(reference, entity.second->GetPosition()) <= radius) entities.push_back(entity.second);
}
return entities;
}
@@ -312,8 +309,12 @@ Entity* EntityManager::GetSpawnPointEntity(const std::string& spawnName) const {
// Lookup the spawn point entity in the map
const auto& spawnPoint = m_SpawnPoints.find(spawnName);
if (spawnPoint == m_SpawnPoints.end()) {
return nullptr;
}
// Check if the spawn point entity is valid just in case
return spawnPoint == m_SpawnPoints.end() ? nullptr : GetEntity(spawnPoint->second);
return GetEntity(spawnPoint->second);
}
const std::unordered_map<std::string, LWOOBJID>& EntityManager::GetSpawnPointEntities() const {
@@ -339,25 +340,29 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
entity->SetNetworkId(networkId);
}
if (entity->GetIsGhostingCandidate()) {
if (std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity) == m_EntitiesToGhost.end()) {
const auto checkGhosting = entity->GetIsGhostingCandidate();
if (checkGhosting) {
const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity);
if (iter == m_EntitiesToGhost.end()) {
m_EntitiesToGhost.push_back(entity);
}
}
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
CheckGhosting(entity);
if (checkGhosting && sysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
CheckGhosting(entity);
return;
}
return;
}
m_SerializationCounter++;
RakNet::BitStream stream;
stream.Write<uint8_t>(ID_REPLICA_MANAGER_CONSTRUCTION);
stream.Write<char>(ID_REPLICA_MANAGER_CONSTRUCTION);
stream.Write(true);
stream.Write<uint16_t>(entity->GetNetworkId());
stream.Write<unsigned short>(entity->GetNetworkId());
entity->WriteBaseReplicaData(&stream, eReplicaPacketType::CONSTRUCTION);
entity->WriteComponents(&stream, eReplicaPacketType::CONSTRUCTION);
@@ -390,9 +395,9 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
//ZoneControl is special:
ConstructEntity(m_ZoneControlEntity, sysAddr);
for (auto* entity : m_Entities | std::views::values) {
if (entity && (entity->GetSpawnerID() != 0 || entity->GetLOT() == 1) && !entity->GetIsGhostingCandidate()) {
ConstructEntity(entity, sysAddr);
for (const auto& e : m_Entities) {
if (e.second && (e.second->GetSpawnerID() != 0 || e.second->GetLOT() == 1) && !e.second->GetIsGhostingCandidate()) {
ConstructEntity(e.second, sysAddr);
}
}
@@ -404,8 +409,8 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
RakNet::BitStream stream;
stream.Write<uint8_t>(ID_REPLICA_MANAGER_DESTRUCTION);
stream.Write<uint16_t>(entity->GetNetworkId());
stream.Write<char>(ID_REPLICA_MANAGER_DESTRUCTION);
stream.Write<unsigned short>(entity->GetNetworkId());
Game::server->Send(&stream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS);
@@ -426,8 +431,8 @@ void EntityManager::SerializeEntity(Entity* entity) {
}
void EntityManager::DestructAllEntities(const SystemAddress& sysAddr) {
for (auto* entity : m_Entities | std::views::values) {
DestructEntity(entity, sysAddr);
for (const auto& e : m_Entities) {
DestructEntity(e.second, sysAddr);
}
}
@@ -435,12 +440,22 @@ void EntityManager::SetGhostDistanceMax(float value) {
m_GhostDistanceMaxSquared = value * value;
}
float EntityManager::GetGhostDistanceMax() const {
return std::sqrt(m_GhostDistanceMaxSquared);
}
void EntityManager::SetGhostDistanceMin(float value) {
m_GhostDistanceMinSqaured = value * value;
}
float EntityManager::GetGhostDistanceMin() const {
return std::sqrt(m_GhostDistanceMinSqaured);
}
void EntityManager::QueueGhostUpdate(LWOOBJID playerID) {
if (std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID) == m_PlayersToUpdateGhosting.end()) {
const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID);
if (iter == m_PlayersToUpdateGhosting.end()) {
m_PlayersToUpdateGhosting.push_back(playerID);
}
}
@@ -460,20 +475,26 @@ void EntityManager::UpdateGhosting() {
}
void EntityManager::UpdateGhosting(Entity* player) {
if (!player) return;
if (player == nullptr) {
return;
}
auto* missionComponent = player->GetComponent<MissionComponent>();
auto* ghostComponent = player->GetComponent<GhostComponent>();
if (!missionComponent || !ghostComponent) return;
if (missionComponent == nullptr || !ghostComponent) {
return;
}
const auto& referencePoint = ghostComponent->GetGhostReferencePoint();
const auto isOverride = ghostComponent->GetGhostOverride();
for (auto* entity : m_EntitiesToGhost) {
const auto isAudioEmitter = entity->GetLOT() == 6368;
const auto& entityPoint = entity->GetPosition();
const auto id = entity->GetObjectID();
const int32_t id = entity->GetObjectID();
const auto observed = ghostComponent->IsObserved(id);
@@ -482,7 +503,6 @@ void EntityManager::UpdateGhosting(Entity* player) {
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
const auto isAudioEmitter = entity->GetLOT() == 6368; // https://explorer.lu/objects/6368
if (isAudioEmitter) {
ghostingDistanceMax = ghostingDistanceMin;
}
@@ -521,25 +541,30 @@ void EntityManager::CheckGhosting(Entity* entity) {
const auto& referencePoint = entity->GetPosition();
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
const auto isAudioEmitter = entity->GetLOT() == 6368;
for (auto* player : PlayerManager::GetAllPlayers()) {
auto* ghostComponent = player->GetComponent<GhostComponent>();
if (!ghostComponent) continue;
const auto& entityPoint = ghostComponent->GetGhostReferencePoint();
const auto id = entity->GetObjectID();
const int32_t id = entity->GetObjectID();
const auto observed = ghostComponent->IsObserved(id);
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
if (observed && distance > m_GhostDistanceMaxSquared) {
if (observed && distance > ghostingDistanceMax) {
ghostComponent->GhostEntity(id);
DestructEntity(entity, player->GetSystemAddress());
entity->SetObservers(entity->GetObservers() - 1);
} else if (!observed && m_GhostDistanceMinSqaured > distance) {
} else if (!observed && ghostingDistanceMin > distance) {
ghostComponent->ObserveEntity(id);
ConstructEntity(entity, player->GetSystemAddress());
@@ -549,7 +574,7 @@ void EntityManager::CheckGhosting(Entity* entity) {
}
}
Entity* EntityManager::GetGhostCandidate(LWOOBJID id) const {
Entity* EntityManager::GetGhostCandidate(int32_t id) {
for (auto* entity : m_EntitiesToGhost) {
if (entity->GetObjectID() == id) {
return entity;
@@ -575,22 +600,26 @@ void EntityManager::ScheduleForKill(Entity* entity) {
const auto objectId = entity->GetObjectID();
if (std::find(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId) == m_EntitiesToKill.end()) {
m_EntitiesToKill.push_back(objectId);
if (std::count(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId)) {
return;
}
m_EntitiesToKill.push_back(objectId);
}
void EntityManager::ScheduleForDeletion(LWOOBJID entity) {
if (std::find(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity) == m_EntitiesToDelete.end()) {
m_EntitiesToDelete.push_back(entity);
if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity)) {
return;
}
m_EntitiesToDelete.push_back(entity);
}
void EntityManager::FireEventServerSide(Entity* origin, std::string args) {
for (const auto entity : m_Entities | std::views::values) {
if (entity) {
entity->OnFireEventServerSide(origin, args);
for (std::pair<LWOOBJID, Entity*> e : m_Entities) {
if (e.second) {
e.second->OnFireEventServerSide(origin, args);
}
}
}

View File

@@ -50,12 +50,14 @@ public:
void DestructAllEntities(const SystemAddress& sysAddr);
void SetGhostDistanceMax(float value);
float GetGhostDistanceMax() const;
void SetGhostDistanceMin(float value);
float GetGhostDistanceMin() const;
void QueueGhostUpdate(LWOOBJID playerID);
void UpdateGhosting();
void UpdateGhosting(Entity* player);
void CheckGhosting(Entity* entity);
Entity* GetGhostCandidate(LWOOBJID id) const;
Entity* GetGhostCandidate(int32_t id);
bool GetGhostingEnabled() const;
void ScheduleForKill(Entity* entity);

View File

@@ -402,7 +402,7 @@ Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) {
auto lookup = leaderboardCache.find(gameID);
if (lookup != leaderboardCache.end()) return lookup->second;
auto* activitiesTable = CDClientManager::GetTable<CDActivitiesTable>();
auto* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([gameID](const CDActivities& entry) {
return entry.ActivityID == gameID;
});

Some files were not shown because too many files have changed in this diff Show More