Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 39 additions & 16 deletions src/game/frontend/submenus/Recovery/StatEditor.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#include "StatEditor.hpp"
#include "core/backend/FiberPool.hpp"
#include "core/backend/FiberPool.hpp"
#include "core/frontend/widgets/imgui_bitfield.hpp"
#include "game/backend/AnticheatBypass.hpp"
#include "game/pointers/Pointers.hpp"
#include "game/gta/Natives.hpp"
#include "game/gta/Stats.hpp"
#include "game/pointers/Pointers.hpp"
#include "StatEditor.hpp"
#include "types/stats/CStatsMgr.hpp"

namespace YimMenu::Submenus
{
struct StatInfo
{
std::string m_Name;
std::uint32_t m_NameHash;
std::uint32_t m_NameHash = 0;
bool m_Normalized = false;
sStatData* m_Data = nullptr;

bool IsValid()
bool IsValid() const
{
return m_Data != nullptr;
}
Expand All @@ -26,7 +28,7 @@ namespace YimMenu::Submenus
bool m_IsBoolStat;
bool m_IsValid;

bool IsValid()
bool IsValid() const
{
return m_IsValid;
}
Expand Down Expand Up @@ -128,6 +130,7 @@ namespace YimMenu::Submenus
value.m_AsU64 = data->GetInt64();
return;
case sStatData::Type::UINT64:
case sStatData::Type::PACKED:
value.m_AsU64 = data->GetUInt64();
return;
case sStatData::Type::STRING:
Expand All @@ -154,16 +157,30 @@ namespace YimMenu::Submenus
case sStatData::Type::UINT8:
STATS::STAT_SET_INT(hash, value.m_AsInt, true);
return;
case sStatData::Type::INT64:
data->SetInt64(value.m_AsU64); // TODO this isn't a good idea! natives can't set this
case sStatData::Type::INT64:
data->SetInt64(value.m_AsU64 - 1);
STATS::STAT_INCREMENT(hash, static_cast<float>(1));
return;
case sStatData::Type::UINT64:
STATS::STAT_SET_MASKED_INT(hash, (std::uint32_t)value.m_AsU64, 0, 32, true);
STATS::STAT_SET_MASKED_INT(hash, (std::uint32_t)(value.m_AsU64 >> 32), 32, 32, true);
//Stats::SetMaskedAll(hash, value.m_AsU64);
//This code is simpler
//After writing, restarting will restore the data
data->SetUInt64(value.m_AsU64 - 1);
//You need to use STATS::STAT_INCREMENT to save the data on the server.
STATS::STAT_INCREMENT(hash, static_cast<float>(1));
return;
case sStatData::Type::STRING:
STATS::STAT_SET_STRING(hash, value.m_AsString, true);
return;
case sStatData::Type::PACKED:
/*data->SetUInt64(value.m_AsU64 - 1);
Packed data can't be written using STATS::STAT_INCREMENT
STATS::STAT_INCREMENT(hash, static_cast<float>(1));*/
Stats::SetMaskedAll(hash, value.m_AsU64);
return;
case sStatData::Type::POS:
case sStatData::Type::DATE:
case sStatData::Type::PROFILE_SETTING:
default:
return; // data type not supported
}
Expand Down Expand Up @@ -208,20 +225,24 @@ namespace YimMenu::Submenus
case sStatData::Type::INT64:
{
auto int64_ = std::strtoll(value.data(), nullptr, 10);
data->SetInt64(int64_); // TODO this isn't a good idea! natives can't set this
data->SetInt64(int64_-1);
STATS::STAT_INCREMENT(hash, static_cast<float>(1));
return;
}
case sStatData::Type::UINT64:
{
auto uint64_ = std::strtoull(value.data(), nullptr, 10);

STATS::STAT_SET_MASKED_INT(hash, (std::uint32_t)uint64_, 0, 32, true);
STATS::STAT_SET_MASKED_INT(hash, (std::uint32_t)(uint64_ >> 32), 32, 32, true);
data->SetUInt64(uint64_ - 1);
STATS::STAT_INCREMENT(hash, static_cast<float>(1));
return;
}
case sStatData::Type::STRING:
STATS::STAT_SET_STRING(hash, value.data(), true);
return;
case sStatData::Type::PACKED:
auto uint64_ = std::strtoull(value.data(), nullptr, 10);
Stats::SetMaskedAll(hash, uint64_);
return;
default:
return; // data type not supported
}
Expand All @@ -245,11 +266,13 @@ namespace YimMenu::Submenus
case sStatData::Type::UINT8:
return ImGui::InputScalar("Value", ImGuiDataType_U8, &value.m_AsInt);
case sStatData::Type::INT64:
return ImGui::InputScalar("Value", ImGuiDataType_S64, &value.m_AsInt);
return ImGui::InputScalar("Value", ImGuiDataType_S64, &value.m_AsU64);
case sStatData::Type::UINT64:
return ImGui::InputScalar("Value", ImGuiDataType_U64, &value.m_AsInt);
return ImGui::InputScalar("Value", ImGuiDataType_U64, &value.m_AsU64);
case sStatData::Type::STRING:
return ImGui::InputText("Value", value.m_AsString, sizeof(value.m_AsString));
case sStatData::Type::PACKED:
return ImGui::Bitfield("Value", &value.m_AsU64);
default:
ImGui::BeginDisabled();
ImGui::Text("Data type not supported");
Expand Down
58 changes: 57 additions & 1 deletion src/game/gta/Stats.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Stats.hpp"
#include "Stats.hpp"
#include "game/gta/Natives.hpp"

