backup to Player Variables changes

This commit is contained in:
EricPlayZ
2025-01-07 00:28:09 +02:00
parent 24a343d3f9
commit 8552e28bcd
3 changed files with 312 additions and 133 deletions

View File

@ -3,6 +3,7 @@
#include <unordered_map>
#include <vector>
#include <memory>
#include <algorithm>
#include <EGSDK\ClassHelpers.h>
#include <EGSDK\Utils\Values.h>
@ -42,6 +43,8 @@ namespace EGSDK::GamePH {
EGSDK::ClassHelpers::buffer<0xC, float> defaultValue;
};
FloatPlayerVariable(const std::string& name);
void SetValues(float value);
};
class EGameSDK_API BoolPlayerVariable : public PlayerVariable {
public:
@ -50,13 +53,58 @@ namespace EGSDK::GamePH {
EGSDK::ClassHelpers::buffer<0x9, bool> defaultValue;
};
BoolPlayerVariable(const std::string& name);
void SetValues(bool value);
};
class EGameSDK_API PlayerVarVector {
public:
std::unique_ptr<PlayerVariable>& emplace_back(std::unique_ptr<PlayerVariable> playerVar) {
_playerVars.emplace_back(std::move(playerVar));
return _playerVars.back();
}
auto begin() {
return _playerVars.begin();
}
auto end() {
return _playerVars.end();
}
bool none_of(const std::string& name) {
return std::none_of(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
}
auto FindIter(const std::string& name) {
auto playerVarIt = std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
return playerVarIt;
}
std::unique_ptr<PlayerVariable>* FindPtr(const std::string& name) {
auto playerVarIt = FindIter(name);
return playerVarIt == _playerVars.end() ? nullptr : &*playerVarIt;
}
PlayerVariable* Find(const std::string& name) {
auto playerVarPtr = FindPtr(name);
return playerVarPtr == nullptr ? nullptr : playerVarPtr->get();
}
auto Erase(const std::string& name) {
auto playerVarIt = FindIter(name);
if (playerVarIt != _playerVars.end())
return _playerVars.erase(playerVarIt);
return _playerVars.end();
}
std::vector<std::unique_ptr<PlayerVariable>> _playerVars{};
};
class EGameSDK_API PlayerVariables {
public:
static std::vector<std::unique_ptr<PlayerVariable>> playerVars;
static std::vector<std::unique_ptr<PlayerVariable>> defaultPlayerVars;
static std::vector<std::unique_ptr<PlayerVariable>> customDefaultPlayerVars;
static PlayerVarVector playerVars;
static PlayerVarVector customPlayerVars;
static PlayerVarVector defaultPlayerVars;
static PlayerVarVector customDefaultPlayerVars;
static bool gotPlayerVars;
static std::unordered_map<std::string, std::any> prevPlayerVarValueMap;
@ -88,13 +136,10 @@ namespace EGSDK::GamePH {
if (!gotPlayerVars)
return getDefaultValue<T>();
auto playerVarIt = std::find_if(playerVars.begin(), playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
if (playerVarIt == playerVars.end())
auto playerVar = playerVars.Find(name);
if (!playerVar)
return getDefaultValue<T>();
auto playerVar = playerVarIt->get();
if constexpr (std::is_same_v<T, std::string>) {
StringPlayerVariable* stringPlayerVar = reinterpret_cast<StringPlayerVariable*>(playerVar);
return stringPlayerVar->value.data;
@ -113,34 +158,31 @@ namespace EGSDK::GamePH {
if (!gotPlayerVars)
return;
auto playerVarIt = std::find_if(playerVars.begin(), playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
if (playerVarIt == playerVars.end())
auto playerVar = playerVars.Find(name);
if (!playerVar)
return;
auto playerVar = playerVarIt->get();
if constexpr (std::is_same_v<T, std::string>) {
switch (playerVar->GetType()) {
case PlayerVarType::String:
// TO IMPLEMENT
break;
case PlayerVarType::Float: {
case PlayerVarType::Float:
{
std::string valueStr = Utils::Values::to_string(value);
float actualValue = std::stof(valueStr);
FloatPlayerVariable* floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
floatPlayerVar->value = actualValue;
floatPlayerVar->defaultValue = actualValue;
floatPlayerVar->SetValues(actualValue);
break;
}
case PlayerVarType::Bool: {
case PlayerVarType::Bool:
{
std::string valueStr = Utils::Values::to_string(value);
bool actualValue = valueStr == "true";
BoolPlayerVariable* boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVar);
boolPlayerVar->value = actualValue;
boolPlayerVar->defaultValue = actualValue;
boolPlayerVar->SetValues(actualValue);
break;
}
default:
@ -151,39 +193,148 @@ namespace EGSDK::GamePH {
return;
FloatPlayerVariable* floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
floatPlayerVar->value = value;
floatPlayerVar->defaultValue = value;
floatPlayerVar->SetValues(value);
} else if constexpr (std::is_same_v<T, bool>) {
if (playerVar->GetType() != PlayerVarType::Bool)
return;
BoolPlayerVariable* boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVar);
boolPlayerVar->value = value;
boolPlayerVar->defaultValue = value;
boolPlayerVar->SetValues(value);
}
}
template <typename T>
static void ChangePlayerVarFromList(const std::string& name, const T value, PlayerVariable* playerVar = nullptr) {
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, bool>, "Invalid type: value must be string, float or bool");
if (!gotPlayerVars)
return;
if (!playerVar) {
playerVar = playerVars.Find(name);
if (!playerVar)
return;
}
auto customPlayerVar = customPlayerVars.Find(name);
auto defPlayerVar = defaultPlayerVars.Find(name);
if constexpr (std::is_same_v<T, std::string>) {
switch (playerVar->GetType()) {
case PlayerVarType::String:
// TO IMPLEMENT
break;
case PlayerVarType::Float:
{
if (!customPlayerVar)
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
std::string valueStr = Utils::Values::to_string(value);
float actualValue = std::stof(valueStr);
FloatPlayerVariable* floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
FloatPlayerVariable* customFloatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(customPlayerVar);
if (!defPlayerVar) {
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(defPlayerVar);
defFloatPlayerVar->SetValues(floatPlayerVar->value);
}
floatPlayerVar->SetValues(actualValue);
customFloatPlayerVar->SetValues(actualValue);
break;
}
case PlayerVarType::Bool:
{
if (!customPlayerVar)
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
std::string valueStr = Utils::Values::to_string(value);
bool actualValue = valueStr == "true";
BoolPlayerVariable* boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVar);
BoolPlayerVariable* customBoolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(customPlayerVar);
if (!defPlayerVar) {
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(defPlayerVar);
defBoolPlayerVar->SetValues(boolPlayerVar->value);
}
boolPlayerVar->SetValues(actualValue);
customBoolPlayerVar->SetValues(actualValue);
break;
}
default:
break;
}
} else if constexpr (std::is_same_v<T, float>) {
if (playerVar->GetType() != PlayerVarType::Float)
return;
if (!customPlayerVar)
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
FloatPlayerVariable* floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
FloatPlayerVariable* customFloatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(customPlayerVar);
if (!defPlayerVar) {
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(defPlayerVar);
defFloatPlayerVar->SetValues(floatPlayerVar->value);
}
floatPlayerVar->SetValues(value);
customFloatPlayerVar->SetValues(value);
} else if constexpr (std::is_same_v<T, bool>) {
if (playerVar->GetType() != PlayerVarType::Bool)
return;
if (!customPlayerVar)
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
BoolPlayerVariable* boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVar);
BoolPlayerVariable* customBoolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(customPlayerVar);
if (!defPlayerVar) {
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(defPlayerVar);
defBoolPlayerVar->SetValues(boolPlayerVar->value);
}
boolPlayerVar->SetValues(value);
customBoolPlayerVar->SetValues(value);
}
}
template <typename T>
static void ManagePlayerVarByBool(const std::string& playerVar, const T valueIfTrue, const T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
static void ManagePlayerVarByBool(const std::string& name, const T valueIfTrue, const T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
if (!gotPlayerVars)
return;
if (prevPlayerVarValueMap.find(playerVar) == prevPlayerVarValueMap.end())
prevPlayerVarValueMap[playerVar] = GetPlayerVarValue<T>(playerVar);
if (prevBoolValueMap.find(playerVar) == prevBoolValueMap.end())
prevBoolValueMap[playerVar] = false;
if (prevPlayerVarValueMap.find(name) == prevPlayerVarValueMap.end())
prevPlayerVarValueMap[name] = GetPlayerVarValue<T>(name);
if (prevBoolValueMap.find(name) == prevBoolValueMap.end())
prevBoolValueMap[name] = false;
if (boolVal) {
if (!prevBoolValueMap[playerVar])
prevPlayerVarValueMap[playerVar] = GetPlayerVarValue<T>(playerVar);
if (!prevBoolValueMap[name])
prevPlayerVarValueMap[name] = GetPlayerVarValue<T>(name);
ChangePlayerVar(playerVar, valueIfTrue);
prevBoolValueMap[playerVar] = true;
} else if (prevBoolValueMap[playerVar]) {
prevBoolValueMap[playerVar] = false;
ChangePlayerVar(playerVar, usePreviousVal ? std::any_cast<T>(prevPlayerVarValueMap[playerVar]) : valueIfFalse);
ChangePlayerVar(name, valueIfTrue);
prevBoolValueMap[name] = true;
} else if (prevBoolValueMap[name]) {
prevBoolValueMap[name] = false;
ChangePlayerVar(name, usePreviousVal ? std::any_cast<T>(prevPlayerVarValueMap[name]) : valueIfFalse);
prevPlayerVarValueMap.erase(name);
}
}
static bool IsPlayerVarManagedByBool(const std::string& name) {
if (!gotPlayerVars)
return false;
return prevBoolValueMap.find(name) != prevBoolValueMap.end() && !prevBoolValueMap[name];
}
static PlayerVariables* Get();
};

View File

@ -44,13 +44,22 @@ namespace EGSDK::GamePH {
FloatPlayerVariable::FloatPlayerVariable(const std::string& name) : PlayerVariable(name) {
SetType(PlayerVarType::Float);
}
void FloatPlayerVariable::SetValues(float value) {
this->value = value;
this->defaultValue = value;
}
BoolPlayerVariable::BoolPlayerVariable(const std::string& name) : PlayerVariable(name) {
SetType(PlayerVarType::Bool);
}
void BoolPlayerVariable::SetValues(bool value) {
this->value = value;
this->defaultValue = value;
}
std::vector<std::unique_ptr<PlayerVariable>> PlayerVariables::playerVars{};
std::vector<std::unique_ptr<PlayerVariable>> PlayerVariables::defaultPlayerVars{};
std::vector<std::unique_ptr<PlayerVariable>> PlayerVariables::customDefaultPlayerVars{};
PlayerVarVector PlayerVariables::playerVars{};
PlayerVarVector PlayerVariables::customPlayerVars{};
PlayerVarVector PlayerVariables::defaultPlayerVars{};
PlayerVarVector PlayerVariables::customDefaultPlayerVars{};
bool PlayerVariables::gotPlayerVars = false;
static bool sortedPlayerVars = false;
@ -58,29 +67,23 @@ namespace EGSDK::GamePH {
std::unordered_map<std::string, bool> PlayerVariables::prevBoolValueMap{};
template <typename T>
static void updateDefaultVar(std::vector<std::unique_ptr<PlayerVariable>>& defaultVars, const std::string& name, T value, T defaultValue) {
static void updateDefaultVar(PlayerVarVector& defaultVars, const std::string& name, T value, T defaultValue) {
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, bool>, "Invalid type: value must be string, float or bool");
auto playerVarIt = std::find_if(defaultVars.begin(), defaultVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
if (playerVarIt == defaultVars.end()) {
auto playerVar = defaultVars.Find(name);
if (!playerVar) {
if constexpr (std::is_same_v<T, std::string>) {
auto stringPlayerVar = std::make_unique<StringPlayerVariable>(name);
stringPlayerVar->value = value;
stringPlayerVar->defaultValue = defaultValue;
defaultVars.emplace_back(std::move(stringPlayerVar));
}
else if constexpr (std::is_same_v<T, float>) {
auto floatPlayerVar = std::make_unique<FloatPlayerVariable>(name);
floatPlayerVar->value = value;
floatPlayerVar->defaultValue = defaultValue;
floatPlayerVar->SetValues(value);
defaultVars.emplace_back(std::move(floatPlayerVar));
}
else if constexpr (std::is_same_v<T, bool>) {
auto boolPlayerVar = std::make_unique<BoolPlayerVariable>(name);
boolPlayerVar->value = value;
boolPlayerVar->defaultValue = defaultValue;
boolPlayerVar->SetValues(value);
defaultVars.emplace_back(std::move(boolPlayerVar));
}
} else {
@ -88,17 +91,15 @@ namespace EGSDK::GamePH {
// TO IMPLEMENT
return;
} else if constexpr (std::is_same_v<T, float>) {
auto floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVarIt->get());
floatPlayerVar->value = value;
floatPlayerVar->defaultValue = defaultValue;
auto floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
floatPlayerVar->SetValues(value);
} else if constexpr (std::is_same_v<T, bool>) {
auto boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVarIt->get());
boolPlayerVar->value = value;
boolPlayerVar->defaultValue = defaultValue;
auto boolPlayerVar = dynamic_cast<BoolPlayerVariable*>(playerVar);
boolPlayerVar->SetValues(value);
}
}
}
static void processPlayerVar(DWORD64*(*playerVarsGetter)(), std::unique_ptr<PlayerVariable>& playerVar) {
static void processPlayerVar(DWORD64*(*playerVarsGetter)(), std::unique_ptr<PlayerVariable>& playerVarPtr) {
static int offset = 0;
int offsetDif = 0;
while (true) {
@ -112,46 +113,47 @@ namespace EGSDK::GamePH {
continue;
}
std::string varName = playerVar->GetName();
PlayerVarType varType = playerVar->GetType();
std::string varName = playerVarPtr->GetName();
PlayerVarType varType = playerVarPtr->GetType();
switch (playerVar->GetType()) {
case PlayerVarType::String: {
switch (playerVarPtr->GetType()) {
case PlayerVarType::String:
{
if (vTableName != "StringPlayerVariable")
return;
StringPlayerVariable* stringPlayerVar = reinterpret_cast<StringPlayerVariable*>(playerVarsGetter() + offset);
playerVar.reset(stringPlayerVar);
playerVar->SetName(varName);
playerVar->SetType(varType);
playerVarPtr.reset(stringPlayerVar);
playerVarPtr->SetName(varName);
playerVarPtr->SetType(varType);
// TO IMPLEMENT
offset += STRING_SIZE_OFFSET;
return;
}
case PlayerVarType::Float: {
case PlayerVarType::Float:
{
if (vTableName != "FloatPlayerVariable")
return;
FloatPlayerVariable* floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVarsGetter() + offset);
playerVar.reset(floatPlayerVar);
playerVar->SetName(varName);
playerVar->SetType(varType);
updateDefaultVar(PlayerVariables::defaultPlayerVars, varName, floatPlayerVar->value.data, floatPlayerVar->defaultValue.data);
playerVarPtr.reset(floatPlayerVar);
playerVarPtr->SetName(varName);
playerVarPtr->SetType(varType);
updateDefaultVar(PlayerVariables::customDefaultPlayerVars, varName, floatPlayerVar->value.data, floatPlayerVar->defaultValue.data);
offset += FLOAT_SIZE_OFFSET;
return;
}
case PlayerVarType::Bool: {
case PlayerVarType::Bool:
{
if (vTableName != "BoolPlayerVariable")
return;
BoolPlayerVariable* boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVarsGetter() + offset);
playerVar.reset(boolPlayerVar);
playerVar->SetName(varName);
playerVar->SetType(varType);
updateDefaultVar(PlayerVariables::defaultPlayerVars, varName, boolPlayerVar->value.data, boolPlayerVar->defaultValue.data);
playerVarPtr.reset(boolPlayerVar);
playerVarPtr->SetName(varName);
playerVarPtr->SetType(varType);
updateDefaultVar(PlayerVariables::customDefaultPlayerVars, varName, boolPlayerVar->value.data, boolPlayerVar->defaultValue.data);
offset += BOOL_SIZE_OFFSET;
@ -172,11 +174,11 @@ namespace EGSDK::GamePH {
if (!Get())
return;
for (auto& var : playerVars) {
for (auto& playerVarPtr : playerVars) {
__try {
processPlayerVar(reinterpret_cast<DWORD64*(*)()>(&Get), var);
processPlayerVar(reinterpret_cast<DWORD64*(*)()>(&Get), playerVarPtr);
} __except (EXCEPTION_EXECUTE_HANDLER) {
SPDLOG_ERROR("Failed to process player variable: {}", var->GetName());
SPDLOG_ERROR("Failed to process player variable: {}", playerVarPtr->GetName());
}
}

View File

@ -115,9 +115,34 @@ namespace EGT::Menu {
if (!playerVariables.GetValue())
return;
auto playerVarBeginIt = EGSDK::GamePH::PlayerVariables::playerVars.begin();
for (auto& playerVarIt = playerVarBeginIt; playerVarIt != EGSDK::GamePH::PlayerVariables::playerVars.end(); ++playerVarIt) {
auto playerVar = playerVarIt->get();
for (const auto& customPlayerVar : EGSDK::GamePH::PlayerVariables::customPlayerVars) {
if (EGSDK::GamePH::PlayerVariables::IsPlayerVarManagedByBool(customPlayerVar->GetName()))
continue;
switch (customPlayerVar->GetType()) {
case EGSDK::GamePH::PlayerVarType::String:
// TO IMPLEMENT
break;
case EGSDK::GamePH::PlayerVarType::Float:
{
EGSDK::GamePH::FloatPlayerVariable* customFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(customPlayerVar.get());
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(customFloatPlayerVar->GetName(), customFloatPlayerVar->value.data);
break;
}
case EGSDK::GamePH::PlayerVarType::Bool:
{
EGSDK::GamePH::BoolPlayerVariable* customBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(customPlayerVar.get());
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(customBoolPlayerVar->GetName(), customBoolPlayerVar->value.data);
break;
}
default:
break;
}
}
/*auto customPlayerVarBeginIt = EGSDK::GamePH::PlayerVariables::customPlayerVars.begin();
for (auto& customPlayerVarIt = customPlayerVarBeginIt; customPlayerVarIt != EGSDK::GamePH::PlayerVariables::customPlayerVars.end(); ++customPlayerVarIt) {
auto customPlayerVar = customPlayerVarIt->get();
try {
auto defPlayerVar = &EGSDK::GamePH::PlayerVariables::defaultPlayerVars.at(playerVarIt - playerVarBeginIt);
@ -148,7 +173,7 @@ namespace EGT::Menu {
UNREFERENCED_PARAMETER(e);
SPDLOG_ERROR("PlayerVarsUpdate() threw an exception! Restart the game to fix this error. If the error still happens, please open a bug report.");
}
}
}*/
}
static void PlayerHealthUpdate() {
EGSDK::GamePH::PlayerHealthModule* playerHealthModule = EGSDK::GamePH::PlayerHealthModule::Get();
@ -224,13 +249,10 @@ namespace EGT::Menu {
if (name.empty())
continue;
auto playerVarIt = std::find_if(EGSDK::GamePH::PlayerVariables::playerVars.begin(), EGSDK::GamePH::PlayerVariables::playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
if (playerVarIt == EGSDK::GamePH::PlayerVariables::playerVars.end())
auto playerVar = EGSDK::GamePH::PlayerVariables::playerVars.Find(name);
if (!playerVar)
continue;
auto playerVar = playerVarIt->get();
switch (playerVar->GetType()) {
case EGSDK::GamePH::PlayerVarType::String:
// TO IMPLEMENT
@ -288,12 +310,12 @@ namespace EGT::Menu {
}
static void RestoreVariablesToDefault() {
for (auto const& playerVar : EGSDK::GamePH::PlayerVariables::playerVars) {
for (auto const& playerVarPtr : EGSDK::GamePH::PlayerVariables::playerVars) {
auto playerVar = playerVarPtr.get();
auto& defVars = restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars : EGSDK::GamePH::PlayerVariables::defaultPlayerVars;
auto defPlayerVarIt = std::find_if(defVars.begin(), defVars.end(), [&playerVar](const auto& defPlayerVar) {
return defPlayerVar->GetName() == playerVar->GetName();
});
if (defPlayerVarIt == defVars.end())
auto defPlayerVar = defVars.Find(playerVar->GetName());
if (!defPlayerVar)
continue;
switch (playerVar->GetType()) {
@ -301,28 +323,31 @@ namespace EGT::Menu {
// TO IMPLEMENT
break;
case EGSDK::GamePH::PlayerVarType::Float: {
EGSDK::GamePH::FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defPlayerVarIt->get());
EGSDK::GamePH::FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defPlayerVar);
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(playerVar->GetName(), defFloatPlayerVar->value.data);
break;
}
case EGSDK::GamePH::PlayerVarType::Bool: {
EGSDK::GamePH::BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defPlayerVarIt->get());
EGSDK::GamePH::BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defPlayerVar);
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(playerVar->GetName(), defBoolPlayerVar->value.data);
break;
}
default:
break;
}
if (!restoreVarsToSavedVarsEnabled)
defVars.Erase(playerVar->GetName());
}
ImGui::OpenPopup("Restored player variables!");
}
static void SaveVariablesAsDefault() {
for (auto const& playerVar : EGSDK::GamePH::PlayerVariables::playerVars) {
auto defCustomPlayerVarIt = std::find_if(EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars.begin(), EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars.end(), [&playerVar](const auto& defCustomPlayerVar) {
return defCustomPlayerVar->GetName() == playerVar->GetName();
});
if (defCustomPlayerVarIt == EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars.end())
for (auto const& playerVarPtr : EGSDK::GamePH::PlayerVariables::playerVars) {
auto playerVar = playerVarPtr.get();
auto defCustomPlayerVar = EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars.Find(playerVar->GetName());
if (!defCustomPlayerVar)
continue;
switch (playerVar->GetType()) {
@ -330,14 +355,14 @@ namespace EGT::Menu {
// TO IMPLEMENT
break;
case EGSDK::GamePH::PlayerVarType::Float: {
EGSDK::GamePH::FloatPlayerVariable* floatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar.get());
EGSDK::GamePH::FloatPlayerVariable* defCustomFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defCustomPlayerVarIt->get());
EGSDK::GamePH::FloatPlayerVariable* floatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar);
EGSDK::GamePH::FloatPlayerVariable* defCustomFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defCustomPlayerVar);
defCustomFloatPlayerVar->value = floatPlayerVar->value;
break;
}
case EGSDK::GamePH::PlayerVarType::Bool: {
EGSDK::GamePH::BoolPlayerVariable* boolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar.get());
EGSDK::GamePH::BoolPlayerVariable* defCustomBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defCustomPlayerVarIt->get());
EGSDK::GamePH::BoolPlayerVariable* boolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar);
EGSDK::GamePH::BoolPlayerVariable* defCustomBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defCustomPlayerVar);
defCustomBoolPlayerVar->value = boolPlayerVar->value;
break;
}
@ -350,33 +375,34 @@ namespace EGT::Menu {
}
static void RestoreVariableToDefault(const std::string& name) {
auto& defVars = restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars : EGSDK::GamePH::PlayerVariables::defaultPlayerVars;
auto defPlayerVarIt = std::find_if(defVars.begin(), defVars.end(), [&name](const auto& defPlayerVar) {
return defPlayerVar->GetName() == name;
});
if (defPlayerVarIt == defVars.end())
auto defPlayerVar = defVars.Find(name);
if (!defPlayerVar)
return;
switch (defPlayerVarIt->get()->GetType()) {
switch (defPlayerVar->GetType()) {
case EGSDK::GamePH::PlayerVarType::String:
// TO IMPLEMENT
break;
case EGSDK::GamePH::PlayerVarType::Float: {
EGSDK::GamePH::FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defPlayerVarIt->get());
EGSDK::GamePH::FloatPlayerVariable* defFloatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defPlayerVar);
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(name, defFloatPlayerVar->value.data);
break;
}
case EGSDK::GamePH::PlayerVarType::Bool: {
EGSDK::GamePH::BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defPlayerVarIt->get());
EGSDK::GamePH::BoolPlayerVariable* defBoolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defPlayerVar);
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(name, defBoolPlayerVar->value.data);
break;
}
default:
break;
}
if (!restoreVarsToSavedVarsEnabled)
defVars.Erase(name);
}
static bool shouldDisplayVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVar, const std::string& searchFilter) {
if (playerVar->GetType() == EGSDK::GamePH::PlayerVarType::String || playerVar->GetType() == EGSDK::GamePH::PlayerVarType::NONE) // TO IMPLEMENT
static bool shouldDisplayVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr, const std::string& searchFilter) {
if (playerVarPtr->GetType() == EGSDK::GamePH::PlayerVarType::String || playerVarPtr->GetType() == EGSDK::GamePH::PlayerVarType::NONE) // TO IMPLEMENT
return false;
if (searchFilter.empty())
return true;
@ -386,15 +412,15 @@ namespace EGT::Menu {
std::transform(lowerFilter.begin(), lowerFilter.end(), lowerFilter.begin(), ::tolower);
// Convert variable name to lowercase and check if it contains the filter
std::string lowerKey = playerVar->GetName();
std::string lowerKey = playerVarPtr->GetName();
std::transform(lowerKey.begin(), lowerKey.end(), lowerKey.begin(), ::tolower);
return lowerKey.find(lowerFilter) != std::string::npos;
}
static void renderDebugInfo(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVar) {
static void renderDebugInfo(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
const float maxInputTextWidth = ImGui::CalcTextSize("0x0000000000000000").x;
static std::string labelID{};
labelID = "##DebugAddrInputText" + std::string(playerVar->GetName());
DWORD64 finalVarValueAddr = reinterpret_cast<DWORD64>(playerVar.get()) + 0x8;
labelID = "##DebugAddrInputText" + std::string(playerVarPtr->GetName());
DWORD64 finalVarValueAddr = reinterpret_cast<DWORD64>(playerVarPtr.get()) + 0x8;
std::stringstream ss;
if (finalVarValueAddr)
@ -413,27 +439,23 @@ namespace EGT::Menu {
ImGui::InputText(labelID.c_str(), const_cast<char*>(addrString.c_str()), strlen(addrString.c_str()), ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleColor();
}
static void renderPlayerVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVar) {
switch (playerVar->GetType()) {
static void renderPlayerVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
switch (playerVarPtr->GetType()) {
case EGSDK::GamePH::PlayerVarType::String:
// TO IMPLEMENT
break;
case EGSDK::GamePH::PlayerVarType::Float: {
EGSDK::GamePH::FloatPlayerVariable* floatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar.get());
EGSDK::GamePH::FloatPlayerVariable* floatPlayerVar = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVarPtr.get());
float newValue = floatPlayerVar->value;
if (ImGui::InputFloat(floatPlayerVar->GetName(), &newValue)) {
floatPlayerVar->value = newValue;
floatPlayerVar->defaultValue = newValue;
}
if (ImGui::InputFloat(floatPlayerVar->GetName(), &newValue))
EGSDK::GamePH::PlayerVariables::ChangePlayerVarFromList(floatPlayerVar->GetName(), newValue, playerVarPtr.get());
break;
}
case EGSDK::GamePH::PlayerVarType::Bool: {
EGSDK::GamePH::BoolPlayerVariable* boolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar.get());
EGSDK::GamePH::BoolPlayerVariable* boolPlayerVar = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVarPtr.get());
bool newValue = boolPlayerVar->value;
if (ImGui::Checkbox(boolPlayerVar->GetName(), &newValue)) {
boolPlayerVar->value = newValue;
boolPlayerVar->defaultValue = newValue;
}
if (ImGui::Checkbox(boolPlayerVar->GetName(), &newValue))
EGSDK::GamePH::PlayerVariables::ChangePlayerVarFromList(boolPlayerVar->GetName(), newValue, playerVarPtr.get());
break;
}
default:
@ -442,12 +464,16 @@ namespace EGT::Menu {
ImGui::SameLine();
static std::string restoreBtnName{};
restoreBtnName = "Restore##" + std::string(playerVar->GetName());
if (ImGui::Button(restoreBtnName.c_str(), "Restores player variable to default"))
RestoreVariableToDefault(playerVar->GetName());
restoreBtnName = "Restore##" + std::string(playerVarPtr->GetName());
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::customPlayerVars.none_of(playerVarPtr->GetName()));
{
if (ImGui::Button(restoreBtnName.c_str(), "Restores player variable to default"))
RestoreVariableToDefault(playerVarPtr->GetName());
ImGui::EndDisabled();
}
if (debugEnabled)
renderDebugInfo(playerVar);
renderDebugInfo(playerVarPtr);
}
static void HandlePlayerVariablesList() {
if (!playerVariables.GetValue())
@ -475,11 +501,11 @@ namespace EGT::Menu {
ImGui::Separator();
ImGui::InputTextWithHint("##VarsSearch", "Search variables", playerVarsSearchFilter, 64);
for (auto const& playerVar : EGSDK::GamePH::PlayerVariables::playerVars) {
if (!shouldDisplayVariable(playerVar, playerVarsSearchFilter))
for (auto const& playerVarPtr : EGSDK::GamePH::PlayerVariables::playerVars) {
if (!shouldDisplayVariable(playerVarPtr, playerVarsSearchFilter))
continue;
renderPlayerVariable(playerVar);
renderPlayerVariable(playerVarPtr);
}
ImGui::Unindent();