Compare commits

...

16 Commits

Author SHA1 Message Date
e729c7f846 feat: achievement vendor and vendor feedback (#1461)
* Groundwork

* movie buying logic out of gm handler
make transaction result more useful

* Full implementation
Cleanup and fix some calls in gamemessages

* Load the component in the entity
Patch Auth

* new line at eof

* cache lookups

* remove sort

* fix includes
2024-02-25 01:47:05 -06:00
David Markowitz
1328850a8d buffRemoval (#1464)
Update BuffComponent.cpp
2024-02-25 01:01:28 -06:00
jadebenn
721ea78bb4 Update Amf3.h member naming scheme (#1463) 2024-02-24 23:03:59 -06:00
jadebenn
5ae8fd8e0e chore: Remove anonymous namespace from GeneralUtils.h (#1460)
* remove anonymous namespace from GeneralUtils.h

* Put helper functions in nested details namespace to hide from hinting

* rename implementation functions to use lower case, leading underscore and move definitions to source file
2024-02-24 04:30:02 -06:00
David Markowitz
f38537aece fix: incorrectly inverted statement (#1459)
if we DONT find it, we want to kill/delete it.  not the other way around where if we find it we try to delete it again.

tested that you no longer crash when trying to login
tested that bird monument issues are fixed
2024-02-20 05:51:02 -06:00
jadebenn
b6af92ef81 refactor: Rewrite BehaviorMessage classes to use member initialization, preferred member naming conventions, and const-ref getters (#1456)
* Split out BehaviorMessage class changes from PR #1452

* remove <string_view> inclusion in ActionContext.h

* add the arguments nullptr check back in

* remove redundant std::string constructor calls

* Update AddStripMessage.cpp - change push_back to emplace_back
2024-02-18 00:38:26 -06:00
David Markowitz
c7b3d9e817 close trade window (#1457) 2024-02-11 21:00:39 -06:00
David Markowitz
c3fbc87f9e remove copy pasted logic (#1446)
tested that the ninjago platforms and fire still works, tested that point of interest work as well

Update PhantomPhysicsComponent.cpp
2024-02-11 14:36:15 -06:00
David Markowitz
dfb2fd93b4 chore: use ranges in EntityManager and touch up (#1451)
* EntityManager: ranges and cleanup

Use LWOOBJID for ghosting entities
use ranges::views::values for associative container iteration
remove dead code
comment magic numbers
little bit of optimization (not enough to be game changing or take the time to measure, they are free speedups anyways, we take those)
use cstdint types

* use size_t

* use lwoobjid for ghost candidate
2024-02-11 14:28:25 -06:00
David Markowitz
ddaac276fe fix: Remove hard coded groups for spawners (#1454)
* fix macros not trimming newline

* Remove hardcoded spawner groups

Was just missing an inline script implementation and using the wrong name
2024-02-11 00:38:21 -06:00
David Markowitz
f7e4a32621 Fix no effect playing when picking up item (#1455) 2024-02-11 00:29:05 -06:00
ecaaea3175 chore: make predefined name unique when the name files are not provided (#1453)
Multiple characters would not be allowed to be made since they would both have tha name INVALID, that is no longer the case
2024-02-11 00:08:22 -06:00
jadebenn
29666a1ff7 chore: General cleanup roundup (#1444)
* Moved unrelated changes out of the TryParse PR branch

* const correctness and cstdint type usage

* removing a few "== nullptr"

* amf constexpr, const-correctness, and attrib tagging

* update to account for feedback

* Fixing accidentally included header and hopefully fixing the MacOS issue too

* try reordering the amf3 specializations to fix the MacOS issue again

* Amf3 template class member func instantiation fix

* try including only on macos

* Using if constexpr rather than specialization

* Trying a different solution for the instantiation problem

* Remove #include "dPlatforms.h"
2024-02-10 13:44:40 -06:00
jadebenn
0c1ee0513d refactor: Change TryParse implementation (#1442)
* Changed how the TryParse function works (and also did some general cleanup along the way)

* Update noexcept attributes (verified these are correct)

* Add fp overload for MacOS functionality

* resolving some feedback

* Split out unrelated changes to CleanupRoundup branch

* Update in response to feedback

* the consequences of emo's member variable renaming request

* Revert "the consequences of emo's member variable renaming request"

This reverts commit bf318caeda.

* Fully revert renaming attempt

* Revert "the consequences of emo's member variable renaming request"

This reverts commit bf318caeda.

Fully revert renaming attempt

* Created ClientVersion.h and moved the client version defaults to it

* Fix partial parsing and MacOS floating point errors

* attempting fix to MacOS compiler error

* syntax pass (should be the last commit unless the CI fails)

* ah, wait, forgot to uncomment the preprocessor statements for MacOS. THIS should be the last commit pending CI

* Okay, one last thing I noticed: We were including C headers here. Now they're C++ headers. Pinky swear this is it!

* typo and I am OCD. please let this be the last

* hash is usally but not always noexcept, so the specifier should go

* Address MOST of the feedback

* address the claim codes issue
2024-02-10 05:05:25 -06:00
David Markowitz
62b670d283 remove sha512, move md5 to thirdparty (#1443)
title.

Tested that Auth runs and I can login still.
2024-02-09 09:15:28 -06:00
David Markowitz
d2aeebcd46 chore: Move database storage containers to be translation unit local to allow for safe references (#1434)
* Move CDClientManager to be a namespace

Tested that worlds still load data as expected.  Had no use being a singleton anyways.

* Move cdclient data storage to tu local containers

Allows some data from these containers to be saved on object by reference instead of always needing to copy.

iteration 2

- move all unnamed namespace containers to a singular spot
- use macro for template specialization and variable declaration
- use templates to allow for as little copy paste of types and functions as possible

* remember to use typename!

compiler believes T::StorageType is accessing a member, not a type.

* Update CDClientManager.cpp

* move to cpp?
2024-02-09 07:37:58 -06:00
194 changed files with 1844 additions and 2097 deletions

View File

@@ -245,6 +245,7 @@ set(INCLUDED_DIRECTORIES
"thirdparty/SQLite"
"thirdparty/cpplinq"
"thirdparty/cpp-httplib"
"thirdparty/MD5"
"tests"
"tests/dCommonTests"
@@ -320,7 +321,7 @@ add_subdirectory(dPhysics)
add_subdirectory(dServer)
# Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum" "MD5")
# Add platform specific common libraries
if(UNIX)

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

View File

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

View File

@@ -10,21 +10,14 @@
#include "Database.h"
#include "eConnectionType.h"
#include "eChatInternalMessageType.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h"
#include "dConfig.h"
void PlayerContainer::Initialize() {
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends);
}
PlayerContainer::~PlayerContainer() {
m_Players.clear();
}
PlayerData::PlayerData() {
gmLevel = eGameMasterLevel::CIVILIAN;
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);
}
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,7 +24,6 @@ struct IgnoreData {
};
struct PlayerData {
PlayerData();
operator bool() const noexcept {
return playerID != LWOOBJID_EMPTY;
}
@@ -45,7 +44,7 @@ struct PlayerData {
std::string playerName;
std::vector<FriendData> friends;
std::vector<IgnoreData> ignoredPlayers;
eGameMasterLevel gmLevel;
eGameMasterLevel gmLevel = static_cast<eGameMasterLevel>(0); // CIVILLIAN
bool isFTP = false;
};
@@ -61,8 +60,6 @@ struct TeamData {
class PlayerContainer {
public:
~PlayerContainer();
void Initialize();
void InsertPlayer(Packet* packet);
void RemovePlayer(Packet* packet);

View File

@@ -31,54 +31,69 @@ enum class eAmf : uint8_t {
class AMFBaseValue {
public:
virtual eAmf GetValueType() { return eAmf::Undefined; };
AMFBaseValue() {};
virtual ~AMFBaseValue() {};
[[nodiscard]] constexpr virtual eAmf GetValueType() const noexcept { return eAmf::Undefined; }
constexpr AMFBaseValue() noexcept = default;
constexpr virtual ~AMFBaseValue() noexcept = default;
};
template<typename ValueType>
// AMFValue template class instantiations
template <typename ValueType>
class AMFValue : public AMFBaseValue {
public:
AMFValue() {};
AMFValue(ValueType value) { SetValue(value); };
virtual ~AMFValue() override {};
AMFValue() = default;
AMFValue(const ValueType value) : m_Data{ value } {}
virtual ~AMFValue() override = default;
eAmf GetValueType() override { return eAmf::Undefined; };
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override;
[[nodiscard]] const ValueType& GetValue() const { return m_Data; }
void SetValue(const ValueType value) { m_Data = value; }
const ValueType& GetValue() { return data; };
void SetValue(ValueType value) { data = value; };
protected:
ValueType data;
ValueType m_Data;
};
// Explicit template class instantiations
template class AMFValue<std::nullptr_t>;
template class AMFValue<bool>;
template class AMFValue<int32_t>;
template class AMFValue<uint32_t>;
template class AMFValue<std::string>;
template class AMFValue<double>;
// AMFValue template class member function instantiations
template <> [[nodiscard]] constexpr eAmf AMFValue<std::nullptr_t>::GetValueType() const noexcept { return eAmf::Null; }
template <> [[nodiscard]] constexpr eAmf AMFValue<bool>::GetValueType() const noexcept { return m_Data ? eAmf::True : eAmf::False; }
template <> [[nodiscard]] constexpr eAmf AMFValue<int32_t>::GetValueType() const noexcept { return eAmf::Integer; }
template <> [[nodiscard]] constexpr eAmf AMFValue<uint32_t>::GetValueType() const noexcept { return eAmf::Integer; }
template <> [[nodiscard]] constexpr eAmf AMFValue<std::string>::GetValueType() const noexcept { return eAmf::String; }
template <> [[nodiscard]] constexpr eAmf AMFValue<double>::GetValueType() const noexcept { return eAmf::Double; }
template <typename ValueType>
[[nodiscard]] constexpr eAmf AMFValue<ValueType>::GetValueType() const noexcept { return eAmf::Undefined; }
// As a string this is much easier to write and read from a BitStream.
template<>
template <>
class AMFValue<const char*> : public AMFBaseValue {
public:
AMFValue() {};
AMFValue(const char* value) { SetValue(std::string(value)); };
virtual ~AMFValue() override {};
AMFValue() = default;
AMFValue(const char* value) { m_Data = value; }
virtual ~AMFValue() override = default;
eAmf GetValueType() override { return eAmf::String; };
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::String; }
const std::string& GetValue() { return data; };
void SetValue(std::string value) { data = value; };
[[nodiscard]] const std::string& GetValue() const { return m_Data; }
void SetValue(const std::string& value) { m_Data = value; }
protected:
std::string data;
std::string m_Data;
};
typedef AMFValue<std::nullptr_t> AMFNullValue;
typedef AMFValue<bool> AMFBoolValue;
typedef AMFValue<int32_t> AMFIntValue;
typedef AMFValue<std::string> AMFStringValue;
typedef AMFValue<double> AMFDoubleValue;
template<> inline eAmf AMFValue<std::nullptr_t>::GetValueType() { return eAmf::Null; };
template<> inline eAmf AMFValue<bool>::GetValueType() { return this->data ? eAmf::True : eAmf::False; };
template<> inline eAmf AMFValue<int32_t>::GetValueType() { return eAmf::Integer; };
template<> inline eAmf AMFValue<uint32_t>::GetValueType() { return eAmf::Integer; };
template<> inline eAmf AMFValue<std::string>::GetValueType() { return eAmf::String; };
template<> inline eAmf AMFValue<double>::GetValueType() { return eAmf::Double; };
using AMFNullValue = AMFValue<std::nullptr_t>;
using AMFBoolValue = AMFValue<bool>;
using AMFIntValue = AMFValue<int32_t>;
using AMFStringValue = AMFValue<std::string>;
using AMFDoubleValue = AMFValue<double>;
/**
* The AMFArrayValue object holds 2 types of lists:
@@ -89,15 +104,14 @@ template<> inline eAmf AMFValue<double>::GetValueType() { return eAmf::Double; }
* and are not to be deleted by a caller.
*/
class AMFArrayValue : public AMFBaseValue {
typedef std::unordered_map<std::string, AMFBaseValue*> AMFAssociative;
typedef std::vector<AMFBaseValue*> AMFDense;
using AMFAssociative = std::unordered_map<std::string, AMFBaseValue*>;
using AMFDense = std::vector<AMFBaseValue*>;
public:
eAmf GetValueType() override { return eAmf::Array; };
[[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; }
~AMFArrayValue() override {
for (auto valueToDelete : GetDense()) {
for (const auto* valueToDelete : GetDense()) {
if (valueToDelete) {
delete valueToDelete;
valueToDelete = nullptr;
@@ -109,17 +123,17 @@ public:
valueToDelete.second = nullptr;
}
}
};
}
/**
* Returns the Associative portion of the object
*/
inline AMFAssociative& GetAssociative() { return this->associative; };
[[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return m_Associative; }
/**
* Returns the dense portion of the object
*/
inline AMFDense& GetDense() { return this->dense; };
[[nodiscard]] inline const AMFDense& GetDense() const noexcept { return m_Dense; }
/**
* Inserts an AMFValue into the associative portion with the given key.
@@ -135,48 +149,48 @@ public:
* @return The inserted element if the type matched,
* or nullptr if a key existed and was not the same type
*/
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, ValueType value) {
auto element = associative.find(key);
template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const std::string& key, const ValueType value) {
const auto element = m_Associative.find(key);
AMFValue<ValueType>* val = nullptr;
bool found = true;
if (element == associative.end()) {
if (element == m_Associative.cend()) {
val = new AMFValue<ValueType>(value);
associative.insert(std::make_pair(key, val));
m_Associative.emplace(key, val);
} else {
val = dynamic_cast<AMFValue<ValueType>*>(element->second);
found = false;
}
return std::make_pair(val, found);
};
}
// Associates an array with a string key
std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
auto element = associative.find(key);
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const std::string& key) {
const auto element = m_Associative.find(key);
AMFArrayValue* val = nullptr;
bool found = true;
if (element == associative.end()) {
if (element == m_Associative.cend()) {
val = new AMFArrayValue();
associative.insert(std::make_pair(key, val));
m_Associative.emplace(key, val);
} else {
val = dynamic_cast<AMFArrayValue*>(element->second);
found = false;
}
return std::make_pair(val, found);
};
}
// Associates an array with an integer key
std::pair<AMFBaseValue*, bool> Insert(const uint32_t& index) {
[[maybe_unused]] std::pair<AMFBaseValue*, bool> Insert(const size_t index) {
AMFArrayValue* val = nullptr;
bool inserted = false;
if (index >= dense.size()) {
dense.resize(index + 1);
if (index >= m_Dense.size()) {
m_Dense.resize(index + 1);
val = new AMFArrayValue();
dense.at(index) = val;
m_Dense.at(index) = val;
inserted = true;
}
return std::make_pair(dynamic_cast<AMFArrayValue*>(dense.at(index)), inserted);
};
return std::make_pair(dynamic_cast<AMFArrayValue*>(m_Dense.at(index)), inserted);
}
/**
* @brief Inserts an AMFValue into the AMFArray key'd by index.
@@ -188,18 +202,18 @@ public:
* @return The inserted element, or nullptr if the type did not match
* what was at the index.
*/
template<typename ValueType>
std::pair<AMFValue<ValueType>*, bool> Insert(const uint32_t& index, ValueType value) {
template <typename ValueType>
[[maybe_unused]] std::pair<AMFValue<ValueType>*, bool> Insert(const size_t index, const ValueType value) {
AMFValue<ValueType>* val = nullptr;
bool inserted = false;
if (index >= this->dense.size()) {
this->dense.resize(index + 1);
if (index >= m_Dense.size()) {
m_Dense.resize(index + 1);
val = new AMFValue<ValueType>(value);
this->dense.at(index) = val;
m_Dense.at(index) = val;
inserted = true;
}
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(this->dense.at(index)), inserted);
};
return std::make_pair(dynamic_cast<AMFValue<ValueType>*>(m_Dense.at(index)), inserted);
}
/**
* Inserts an AMFValue into the associative portion with the given key.
@@ -210,15 +224,15 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const std::string& key, AMFBaseValue* value) {
auto element = associative.find(key);
if (element != associative.end() && element->second) {
void Insert(const std::string& key, AMFBaseValue* const value) {
const auto element = m_Associative.find(key);
if (element != m_Associative.cend() && element->second) {
delete element->second;
element->second = value;
} else {
associative.insert(std::make_pair(key, value));
m_Associative.emplace(key, value);
}
};
}
/**
* Inserts an AMFValue into the associative portion with the given index.
@@ -229,15 +243,15 @@ public:
* @param key The key to associate with the value
* @param value The value to insert
*/
void Insert(const uint32_t index, AMFBaseValue* value) {
if (index < dense.size()) {
AMFDense::iterator itr = dense.begin() + index;
if (*itr) delete dense.at(index);
void Insert(const size_t index, AMFBaseValue* const value) {
if (index < m_Dense.size()) {
const AMFDense::const_iterator itr = m_Dense.cbegin() + index;
if (*itr) delete m_Dense.at(index);
} else {
dense.resize(index + 1);
m_Dense.resize(index + 1);
}
dense.at(index) = value;
};
m_Dense.at(index) = value;
}
/**
* Pushes an AMFValue into the back of the dense portion.
@@ -249,10 +263,10 @@ public:
*
* @return The inserted pointer, or nullptr should the key already be in use.
*/
template<typename ValueType>
inline AMFValue<ValueType>* Push(ValueType value) {
return Insert(this->dense.size(), value).first;
};
template <typename ValueType>
[[maybe_unused]] inline AMFValue<ValueType>* Push(const ValueType value) {
return Insert(m_Dense.size(), value).first;
}
/**
* Removes the key from the associative portion
@@ -261,52 +275,49 @@ public:
*
* @param key The key to remove from the associative portion
*/
void Remove(const std::string& key, bool deleteValue = true) {
AMFAssociative::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
void Remove(const std::string& key, const bool deleteValue = true) {
const AMFAssociative::const_iterator it = m_Associative.find(key);
if (it != m_Associative.cend()) {
if (deleteValue) delete it->second;
this->associative.erase(it);
m_Associative.erase(it);
}
}
/**
* Pops the last element in the dense portion, deleting it in the process.
*/
void Remove(const uint32_t index) {
if (!this->dense.empty() && index < this->dense.size()) {
auto itr = this->dense.begin() + index;
void Remove(const size_t index) {
if (!m_Dense.empty() && index < m_Dense.size()) {
const auto itr = m_Dense.cbegin() + index;
if (*itr) delete (*itr);
this->dense.erase(itr);
m_Dense.erase(itr);
}
}
void Pop() {
if (!this->dense.empty()) Remove(this->dense.size() - 1);
if (!m_Dense.empty()) Remove(m_Dense.size() - 1);
}
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 std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? dynamic_cast<AMFArrayValue*>(it->second) : nullptr;
}
AMFArrayValue* GetArray(const uint32_t index) {
return index >= this->dense.size() ? nullptr : dynamic_cast<AMFArrayValue*>(this->dense.at(index));
};
[[nodiscard]] AMFArrayValue* GetArray(const size_t index) const {
return index < m_Dense.size() ? dynamic_cast<AMFArrayValue*>(m_Dense.at(index)) : nullptr;
}
inline AMFArrayValue* InsertArray(const std::string& key) {
[[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) {
return static_cast<AMFArrayValue*>(Insert(key).first);
};
}
inline AMFArrayValue* InsertArray(const uint32_t index) {
[[maybe_unused]] inline AMFArrayValue* InsertArray(const size_t index) {
return static_cast<AMFArrayValue*>(Insert(index).first);
};
}
inline AMFArrayValue* PushArray() {
return static_cast<AMFArrayValue*>(Insert(this->dense.size()).first);
};
[[maybe_unused]] inline AMFArrayValue* PushArray() {
return static_cast<AMFArrayValue*>(Insert(m_Dense.size()).first);
}
/**
* Gets an AMFValue by the key from the associative portion and converts it
@@ -318,18 +329,18 @@ public:
* @return The AMFValue
*/
template <typename AmfType>
AMFValue<AmfType>* Get(const std::string& key) const {
AMFAssociative::const_iterator it = this->associative.find(key);
return it != this->associative.end() ?
[[nodiscard]] AMFValue<AmfType>* Get(const std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ?
dynamic_cast<AMFValue<AmfType>*>(it->second) :
nullptr;
};
}
// Get from the array but dont cast it
AMFBaseValue* Get(const std::string& key) const {
AMFAssociative::const_iterator it = this->associative.find(key);
return it != this->associative.end() ? it->second : nullptr;
};
[[nodiscard]] AMFBaseValue* Get(const std::string& key) const {
const AMFAssociative::const_iterator it = m_Associative.find(key);
return it != m_Associative.cend() ? it->second : nullptr;
}
/**
* @brief Get an AMFValue object at a position in the dense portion.
@@ -341,27 +352,28 @@ public:
* @return The casted object, or nullptr.
*/
template <typename AmfType>
AMFValue<AmfType>* Get(uint32_t index) const {
return index < this->dense.size() ?
dynamic_cast<AMFValue<AmfType>*>(this->dense.at(index)) :
[[nodiscard]] AMFValue<AmfType>* Get(const size_t index) const {
return index < m_Dense.size() ?
dynamic_cast<AMFValue<AmfType>*>(m_Dense.at(index)) :
nullptr;
};
}
// Get from the dense but dont cast it
AMFBaseValue* Get(const uint32_t index) const {
return index < this->dense.size() ? this->dense.at(index) : nullptr;
};
[[nodiscard]] AMFBaseValue* Get(const size_t index) const {
return index < m_Dense.size() ? m_Dense.at(index) : nullptr;
}
private:
/**
* The associative portion. These values are key'd with strings to an AMFValue.
*/
AMFAssociative associative;
AMFAssociative m_Associative;
/**
* The dense portion. These AMFValue's are stored one after
* another with the most recent addition being at the back.
*/
AMFDense dense;
AMFDense m_Dense;
};
#endif //!__AMF3__H__

View File

@@ -8,11 +8,9 @@ set(DCOMMON_SOURCES
"Game.cpp"
"GeneralUtils.cpp"
"LDFFormat.cpp"
"MD5.cpp"
"Metrics.cpp"
"NiPoint3.cpp"
"NiQuaternion.cpp"
"SHA512.cpp"
"Demangler.cpp"
"ZCompression.cpp"
"BrickByBrickFix.cpp"
@@ -68,8 +66,3 @@ else ()
endif ()
target_link_libraries(dCommon ZLIB::ZLIB)
# Disable deprecation warnings on MD5.cpp and SHA512.cpp for Apple Clang
if (APPLE)
set_source_files_properties("MD5.cpp" "SHA512.cpp" PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
endif()

View File

@@ -294,32 +294,50 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) {
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) {
// Because we dont know how large the initial number before the first _ is we need to make it a map like so.
std::map<uint32_t, std::string> filenames{};
std::map<uint32_t, std::string> filenames{};
for (auto& t : std::filesystem::directory_iterator(folder)) {
auto filename = t.path().filename().string();
auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.insert(std::make_pair(index, filename));
auto filename = t.path().filename().string();
auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.insert(std::make_pair(index, filename));
}
// Now sort the map by the oldest migration.
std::vector<std::string> sortedFiles{};
auto fileIterator = filenames.begin();
std::map<uint32_t, std::string>::iterator oldest = filenames.begin();
while (!filenames.empty()) {
auto fileIterator = filenames.begin();
std::map<uint32_t, std::string>::iterator oldest = filenames.begin();
while (!filenames.empty()) {
if (fileIterator == filenames.end()) {
sortedFiles.push_back(oldest->second);
filenames.erase(oldest);
fileIterator = filenames.begin();
oldest = filenames.begin();
continue;
sortedFiles.push_back(oldest->second);
filenames.erase(oldest);
fileIterator = filenames.begin();
oldest = filenames.begin();
continue;
}
if (oldest->first > fileIterator->first) oldest = fileIterator;
fileIterator++;
if (oldest->first > fileIterator->first) oldest = fileIterator;
fileIterator++;
}
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);
#ifdef DARKFLAME_PLATFORM_MACOS
// MacOS floating-point parse function specializations
namespace GeneralUtils::details {
template <>
[[nodiscard]] float _parse<float>(const std::string_view str, size_t& parseNum) {
return std::stof(std::string{ str }, &parseNum);
}
template <>
[[nodiscard]] double _parse<double>(const std::string_view str, size_t& parseNum) {
return std::stod(std::string{ str }, &parseNum);
}
template <>
[[nodiscard]] long double _parse<long double>(const std::string_view str, size_t& parseNum) {
return std::stold(std::string{ str }, &parseNum);
}
}
#endif

View File

@@ -1,17 +1,20 @@
#pragma once
// C++
#include <stdint.h>
#include <charconv>
#include <cstdint>
#include <random>
#include <time.h>
#include <ctime>
#include <string>
#include <type_traits>
#include <string_view>
#include <optional>
#include <functional>
#include <type_traits>
#include <stdexcept>
#include "BitStream.h"
#include "NiPoint3.h"
#include "dPlatforms.h"
#include "Game.h"
#include "Logger.h"
@@ -123,90 +126,111 @@ namespace GeneralUtils {
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);
// Concept constraining to enum types
template <typename T>
T Parse(const char* value);
concept Enum = std::is_enum_v<T>;
template <>
inline bool Parse(const char* value) {
return std::stoi(value);
// Concept constraining to numeric types
template <typename T>
concept Numeric = std::integral<T> || Enum<T> || std::floating_point<T>;
// 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 int32_t Parse(const char* value) {
return std::stoi(value);
#ifdef DARKFLAME_PLATFORM_MACOS
// MacOS floating-point parse helper function specializations
namespace details {
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);
/**
* 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 = details::_parse<T>(str, parseNum);
const bool isParsed = str.length() == parseNum;
return isParsed ? result : std::optional<T>{};
} catch (...) {
return std::nullopt;
}
template <>
inline float Parse(const char* value) {
return std::stof(value);
#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;
}
template <>
inline double Parse(const char* value) {
return std::stod(value);
}
template <>
inline uint16_t Parse(const char* value) {
return std::stoul(value);
}
template <>
inline uint32_t Parse(const char* value) {
return std::stoul(value);
}
template <>
inline uint64_t Parse(const char* value) {
return std::stoull(value);
}
template <>
inline eInventoryType Parse(const char* value) {
return static_cast<eInventoryType>(std::stoul(value));
}
template <>
inline eReplicaComponentType Parse(const char* value) {
return static_cast<eReplicaComponentType>(std::stoul(value));
/**
* The TryParse overload for handling NiPoint3 by passingn a reference to a vector of three strings
* @param str The string vector representing the X, Y, and Xcoordinates
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::vector<std::string>& str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
}
template <typename T>
bool TryParse(const char* value, T& dst) {
try {
dst = Parse<T>(value);
return true;
} catch (...) {
return false;
}
}
template <typename T>
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>
void hash_combine(std::size_t& s, const T& v) {
constexpr void hash_combine(std::size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
@@ -239,10 +263,8 @@ namespace GeneralUtils {
* @param entry Enum entry to cast
* @returns The enum entry's value in its underlying type
*/
template <typename eType>
inline constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) {
static_assert(std::is_enum_v<eType>, "Not an enum");
template <Enum eType>
constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) noexcept {
return static_cast<typename std::underlying_type_t<eType>>(entry);
}

View File

@@ -61,33 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_S32: {
int32_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto data = GeneralUtils::TryParse<int32_t>(ldfTypeAndValue.second);
if (!data) {
LOG("Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<int32_t>(key, data);
returnValue = new LDFData<int32_t>(key, data.value());
break;
}
case LDF_TYPE_FLOAT: {
float data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto data = GeneralUtils::TryParse<float>(ldfTypeAndValue.second);
if (!data) {
LOG("Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<float>(key, data);
returnValue = new LDFData<float>(key, data.value());
break;
}
case LDF_TYPE_DOUBLE: {
double data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto data = GeneralUtils::TryParse<double>(ldfTypeAndValue.second);
if (!data) {
LOG("Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<double>(key, data);
returnValue = new LDFData<double>(key, data.value());
break;
}
@@ -100,10 +100,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = 0;
} else {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto dataOptional = GeneralUtils::TryParse<uint32_t>(ldfTypeAndValue.second);
if (!dataOptional) {
LOG("Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
data = dataOptional.value();
}
returnValue = new LDFData<uint32_t>(key, data);
@@ -118,10 +120,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
} else if (ldfTypeAndValue.second == "false") {
data = false;
} else {
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto dataOptional = GeneralUtils::TryParse<bool>(ldfTypeAndValue.second);
if (!dataOptional) {
LOG("Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
data = dataOptional.value();
}
returnValue = new LDFData<bool>(key, data);
@@ -129,22 +133,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) {
}
case LDF_TYPE_U64: {
uint64_t data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto data = GeneralUtils::TryParse<uint64_t>(ldfTypeAndValue.second);
if (!data) {
LOG("Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<uint64_t>(key, data);
returnValue = new LDFData<uint64_t>(key, data.value());
break;
}
case LDF_TYPE_OBJID: {
LWOOBJID data;
if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) {
const auto data = GeneralUtils::TryParse<LWOOBJID>(ldfTypeAndValue.second);
if (!data) {
LOG("Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data());
return nullptr;
}
returnValue = new LDFData<LWOOBJID>(key, data);
returnValue = new LDFData<LWOOBJID>(key, data.value());
break;
}

View File

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

View File

@@ -1,154 +0,0 @@
// Source: http://www.zedwood.com/article/cpp-sha512-function
#include "SHA512.h"
#include <cstring>
#include <fstream>
const unsigned long long SHA512::sha512_k[80] = //ULL = uint64
{ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
void SHA512::transform(const unsigned char* message, unsigned int block_nb) {
uint64 w[80];
uint64 wv[8];
uint64 t1, t2;
const unsigned char* sub_block;
int i, j;
for (i = 0; i < (int)block_nb; i++) {
sub_block = message + (i << 7);
for (j = 0; j < 16; j++) {
SHA2_PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
}
for (j = 0; j < 8; j++) {
wv[j] = m_h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
m_h[j] += wv[j];
}
}
}
void SHA512::init() {
m_h[0] = 0x6a09e667f3bcc908ULL;
m_h[1] = 0xbb67ae8584caa73bULL;
m_h[2] = 0x3c6ef372fe94f82bULL;
m_h[3] = 0xa54ff53a5f1d36f1ULL;
m_h[4] = 0x510e527fade682d1ULL;
m_h[5] = 0x9b05688c2b3e6c1fULL;
m_h[6] = 0x1f83d9abfb41bd6bULL;
m_h[7] = 0x5be0cd19137e2179ULL;
m_len = 0;
m_tot_len = 0;
}
void SHA512::update(const unsigned char* message, unsigned int len) {
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char* shifted_message;
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&m_block[m_len], message, rem_len);
if (m_len + len < SHA384_512_BLOCK_SIZE) {
m_len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_512_BLOCK_SIZE;
shifted_message = message + rem_len;
transform(m_block, 1);
transform(shifted_message, block_nb);
rem_len = new_len % SHA384_512_BLOCK_SIZE;
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
m_len = rem_len;
m_tot_len += (block_nb + 1) << 7;
}
void SHA512::final(unsigned char* digest) {
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
int i;
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
< (m_len % SHA384_512_BLOCK_SIZE));
len_b = (m_tot_len + m_len) << 3;
pm_len = block_nb << 7;
memset(m_block + m_len, 0, pm_len - m_len);
m_block[m_len] = 0x80;
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
transform(m_block, block_nb);
for (i = 0; i < 8; i++) {
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
}
}
std::string sha512(std::string input) {
unsigned char digest[SHA512::DIGEST_SIZE];
memset(digest, 0, SHA512::DIGEST_SIZE);
class SHA512 ctx;
ctx.init();
ctx.update((unsigned char*)input.c_str(), input.length());
ctx.final(digest);
char buf[2 * SHA512::DIGEST_SIZE + 1];
buf[2 * SHA512::DIGEST_SIZE] = 0;
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
return std::string(buf);
}

View File

@@ -1,68 +0,0 @@
#pragma once
// C++
#include <string>
class SHA512 {
protected:
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
const static uint64 sha512_k[];
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
public:
void init();
void update(const unsigned char* message, unsigned int len);
void final(unsigned char* digest);
static const unsigned int DIGEST_SIZE = (512 / 8);
protected:
void transform(const unsigned char* message, unsigned int block_nb);
unsigned int m_tot_len;
unsigned int m_len;
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
uint64 m_h[8];
};
std::string sha512(std::string input);
#define SHA2_SHFR(x, n) (x >> n)
#define SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA512_F1(x) (SHA2_ROTR(x, 28) ^ SHA2_ROTR(x, 34) ^ SHA2_ROTR(x, 39))
#define SHA512_F2(x) (SHA2_ROTR(x, 14) ^ SHA2_ROTR(x, 18) ^ SHA2_ROTR(x, 41))
#define SHA512_F3(x) (SHA2_ROTR(x, 1) ^ SHA2_ROTR(x, 8) ^ SHA2_SHFR(x, 7))
#define SHA512_F4(x) (SHA2_ROTR(x, 19) ^ SHA2_ROTR(x, 61) ^ SHA2_SHFR(x, 6))
#define SHA2_UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8) ((x) ); \
*((str) + 2) = (uint8) ((x) >> 8); \
*((str) + 1) = (uint8) ((x) >> 16); \
*((str) + 0) = (uint8) ((x) >> 24); \
}
#define SHA2_UNPACK64(x, str) \
{ \
*((str) + 7) = (uint8) ((x) ); \
*((str) + 6) = (uint8) ((x) >> 8); \
*((str) + 5) = (uint8) ((x) >> 16); \
*((str) + 4) = (uint8) ((x) >> 24); \
*((str) + 3) = (uint8) ((x) >> 32); \
*((str) + 2) = (uint8) ((x) >> 40); \
*((str) + 1) = (uint8) ((x) >> 48); \
*((str) + 0) = (uint8) ((x) >> 56); \
}
#define SHA2_PACK64(str, x) \
{ \
*(x) = ((uint64) *((str) + 7) ) \
| ((uint64) *((str) + 6) << 8) \
| ((uint64) *((str) + 5) << 16) \
| ((uint64) *((str) + 4) << 24) \
| ((uint64) *((str) + 3) << 32) \
| ((uint64) *((str) + 2) << 40) \
| ((uint64) *((str) + 1) << 48) \
| ((uint64) *((str) + 0) << 56); \
}

View File

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

View File

@@ -0,0 +1,12 @@
#ifndef __CLIENTVERSION_H__
#define __CLIENTVERSION_H__
#include <cstdint>
namespace ClientVersion {
constexpr uint16_t major = 1;
constexpr uint16_t current = 10;
constexpr uint16_t minor = 64;
}
#endif // !__CLIENTVERSION_H__

View File

@@ -39,86 +39,84 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
//=========== TYPEDEFS ==========
typedef int32_t LOT; //!< A LOT
typedef int64_t LWOOBJID; //!< An object ID (should be unsigned actually but ok)
typedef int32_t TSkillID; //!< A skill ID
typedef uint32_t LWOCLONEID; //!< Used for Clone IDs
typedef uint16_t LWOMAPID; //!< Used for Map IDs
typedef uint16_t LWOINSTANCEID; //!< Used for Instance IDs
typedef uint32_t PROPERTYCLONELIST; //!< Used for Property Clone IDs
typedef uint32_t StripId;
using LOT = int32_t; //!< A LOT
using LWOOBJID = int64_t; //!< An object ID (should be unsigned actually but ok)
using TSkillID = int32_t; //!< A skill ID
using LWOCLONEID = uint32_t; //!< Used for Clone IDs
using LWOMAPID = uint16_t; //!< Used for Map IDs
using LWOINSTANCEID = uint16_t; //!< Used for Instance IDs
using PROPERTYCLONELIST = uint32_t; //!< Used for Property Clone IDs
using StripId = uint32_t;
const LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
const LOT LOT_NULL = -1; //!< A null LOT
const int32_t LOOTTYPE_NONE = 0; //!< No loot type available
const float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
const uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
const uint32_t LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
const uint16_t LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
const uint16_t LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
constexpr LWOOBJID LWOOBJID_EMPTY = 0; //!< An empty object ID
constexpr LOT LOT_NULL = -1; //!< A null LOT
constexpr int32_t LOOTTYPE_NONE = 0; //!< No loot type available
constexpr float SECONDARY_PRIORITY = 1.0f; //!< Secondary Priority
constexpr uint32_t INVENTORY_MAX = 9999999; //!< The Maximum Inventory Size
constexpr LWOCLONEID LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID
constexpr LWOINSTANCEID LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID
constexpr LWOMAPID LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID
constexpr uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
const float PI = 3.14159f;
constexpr float PI = 3.14159f;
//============ STRUCTS ==============
struct LWOSCENEID {
public:
LWOSCENEID() { m_sceneID = -1; m_layerID = 0; }
LWOSCENEID(int sceneID) { m_sceneID = sceneID; m_layerID = 0; }
LWOSCENEID(int sceneID, unsigned int layerID) { m_sceneID = sceneID; m_layerID = layerID; }
constexpr LWOSCENEID() noexcept { m_sceneID = -1; m_layerID = 0; }
constexpr LWOSCENEID(int32_t sceneID) noexcept { m_sceneID = sceneID; m_layerID = 0; }
constexpr LWOSCENEID(int32_t sceneID, uint32_t layerID) noexcept { m_sceneID = sceneID; m_layerID = layerID; }
LWOSCENEID& operator=(const LWOSCENEID& rhs) { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
LWOSCENEID& operator=(const int rhs) { m_sceneID = rhs; m_layerID = 0; return *this; }
constexpr LWOSCENEID& operator=(const LWOSCENEID& rhs) noexcept { m_sceneID = rhs.m_sceneID; m_layerID = rhs.m_layerID; return *this; }
constexpr LWOSCENEID& operator=(const int32_t rhs) noexcept { m_sceneID = rhs; m_layerID = 0; return *this; }
bool operator<(const LWOSCENEID& rhs) const { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
bool operator<(const int rhs) const { return m_sceneID < rhs; }
constexpr bool operator<(const LWOSCENEID& rhs) const noexcept { return (m_sceneID < rhs.m_sceneID || (m_sceneID == rhs.m_sceneID && m_layerID < rhs.m_layerID)); }
constexpr bool operator<(const int32_t rhs) const noexcept { return m_sceneID < rhs; }
bool operator==(const LWOSCENEID& rhs) const { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
bool operator==(const int rhs) const { return m_sceneID == rhs; }
constexpr bool operator==(const LWOSCENEID& rhs) const noexcept { return (m_sceneID == rhs.m_sceneID && m_layerID == rhs.m_layerID); }
constexpr bool operator==(const int32_t rhs) const noexcept { return m_sceneID == rhs; }
const int GetSceneID() const { return m_sceneID; }
const unsigned int GetLayerID() const { return m_layerID; }
constexpr int32_t GetSceneID() const noexcept { return m_sceneID; }
constexpr uint32_t GetLayerID() const noexcept { return m_layerID; }
void SetSceneID(const int sceneID) { m_sceneID = sceneID; }
void SetLayerID(const unsigned int layerID) { m_layerID = layerID; }
constexpr void SetSceneID(const int32_t sceneID) noexcept { m_sceneID = sceneID; }
constexpr void SetLayerID(const uint32_t layerID) noexcept { m_layerID = layerID; }
private:
int m_sceneID;
unsigned int m_layerID;
int32_t m_sceneID;
uint32_t m_layerID;
};
struct LWOZONEID {
public:
const LWOMAPID& GetMapID() const { return m_MapID; }
const LWOINSTANCEID& GetInstanceID() const { return m_InstanceID; }
const LWOCLONEID& GetCloneID() const { return m_CloneID; }
constexpr const LWOMAPID& GetMapID() const noexcept { return m_MapID; }
constexpr const LWOINSTANCEID& GetInstanceID() const noexcept { return m_InstanceID; }
constexpr const LWOCLONEID& GetCloneID() const noexcept { return m_CloneID; }
//In order: def constr, constr, assign op
LWOZONEID() { m_MapID = LWOMAPID_INVALID; m_InstanceID = LWOINSTANCEID_INVALID; m_CloneID = LWOCLONEID_INVALID; }
LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
LWOZONEID(const LWOZONEID& replacement) { *this = replacement; }
constexpr LWOZONEID() noexcept = default;
constexpr LWOZONEID(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) noexcept { m_MapID = mapID; m_InstanceID = instanceID; m_CloneID = cloneID; }
constexpr LWOZONEID(const LWOZONEID& replacement) noexcept { *this = replacement; }
private:
LWOMAPID m_MapID; //1000 for VE, 1100 for AG, etc...
LWOINSTANCEID m_InstanceID; //Instances host the same world, but on a different dWorld process.
LWOCLONEID m_CloneID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
LWOMAPID m_MapID = LWOMAPID_INVALID; //1000 for VE, 1100 for AG, etc...
LWOINSTANCEID m_InstanceID = LWOINSTANCEID_INVALID; //Instances host the same world, but on a different dWorld process.
LWOCLONEID m_CloneID = LWOCLONEID_INVALID; //To differentiate between "your property" and "my property". Always 0 for non-prop worlds.
};
const LWOSCENEID LWOSCENEID_INVALID = -1;
constexpr LWOSCENEID LWOSCENEID_INVALID = -1;
struct LWONameValue {
uint32_t length = 0; //!< The length of the name
std::u16string name; //!< The name
LWONameValue(void) {}
LWONameValue() = default;
LWONameValue(const std::u16string& name) {
this->name = name;
this->length = static_cast<uint32_t>(name.length());
}
~LWONameValue(void) {}
};
struct FriendData {

View File

@@ -106,7 +106,7 @@ enum class eReplicaComponentType : uint32_t {
INTERACTION_MANAGER,
DONATION_VENDOR,
COMBAT_MEDIATOR,
COMMENDATION_VENDOR,
ACHIEVEMENT_VENDOR,
GATE_RUSH_CONTROL,
RAIL_ACTIVATOR,
ROLLER,

View File

@@ -0,0 +1,15 @@
#ifndef __EVENDORTRANSACTIONRESULT__
#define __EVENDORTRANSACTIONRESULT__
#include <cstdint>
enum class eVendorTransactionResult : uint32_t {
SELL_SUCCESS = 0,
SELL_FAIL,
PURCHASE_SUCCESS,
PURCHASE_FAIL,
DONATION_FAIL,
DONATION_FULL
};
#endif // !__EVENDORTRANSACTIONRESULT__

View File

@@ -39,6 +39,7 @@
#include "CDFeatureGatingTable.h"
#include "CDRailActivatorComponent.h"
#include "CDRewardCodesTable.h"
#include "CDPetComponentTable.h"
#include <exception>
@@ -61,6 +62,55 @@ 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,8 +1,5 @@
#pragma once
#include "CDTable.h"
#include "Singleton.h"
#ifndef __CDCLIENTMANAGER__H__
#define __CDCLIENTMANAGER__H__
#define UNUSED_TABLE(v)
@@ -20,7 +17,28 @@ namespace CDClientManager {
* @return A pointer to the requested table.
*/
template<typename T>
T* GetTable() {
return &T::Instance();
}
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();
};
// 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,5 +1,6 @@
#include "CDActivitiesTable.h"
void CDActivitiesTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
@@ -13,7 +14,8 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities");
@@ -39,7 +41,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1);
entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -48,7 +50,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActivities)> predicate) {
std::vector<CDActivities> data = cpplinq::from(this->entries)
std::vector<CDActivities> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();

View File

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

View File

@@ -13,15 +13,9 @@ struct CDActivityRewards {
std::string description; //!< The description
};
class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable> {
private:
std::vector<CDActivityRewards> entries;
class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable, std::vector<CDActivityRewards>> {
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,6 +5,7 @@
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());
@@ -24,7 +25,7 @@ void CDAnimationsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)
this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
}
@@ -35,6 +36,7 @@ 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", "");
@@ -55,7 +57,7 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)
this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
} while (!tableData.eof());
@@ -68,15 +70,17 @@ 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)) {
this->animations[animationKey];
animations[animationKey];
}
}
void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {
auto animationEntryCached = this->animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != this->animations.end()) {
auto& animations = GetEntriesMutable();
auto animationEntryCached = animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != animations.end()) {
return;
}
@@ -85,28 +89,29 @@ void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {
// Cache the query so we don't run the query again.
CacheData(query);
this->animations[CDAnimationKey("", animationGroupID)];
animations[CDAnimationKey("", animationGroupID)];
}
CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
std::optional<CDAnimation> CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
auto& animations = GetEntriesMutable();
CDAnimationKey animationKey(animationType, animationGroupID);
auto animationEntryCached = this->animations.find(animationKey);
if (animationEntryCached == this->animations.end()) {
auto animationEntryCached = animations.find(animationKey);
if (animationEntryCached == animations.end()) {
this->CacheAnimations(animationKey);
}
auto animationEntry = this->animations.find(animationKey);
auto animationEntry = animations.find(animationKey);
// If we have only one animation, return it regardless of the chance to play.
if (animationEntry->second.size() == 1) {
return CDAnimationLookupResult(animationEntry->second.front());
return 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 CDAnimationLookupResult(animationEntry);
if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return animationEntry;
}
return CDAnimationLookupResult();
return std::nullopt;
}

View File

@@ -2,6 +2,11 @@
#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;
@@ -20,12 +25,7 @@ struct CDAnimation {
UNUSED_COLUMN(float blendTime;) //!< The blend time
};
typedef LookupResult<CDAnimation> CDAnimationLookupResult;
class CDAnimationsTable : public CDTable<CDAnimationsTable> {
typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;
class CDAnimationsTable : public CDTable<CDAnimationsTable, std::map<CDAnimationKey, std::list<CDAnimation>>> {
public:
void LoadValuesFromDatabase();
/**
@@ -38,7 +38,7 @@ public:
* @param animationGroupID The animationGroupID to lookup
* @return CDAnimationLookupResult
*/
[[nodiscard]] CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);
[[nodiscard]] std::optional<CDAnimation> GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);
/**
* Cache a full AnimationGroup by its ID.
@@ -58,10 +58,4 @@ 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,6 +1,10 @@
#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;
@@ -11,6 +15,7 @@ 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", ""));
@@ -24,7 +29,7 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
uint64_t hash = GetKey(behaviorID, parameterId);
float value = tableData.getFloatField("value", -1.0f);
m_Entries.insert(std::make_pair(hash, value));
entries.insert(std::make_pair(hash, value));
tableData.nextRow();
}
@@ -32,22 +37,24 @@ void CDBehaviorParameterTable::LoadValuesFromDatabase() {
}
float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
auto parameterID = this->m_ParametersList.find(name);
if (parameterID == this->m_ParametersList.end()) return defaultValue;
auto parameterID = m_ParametersList.find(name);
if (parameterID == m_ParametersList.end()) return defaultValue;
auto hash = GetKey(behaviorID, parameterID->second);
// Search for specific parameter
auto it = m_Entries.find(hash);
return it != m_Entries.end() ? it->second : defaultValue;
auto& entries = GetEntriesMutable();
auto it = entries.find(hash);
return it != 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 = m_Entries.find(hash);
if (infoCandidate != m_Entries.end()) {
auto infoCandidate = entries.find(hash);
if (infoCandidate != entries.end()) {
returnInfo.insert(std::make_pair(parameterString, infoCandidate->second));
}
}

View File

@@ -5,12 +5,10 @@
#include <unordered_map>
#include <unordered_set>
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;
typedef uint64_t BehaviorParameterHash;
typedef float BehaviorParameterValue;
class CDBehaviorParameterTable : public CDTable<CDBehaviorParameterTable, std::unordered_map<BehaviorParameterHash, BehaviorParameterValue>> {
public:
void LoadValuesFromDatabase();

View File

@@ -1,5 +1,9 @@
#include "CDBehaviorTemplateTable.h"
namespace {
std::unordered_set<std::string> m_EffectHandles;
};
void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -13,11 +17,9 @@ 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);
@@ -31,30 +33,17 @@ void CDBehaviorTemplateTable::LoadValuesFromDatabase() {
entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first;
}
this->entries.push_back(entry);
this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry));
entries.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 entry = this->entriesMappedByBehaviorID.find(behaviorID);
if (entry == this->entriesMappedByBehaviorID.end()) {
auto& entries = GetEntriesMutable();
auto entry = entries.find(behaviorID);
if (entry == entries.end()) {
CDBehaviorTemplate entryToReturn;
entryToReturn.behaviorID = 0;
entryToReturn.effectHandle = m_EffectHandles.end();

View File

@@ -12,19 +12,9 @@ struct CDBehaviorTemplate {
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
};
class CDBehaviorTemplateTable : public CDTable<CDBehaviorTemplateTable> {
private:
std::vector<CDBehaviorTemplate> entries;
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
std::unordered_set<std::string> m_EffectHandles;
class CDBehaviorTemplateTable : public CDTable<CDBehaviorTemplateTable, std::unordered_map<uint32_t, CDBehaviorTemplate>> {
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,7 +14,8 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BrickIDTable");
@@ -23,7 +24,7 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
entry.NDObjectID = tableData.getIntField("NDObjectID", -1);
entry.LEGOBrickID = tableData.getIntField("LEGOBrickID", -1);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -31,15 +32,9 @@ void CDBrickIDTableTable::LoadValuesFromDatabase() {
}
std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBrickIDTable)> predicate) {
std::vector<CDBrickIDTable> data = cpplinq::from(this->entries)
std::vector<CDBrickIDTable> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDBrickIDTable>& CDBrickIDTableTable::GetEntries() const {
return this->entries;
}

View File

@@ -16,14 +16,9 @@ struct CDBrickIDTable {
//! BrickIDTable table
class CDBrickIDTableTable : public CDTable<CDBrickIDTableTable> {
private:
std::vector<CDBrickIDTable> entries;
class CDBrickIDTableTable : public CDTable<CDBrickIDTableTable, std::vector<CDBrickIDTable>> {
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,14 +4,15 @@
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);
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);
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);
tableData.nextRow();
}
@@ -20,10 +21,11 @@ void CDComponentsRegistryTable::LoadValuesFromDatabase() {
}
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) {
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;
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;
}
// Now get the data. Get all components of this entity so we dont do a query for each component
@@ -38,14 +40,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);
this->mappedEntries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
entries.insert_or_assign(static_cast<uint64_t>(entry.component_type) << 32 | static_cast<uint64_t>(entry.id), entry.component_id);
tableData.nextRow();
}
mappedEntries.insert_or_assign(id, 0);
entries.insert_or_assign(id, 0);
auto iter = this->mappedEntries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
auto iter = entries.find(static_cast<uint64_t>(componentType) << 32 | static_cast<uint64_t>(id));
return iter == this->mappedEntries.end() ? defaultValue : iter->second;
return iter == entries.end() ? defaultValue : iter->second;
}

View File

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

View File

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

View File

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

View File

@@ -20,14 +20,9 @@ struct CDDestructibleComponent {
int32_t difficultyLevel; //!< ???
};
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> {
private:
std::vector<CDDestructibleComponent> entries;
class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable, std::vector<CDDestructibleComponent>> {
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,6 +2,7 @@
void CDEmoteTableTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDEmoteTable entry;
entry.ID = tableData.getIntField("id", -1);
@@ -21,6 +22,7 @@ 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,10 +26,7 @@ struct CDEmoteTable {
std::string gateVersion;
};
class CDEmoteTableTable : public CDTable<CDEmoteTableTable> {
private:
std::map<int, CDEmoteTable> entries;
class CDEmoteTableTable : public CDTable<CDEmoteTableTable, std::map<int, CDEmoteTable>> {
public:
void LoadValuesFromDatabase();
// Returns an emote by ID

View File

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

View File

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

View File

@@ -10,14 +10,9 @@ struct CDInventoryComponent {
bool equip; //!< Whether or not to equip the item
};
class CDInventoryComponentTable : public CDTable<CDInventoryComponentTable> {
private:
std::vector<CDInventoryComponent> entries;
class CDInventoryComponentTable : public CDTable<CDInventoryComponentTable, std::vector<CDInventoryComponent>> {
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,6 +17,7 @@ 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);
@@ -62,7 +63,7 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
entry.forgeType = tableData.getIntField("forgeType", -1);
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
this->entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -70,8 +71,9 @@ void CDItemComponentTable::LoadValuesFromDatabase() {
}
const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skillID) {
const auto& it = this->entries.find(skillID);
if (it != this->entries.end()) {
auto& entries = GetEntriesMutable();
const auto& it = entries.find(skillID);
if (it != entries.end()) {
return it->second;
}
@@ -129,12 +131,12 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skill
entry.forgeType = tableData.getIntField("forgeType", -1);
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
this->entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
const auto& it2 = this->entries.find(skillID);
if (it2 != this->entries.end()) {
const auto& it2 = entries.find(skillID);
if (it2 != entries.end()) {
return it2->second;
}

View File

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

View File

@@ -14,7 +14,8 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSetSkills");
@@ -24,7 +25,7 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
entry.SkillID = tableData.getIntField("SkillID", -1);
entry.SkillCastType = tableData.getIntField("SkillCastType", -1);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -32,22 +33,17 @@ void CDItemSetSkillsTable::LoadValuesFromDatabase() {
}
std::vector<CDItemSetSkills> CDItemSetSkillsTable::Query(std::function<bool(CDItemSetSkills)> predicate) {
std::vector<CDItemSetSkills> data = cpplinq::from(this->entries)
std::vector<CDItemSetSkills> data = cpplinq::from(GetEntries())
>> 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 (CDItemSetSkills entry : this->entries) {
for (const auto& entry : GetEntries()) {
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,16 +9,11 @@ struct CDItemSetSkills {
uint32_t SkillCastType; //!< The skill cast type
};
class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable> {
private:
std::vector<CDItemSetSkills> entries;
class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable, std::vector<CDItemSetSkills>> {
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,7 +14,8 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSets");
@@ -36,7 +37,7 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
entry.kitID = tableData.getIntField("kitID", -1);
entry.priority = tableData.getFloatField("priority", -1.0f);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -45,14 +46,9 @@ void CDItemSetsTable::LoadValuesFromDatabase() {
std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> predicate) {
std::vector<CDItemSets> data = cpplinq::from(this->entries)
std::vector<CDItemSets> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDItemSets>& CDItemSetsTable::GetEntries() const {
return this->entries;
}

View File

@@ -21,15 +21,10 @@ struct CDItemSets {
float priority; //!< The priority
};
class CDItemSetsTable : public CDTable<CDItemSetsTable> {
private:
std::vector<CDItemSets> entries;
class CDItemSetsTable : public CDTable<CDItemSetsTable, std::vector<CDItemSets>> {
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,7 +14,8 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LevelProgressionLookup");
@@ -24,7 +25,7 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
entry.requiredUScore = tableData.getIntField("requiredUScore", -1);
entry.BehaviorEffect = tableData.getStringField("BehaviorEffect", "");
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -33,14 +34,9 @@ void CDLevelProgressionLookupTable::LoadValuesFromDatabase() {
std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::function<bool(CDLevelProgressionLookup)> predicate) {
std::vector<CDLevelProgressionLookup> data = cpplinq::from(this->entries)
std::vector<CDLevelProgressionLookup> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
const std::vector<CDLevelProgressionLookup>& CDLevelProgressionLookupTable::GetEntries() const {
return this->entries;
}

View File

@@ -9,15 +9,10 @@ struct CDLevelProgressionLookup {
std::string BehaviorEffect; //!< The behavior effect attached to this
};
class CDLevelProgressionLookupTable : public CDTable<CDLevelProgressionLookupTable> {
private:
std::vector<CDLevelProgressionLookup> entries;
class CDLevelProgressionLookupTable : public CDTable<CDLevelProgressionLookupTable, std::vector<CDLevelProgressionLookup>> {
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,7 +25,8 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
}
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix");
@@ -33,14 +34,15 @@ void CDLootMatrixTable::LoadValuesFromDatabase() {
CDLootMatrix entry;
uint32_t lootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
this->entries[lootMatrixIndex].push_back(ReadRow(tableData));
entries[lootMatrixIndex].push_back(ReadRow(tableData));
tableData.nextRow();
}
}
const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) {
auto itr = this->entries.find(matrixId);
if (itr != this->entries.end()) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(matrixId);
if (itr != entries.end()) {
return itr->second;
}
@@ -49,10 +51,10 @@ const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) {
auto tableData = query.execQuery();
while (!tableData.eof()) {
this->entries[matrixId].push_back(ReadRow(tableData));
entries[matrixId].push_back(ReadRow(tableData));
tableData.nextRow();
}
return this->entries[matrixId];
return entries[matrixId];
}

View File

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

View File

@@ -49,7 +49,8 @@ void CDLootTableTable::LoadValuesFromDatabase() {
}
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable");
@@ -57,17 +58,18 @@ void CDLootTableTable::LoadValuesFromDatabase() {
CDLootTable entry;
uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1);
this->entries[lootTableIndex].push_back(ReadRow(tableData));
entries[lootTableIndex].push_back(ReadRow(tableData));
tableData.nextRow();
}
for (auto& [id, table] : this->entries) {
for (auto& [id, table] : entries) {
SortTable(table);
}
}
const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) {
auto itr = this->entries.find(tableId);
if (itr != this->entries.end()) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(tableId);
if (itr != entries.end()) {
return itr->second;
}
@@ -77,10 +79,10 @@ const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) {
while (!tableData.eof()) {
CDLootTable entry;
this->entries[tableId].push_back(ReadRow(tableData));
entries[tableId].push_back(ReadRow(tableData));
tableData.nextRow();
}
SortTable(this->entries[tableId]);
SortTable(entries[tableId]);
return this->entries[tableId];
return entries[tableId];
}

View File

@@ -13,10 +13,9 @@ struct CDLootTable {
typedef uint32_t LootTableIndex;
typedef std::vector<CDLootTable> LootTableEntries;
class CDLootTableTable : public CDTable<CDLootTableTable> {
class CDLootTableTable : public CDTable<CDLootTableTable, std::unordered_map<LootTableIndex, LootTableEntries>> {
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() {
void CDMissionEmailTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM MissionEmail");
@@ -14,7 +14,8 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail");
@@ -29,7 +30,7 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
entry.locStatus = tableData.getIntField("locStatus", -1);
entry.gate_version = tableData.getStringField("gate_version", "");
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -38,15 +39,9 @@ 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(this->entries)
std::vector<CDMissionEmail> data = cpplinq::from(GetEntries())
>> 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,14 +15,9 @@ struct CDMissionEmail {
};
class CDMissionEmailTable : public CDTable<CDMissionEmailTable> {
private:
std::vector<CDMissionEmail> entries;
class CDMissionEmailTable : public CDTable<CDMissionEmailTable, std::vector<CDMissionEmail>> {
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,7 +14,8 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent");
@@ -26,7 +27,7 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false;
entry.gate_version = tableData.getStringField("gate_version", "");
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -36,15 +37,9 @@ 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(this->entries)
std::vector<CDMissionNPCComponent> data = cpplinq::from(GetEntries())
>> 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,17 +11,10 @@ struct CDMissionNPCComponent {
std::string gate_version; //!< The gate version
};
class CDMissionNPCComponentTable : public CDTable<CDMissionNPCComponentTable> {
private:
std::vector<CDMissionNPCComponent> entries;
class CDMissionNPCComponentTable : public CDTable<CDMissionNPCComponentTable, std::vector<CDMissionNPCComponent>> {
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,7 +14,8 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks");
@@ -34,7 +35,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false);
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -43,7 +44,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMissionTasks)> predicate) {
std::vector<CDMissionTasks> data = cpplinq::from(this->entries)
std::vector<CDMissionTasks> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
@@ -53,7 +54,8 @@ std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMiss
std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missionID) {
std::vector<CDMissionTasks*> tasks;
for (auto& entry : this->entries) {
// TODO: this should not be linear(?) and also shouldnt need to be a pointer
for (auto& entry : GetEntriesMutable()) {
if (entry.id == missionID) {
tasks.push_back(&entry);
}
@@ -62,7 +64,6 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio
return tasks;
}
const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries() const {
return this->entries;
const typename CDMissionTasksTable::StorageType& CDMissionTasksTable::GetEntries() const {
return CDTable::GetEntries();
}

View File

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

View File

@@ -16,7 +16,8 @@ void CDMissionsTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions");
@@ -75,10 +76,9 @@ void CDMissionsTable::LoadValuesFromDatabase() {
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
tableData.finalize();
Default.id = -1;
@@ -86,19 +86,15 @@ void CDMissionsTable::LoadValuesFromDatabase() {
std::vector<CDMissions> CDMissionsTable::Query(std::function<bool(CDMissions)> predicate) {
std::vector<CDMissions> data = cpplinq::from(this->entries)
std::vector<CDMissions> data = cpplinq::from(GetEntries())
>> 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 : entries) {
for (const auto& entry : GetEntries()) {
if (entry.id == missionID) {
return const_cast<CDMissions*>(&entry);
}
@@ -108,7 +104,7 @@ const CDMissions* CDMissionsTable::GetPtrByMissionID(uint32_t missionID) const {
}
const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& found) const {
for (const auto& entry : entries) {
for (const auto& entry : GetEntries()) {
if (entry.id == missionID) {
found = true;
@@ -121,3 +117,12 @@ const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& foun
return Default;
}
const std::set<int32_t> CDMissionsTable::GetMissionsForReward(LOT lot) {
std::set<int32_t> toReturn {};
for (const auto& entry : GetEntries()) {
if (lot == entry.reward_item1 || lot == entry.reward_item2 || lot == entry.reward_item3 || lot == entry.reward_item4) {
toReturn.insert(entry.id);
}
}
return toReturn;
}

View File

@@ -60,22 +60,19 @@ struct CDMissions {
int32_t reward_bankinventory; //!< The amount of bank space this mission rewards
};
class CDMissionsTable : public CDTable<CDMissionsTable> {
private:
std::vector<CDMissions> entries;
class CDMissionsTable : public CDTable<CDMissionsTable, std::vector<CDMissions>> {
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;
const std::set<int32_t> GetMissionsForReward(LOT lot);
static CDMissions Default;
};

View File

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

View File

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

View File

@@ -10,17 +10,10 @@ struct CDObjectSkills {
uint32_t AICombatWeight; //!< ???
};
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> {
private:
std::vector<CDObjectSkills> entries;
class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable, std::vector<CDObjectSkills>> {
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,5 +1,9 @@
#include "CDObjectsTable.h"
namespace {
CDObjects m_default;
};
void CDObjectsTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
@@ -14,6 +18,7 @@ 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);
@@ -31,7 +36,7 @@ void CDObjectsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "");)
UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1);)
this->entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -41,8 +46,9 @@ void CDObjectsTable::LoadValuesFromDatabase() {
}
const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
const auto& it = this->entries.find(LOT);
if (it != this->entries.end()) {
auto& entries = GetEntriesMutable();
const auto& it = entries.find(LOT);
if (it != entries.end()) {
return it->second;
}
@@ -51,7 +57,7 @@ const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
auto tableData = query.execQuery();
if (tableData.eof()) {
this->entries.insert(std::make_pair(LOT, m_default));
entries.insert(std::make_pair(LOT, m_default));
return m_default;
}
@@ -73,7 +79,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));
this->entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}

View File

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

View File

@@ -13,8 +13,8 @@ void CDPackageComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
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);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -34,15 +34,9 @@ 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(this->entries)
std::vector<CDPackageComponent> data = cpplinq::from(GetEntries())
>> 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,14 +9,9 @@ struct CDPackageComponent {
uint32_t packageType;
};
class CDPackageComponentTable : public CDTable<CDPackageComponentTable> {
private:
std::vector<CDPackageComponent> entries;
class CDPackageComponentTable : public CDTable<CDPackageComponentTable, std::vector<CDPackageComponent>> {
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,10 +23,12 @@ 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 = m_Entries[componentID];
auto& entry = entries[componentID];
entry.id = componentID;
UNUSED_COLUMN(entry.minTameUpdateTime = tableData.getFloatField("minTameUpdateTime", defaultEntry.minTameUpdateTime));
UNUSED_COLUMN(entry.maxTameUpdateTime = tableData.getFloatField("maxTameUpdateTime", defaultEntry.maxTameUpdateTime));
@@ -48,12 +50,13 @@ void CDPetComponentTable::LoadValuesFromDatabase() {
}
void CDPetComponentTable::LoadValuesFromDefaults() {
m_Entries.insert(std::make_pair(defaultEntry.id, defaultEntry));
GetEntriesMutable().insert(std::make_pair(defaultEntry.id, defaultEntry));
}
CDPetComponent& CDPetComponentTable::GetByID(const uint32_t componentID) {
auto itr = m_Entries.find(componentID);
if (itr == m_Entries.end()) {
auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID);
if (itr == 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> {
class CDPetComponentTable : public CDTable<CDPetComponentTable, std::map<uint32_t, CDPetComponent>> {
public:
/**
@@ -39,7 +39,4 @@ 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,6 +2,7 @@
void CDPhysicsComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDPhysicsComponent entry;
entry.id = tableData.getIntField("id", -1);
@@ -21,7 +22,7 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
UNUSED(entry->friction = tableData.getFloatField("friction"));
UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset"));
m_entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -29,7 +30,8 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
}
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(uint32_t componentID) {
auto itr = m_entries.find(componentID);
return itr != m_entries.end() ? &itr->second : nullptr;
auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID);
return itr != entries.end() ? &itr->second : nullptr;
}

View File

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

View File

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

View File

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

View File

@@ -10,14 +10,9 @@ struct CDProximityMonitorComponent {
bool LoadOnServer;
};
class CDProximityMonitorComponentTable : public CDTable<CDProximityMonitorComponentTable> {
private:
std::vector<CDProximityMonitorComponent> entries;
class CDProximityMonitorComponentTable : public CDTable<CDProximityMonitorComponentTable, std::vector<CDProximityMonitorComponent>> {
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,6 +3,7 @@
void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RailActivatorComponent;");
auto& entries = GetEntriesMutable();
while (!tableData.eof()) {
CDRailActivatorComponent entry;
@@ -36,7 +37,7 @@ void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
entry.showNameBillboard = tableData.getIntField("ShowNameBillboard", 0);
m_Entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -44,7 +45,7 @@ void CDRailActivatorComponentTable::LoadValuesFromDatabase() {
}
CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id) const {
for (const auto& entry : m_Entries) {
for (const auto& entry : GetEntries()) {
if (entry.id == id)
return entry;
}
@@ -52,10 +53,6 @@ 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,13 +20,10 @@ struct CDRailActivatorComponent {
bool showNameBillboard;
};
class CDRailActivatorComponentTable : public CDTable<CDRailActivatorComponentTable> {
class CDRailActivatorComponentTable : public CDTable<CDRailActivatorComponentTable, std::vector<CDRailActivatorComponent>> {
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,7 +14,8 @@ void CDRarityTableTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable order by randmax desc;");
@@ -30,5 +31,5 @@ void CDRarityTableTable::LoadValuesFromDatabase() {
}
const std::vector<CDRarityTable>& CDRarityTableTable::GetRarityTable(uint32_t id) {
return entries[id];
return GetEntriesMutable()[id];
}

View File

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

View File

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

View File

@@ -16,15 +16,10 @@ struct CDRebuildComponent {
float time_before_smash; //!< The time before smash
};
class CDRebuildComponentTable : public CDTable<CDRebuildComponentTable> {
private:
std::vector<CDRebuildComponent> entries;
class CDRebuildComponentTable : public CDTable<CDRebuildComponentTable, std::vector<CDRebuildComponent>> {
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,7 +14,8 @@ void CDRewardCodesTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RewardCodes");
@@ -26,20 +27,20 @@ void CDRewardCodesTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1));
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", ""));
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
}
LOT CDRewardCodesTable::GetAttachmentLOT(uint32_t rewardCodeId) const {
for (auto const &entry : this->entries){
for (auto const &entry : GetEntries()){
if (rewardCodeId == entry.id) return entry.attachmentLOT;
}
return LOT_NULL;
}
uint32_t CDRewardCodesTable::GetCodeID(std::string code) const {
for (auto const &entry : this->entries){
for (auto const &entry : GetEntries()){
if (code == entry.code) return entry.id;
}
return -1;

View File

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

View File

@@ -11,13 +11,9 @@ struct CDRewards {
int32_t count;
};
class CDRewardsTable : public CDTable<CDRewardsTable> {
class CDRewardsTable : public CDTable<CDRewardsTable, std::map<uint32_t, CDRewards>> {
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,5 +1,9 @@
#include "CDScriptComponentTable.h"
namespace {
CDScriptComponent m_ToReturnWhenNoneFound;
};
void CDScriptComponentTable::LoadValuesFromDatabase() {
// First, get the size of the table
@@ -15,13 +19,14 @@ 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", "");
this->entries.insert(std::make_pair(entry.id, entry));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow();
}
@@ -29,8 +34,9 @@ void CDScriptComponentTable::LoadValuesFromDatabase() {
}
const CDScriptComponent& CDScriptComponentTable::GetByID(uint32_t id) {
std::map<uint32_t, CDScriptComponent>::iterator it = this->entries.find(id);
if (it != this->entries.end()) {
auto& entries = GetEntries();
auto it = entries.find(id);
if (it != entries.end()) {
return it->second;
}

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#pragma once
#include "CDClientDatabase.h"
#include "CDClientManager.h"
#include "Singleton.h"
#include "DluAssert.h"
@@ -27,22 +28,23 @@
#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>
template<class Table, typename Storage>
class CDTable : public Singleton<Table> {
public:
typedef Storage StorageType;
protected:
virtual ~CDTable() = default;
};
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;
// 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();
}
};

View File

@@ -14,7 +14,8 @@ void CDVendorComponentTable::LoadValuesFromDatabase() {
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM VendorComponent");
@@ -26,7 +27,7 @@ void CDVendorComponentTable::LoadValuesFromDatabase() {
entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f);
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}
@@ -36,15 +37,9 @@ 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(this->entries)
std::vector<CDVendorComponent> data = cpplinq::from(GetEntries())
>> 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,15 +11,10 @@ struct CDVendorComponent {
uint32_t LootMatrixIndex; //!< LootMatrixIndex of the vendor's items
};
class CDVendorComponentTable : public CDTable<CDVendorComponentTable> {
private:
std::vector<CDVendorComponent> entries;
class CDVendorComponentTable : public CDTable<CDVendorComponentTable, std::vector<CDVendorComponent>> {
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,6 +15,7 @@ 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);
@@ -45,7 +46,7 @@ void CDZoneTableTable::LoadValuesFromDatabase() {
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false;
this->m_Entries.insert(std::make_pair(entry.zoneID, entry));
entries.insert(std::make_pair(entry.zoneID, entry));
tableData.nextRow();
}
@@ -54,6 +55,7 @@ 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()) {

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