namespace YimMenu::Stats
Expand Down Expand Up @@ -132,4 +132,60 @@ namespace YimMenu::Stats
STATS::STAT_GET_MASKED_INT(Joaat(statName), &value, bitIndex, bitSize, -1);
return value;
}


void Stats::SetMaskedAll(Hash hash, uint64_t value)
{
uint64_t uint64_value = value;
int part0 = uint64_value & 0xFFFFu;
int part1 = (uint64_value >> 16) & 0xFFFFu;
int part2 = (uint64_value >> 32) & 0xFFFFu;
int part3 = (uint64_value >> 48) & 0xFFFFu;
// The second input parameter is of type int. Using -1 will cause the entire data to overflow
//so you have to split the 64-bit data into 4 parts to write it.
STATS::STAT_SET_MASKED_INT(hash, part0, 0, 16, true); //bit0-bit15
STATS::STAT_SET_MASKED_INT(hash, part1, 16, 16, true); //bit16-bit31
STATS::STAT_SET_MASKED_INT(hash, part2, 32, 16, true); //bit32-bit47
STATS::STAT_SET_MASKED_INT(hash, part3, 48, 16, true); //bit48-bit63
}

void Stats::SetMaskedAll(std::string statName, uint64_t value)
{
ConvertMPX(statName);
uint64_t uint64_value = value;
int part0 = uint64_value & 0xFFFFu;
int part1 = (uint64_value >> 16) & 0xFFFFu;
int part2 = (uint64_value >> 32) & 0xFFFFu;
int part3 = (uint64_value >> 48) & 0xFFFFu;

auto hash = Joaat(statName);
STATS::STAT_SET_MASKED_INT(hash, part0, 0, 16, true); //bit0-bit15
STATS::STAT_SET_MASKED_INT(hash, part1, 16, 16, true); //bit16-bit31
STATS::STAT_SET_MASKED_INT(hash, part2, 32, 16, true); //bit32-bit47
STATS::STAT_SET_MASKED_INT(hash, part3, 48, 16, true); //bit48-bit63
}

uint64_t GetMaskedAll(Hash hash, int playerindex)
{
int part0 = 0, part1 = 0, part2 = 0, part3 = 0;
STATS::STAT_GET_MASKED_INT(hash, &part0, 0, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part1, 16, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part2, 32, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part3, 48, 16, playerindex);
uint64_t value = (static_cast<uint64_t>(part3) << 48) | (static_cast<uint64_t>(part2) << 32) | (static_cast<uint64_t>(part1) << 16) | part0;
return value;
}

uint64_t GetMaskedAll(std::string statName, int playerindex)
{
Hash hash = Joaat(statName);
int part0 = 0, part1 = 0, part2 = 0, part3 = 0;
STATS::STAT_GET_MASKED_INT(hash, &part0, 0, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part1, 16, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part2, 32, 16, playerindex);
STATS::STAT_GET_MASKED_INT(hash, &part3, 48, 16, playerindex);
uint64_t value = (static_cast<uint64_t>(part3) << 48) | (static_cast<uint64_t>(part2) << 32) | (static_cast<uint64_t>(part1) << 16) | part0;
return value;
}

}
11 changes: 9 additions & 2 deletions src/game/gta/Stats.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "core/util/Joaat.hpp"
#include "types/script/types.hpp"

Expand All @@ -7,7 +7,7 @@ namespace YimMenu::Stats
extern int GetCharIndex();

extern void SetInt(std::string statName, int value);
extern void SetBool(std::string statName, bool value);
extern void SetBool(std::string statName, bool value = true);
extern void SetFloat(std::string statName, float value);
extern void SetDate(std::string statName, Date* value);
extern void SetString(std::string statName, const char* value);
Expand All @@ -26,4 +26,11 @@ namespace YimMenu::Stats
extern void SetMaskedInt(std::string statName, int bitStart, int bitSize, int value);
extern bool GetMaskedBool(std::string statName, int bitIndex);
extern int GetMaskedInt(std::string statName, int bitIndex, int bitSize);

//You can directly write/read all packed int/bool and uint64 statistics.
//pos/date seems to work too,but the data structure is still unclear for now.
extern void SetMaskedAll(std::string statName, uint64_t value);
extern void SetMaskedAll(Hash hash, uint64_t value);
uint64_t GetMaskedAll(Hash hash, int playerindex=-1);
uint64_t GetMaskedAll(std::string statName, int playerindex = -1);
}
9 changes: 7 additions & 2 deletions src/types/stats/sStatData.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once
#pragma once

class sStatData
{
public:
enum class Type
{
NONE=0,
INT = 1,
FLOAT,
STRING,
Expand All @@ -15,7 +16,11 @@ class sStatData
UINT64,
DATE = 20,
POS,
INT64 = 26,
TEXTLABEL = 22,
PACKED = 23,
USERID = 24,
PROFILE_SETTING = 25,
INT64 = 26
};

// it isn't recommended to call the SetXXX() functions directly, use the natives instead
Expand Down