feat: add configurable feature and versions (#1298)

* feat: add configurable feature and versions
to allow for easily swithing it out to enable features in the client for funsies
tested that this doesn't break anything and added test

* cleanup
This commit is contained in:
Aaron Kimbrell 2023-11-18 03:33:23 -06:00 committed by GitHub
parent 57e3a4f4ef
commit 8e84cafdfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 18 deletions

View File

@ -151,6 +151,11 @@ namespace GeneralUtils {
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);

View File

@ -42,9 +42,9 @@ std::vector<CDFeatureGating> CDFeatureGatingTable::Query(std::function<bool(CDFe
return data;
}
bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const {
bool CDFeatureGatingTable::FeatureUnlocked(const CDFeatureGating& feature) const {
for (const auto& entry : entries) {
if (entry.featureName == feature) {
if (entry.featureName == feature.featureName && entry >= feature) {
return true;
}
}

View File

@ -9,6 +9,12 @@ struct CDFeatureGating {
int32_t current;
int32_t minor;
std::string description;
bool operator>=(const CDFeatureGating& b) const {
return (this->major > b.major) ||
(this->major == b.major && this->current > b.current) ||
(this->major == b.major && this->current == b.current && this->minor >= b.minor);
}
};
class CDFeatureGatingTable : public CDTable<CDFeatureGatingTable> {
@ -21,7 +27,7 @@ public:
// Queries the table with a custom "where" clause
std::vector<CDFeatureGating> Query(std::function<bool(CDFeatureGating)> predicate);
bool FeatureUnlocked(const std::string& feature) const;
bool FeatureUnlocked(const CDFeatureGating& feature) const;
const std::vector<CDFeatureGating>& GetEntries(void) const;
};

View File

@ -138,18 +138,25 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
packet.Write(static_cast<uint8_t>(responseCode));
// Event Gating
packet.Write(LUString("Talk_Like_A_Pirate"));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(""));
packet.Write(LUString(Game::config->GetValue("event_1")));
packet.Write(LUString(Game::config->GetValue("event_2")));
packet.Write(LUString(Game::config->GetValue("event_3")));
packet.Write(LUString(Game::config->GetValue("event_4")));
packet.Write(LUString(Game::config->GetValue("event_5")));
packet.Write(LUString(Game::config->GetValue("event_6")));
packet.Write(LUString(Game::config->GetValue("event_7")));
packet.Write(LUString(Game::config->GetValue("event_8")));
packet.Write(static_cast<uint16_t>(1)); // Version Major
packet.Write(static_cast<uint16_t>(10)); // Version Current
packet.Write(static_cast<uint16_t>(64)); // Version Minor
uint16_t version_major = 1;
uint16_t version_current = 10;
uint16_t version_minor = 64;
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_major"), version_major);
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_current"), version_current);
GeneralUtils::TryParse<uint16_t>(Game::config->GetValue("version_minor"), version_minor);
packet.Write(version_major);
packet.Write(version_current);
packet.Write(version_minor);
// Writes the user key
uint32_t sessionKey = GeneralUtils::GenerateRandomNumber<uint32_t>();

View File

@ -14,6 +14,7 @@
#include "CDFeatureGatingTable.h"
#include "CDClientManager.h"
#include "AssetManager.h"
#include "dConfig.h"
Level::Level(Zone* parentZone, const std::string& filepath) {
m_ParentZone = parentZone;
@ -234,6 +235,14 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
CDFeatureGatingTable* featureGatingTable = CDClientManager::Instance().GetTable<CDFeatureGatingTable>();
CDFeatureGating gating;
gating.major = 1;
gating.current = 10;
gating.minor = 64;
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_major"), gating.major);
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_current"), gating.current);
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_minor"), gating.minor);
for (uint32_t i = 0; i < objectsCount; ++i) {
SceneObject obj;
BinaryIO::BinaryRead(file, obj.id);
@ -279,11 +288,17 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
bool gated = false;
for (LDFBaseData* data : obj.settings) {
if (data->GetKey() == u"gatingOnFeature") {
std::string featureGate = data->GetValueAsString();
if (!featureGatingTable->FeatureUnlocked(featureGate)) {
gating.featureName = data->GetValueAsString();
if (gating.featureName == Game::config->GetValue("event_1")) break;
else if (gating.featureName == Game::config->GetValue("event_2")) break;
else if (gating.featureName == Game::config->GetValue("event_3")) break;
else if (gating.featureName == Game::config->GetValue("event_4")) break;
else if (gating.featureName == Game::config->GetValue("event_5")) break;
else if (gating.featureName == Game::config->GetValue("event_6")) break;
else if (gating.featureName == Game::config->GetValue("event_7")) break;
else if (gating.featureName == Game::config->GetValue("event_8")) break;
else if (!featureGatingTable->FeatureUnlocked(gating)) {
gated = true;
break;
}
}

View File

@ -47,3 +47,18 @@ client_net_version=171022
# Turn to 0 to default teams to use the live accurate Shared Loot (0) by default as opposed to Free for All (1)
# This is used in both Chat and World servers.
default_team_loot=1
# event gating for login response and luz gating
event_1=Talk_Like_A_Pirate
event_2=
event_3=
event_4=
event_5=
event_6=
event_7=
event_8=
# version for login response and luz gating
version_major=1
version_current=10
version_minor=64

View File

@ -2,6 +2,7 @@ set(DCOMMONTEST_SOURCES
"AMFDeserializeTests.cpp"
"Amf3Tests.cpp"
"HeaderSkipTest.cpp"
"TestCDFeatureGatingTable.cpp"
"TestLDFFormat.cpp"
"TestNiPoint3.cpp"
"TestEncoding.cpp"

View File

@ -0,0 +1,55 @@
#include <gtest/gtest.h>
#include "CDFeatureGatingTable.h"
TEST(dCommonTests, CDFeaturingGatingComparison){
CDFeatureGating a;
a.major = 1;
a.current = 10;
a.minor = 64;
CDFeatureGating b;
b.major = 999;
b.current = 999;
b.minor = 999;
EXPECT_TRUE(b >= a);
EXPECT_FALSE(a >= b);
// below
b.major = 0;
b.current = 10;
b.minor = 64;
EXPECT_FALSE(b >= a);
EXPECT_TRUE(a >= b);
b.major = 1;
b.current = 9;
b.minor = 64;
EXPECT_FALSE(b >= a);
EXPECT_TRUE(a >= b);
b.major = 1;
b.current = 10;
b.minor = 63;
EXPECT_FALSE(b >= a);
EXPECT_TRUE(a >= b);
// above
b.major = 2;
b.current = 10;
b.minor = 64;
EXPECT_TRUE(b >= a);
EXPECT_FALSE(a >= b);
b.major = 1;
b.current = 11;
b.minor = 64;
EXPECT_TRUE(b >= a);
EXPECT_FALSE(a >= b);
b.major = 1;
b.current = 10;
b.minor = 65;
EXPECT_TRUE(b >= a);
EXPECT_FALSE(a >= b);
}