Finish switch to toml, fix hotkey saving

This commit is contained in:
Grinch_ 2022-06-16 16:40:46 +06:00
parent 9613354939
commit 6dfadd3470
23 changed files with 360 additions and 25851 deletions

File diff suppressed because it is too large Load Diff

102
depend/toml_addon.hpp Normal file
View File

@ -0,0 +1,102 @@
#pragma once
#include "toml.hpp"
template <typename T, typename Path>
auto build_from_path(T&& value, Path&& path_component)
{
using component_type = std::remove_cv_t<std::remove_reference_t<Path>>;
static_assert(std::is_integral_v<component_type> || toml::is_key_or_convertible<Path&&>,
"path components must be integers or strings");
// making an array
if constexpr (std::is_integral_v<component_type>)
{
toml::array arr;
const auto index = static_cast<std::size_t>(path_component);
arr.reserve(index + 1u);
// backfill with integers
while (arr.size() < index)
arr.push_back(0);
// add the actual value
arr.push_back(static_cast<T&&>(value));
return arr;
}
else // making a table
{
toml::table tbl;
tbl.insert_or_assign(path_component, value);
return tbl;
}
}
template <typename T, typename Path, typename... Paths>
auto build_from_path(T&& value, Path&& path_component, Paths&&... path_components)
{
static_assert(sizeof...(Paths));
return build_from_path(build_from_path(value, path_components...), path_component);
}
static void merge_left(toml::table& lhs, toml::table&& rhs);
static void merge_left(toml::array& lhs, toml::array&& rhs)
{
rhs.for_each(
[&](std::size_t index, auto&& rhs_val)
{
// rhs index not found in lhs - direct move
if (lhs.size() <= index)
{
lhs.push_back(std::move(rhs_val));
return;
}
// both elements were the same container type - recurse into them
if constexpr (toml::is_container<decltype(rhs_val)>)
{
using rhs_type = std::remove_cv_t<std::remove_reference_t<decltype(rhs_val)>>;
if (auto lhs_child = lhs[index].as<rhs_type>())
{
merge_left(*lhs_child, std::move(rhs_val));
return;
}
}
// replace lhs element with rhs
lhs.replace(lhs.cbegin() + index, std::move(rhs_val));
});
}
static void merge_left(toml::table& lhs, toml::table&& rhs)
{
rhs.for_each(
[&](const toml::key& rhs_key, auto&& rhs_val)
{
auto lhs_it = lhs.lower_bound(rhs_key);
// rhs key not found in lhs - direct move
if (lhs_it == lhs.cend() || lhs_it->first != rhs_key)
{
using rhs_type = std::remove_cv_t<std::remove_reference_t<decltype(rhs_val)>>;
lhs.emplace_hint<rhs_type>(lhs_it, rhs_key, std::move(rhs_val));
return;
}
// both children were the same container type - recurse into them
if constexpr (toml::is_container<decltype(rhs_val)>)
{
using rhs_type = std::remove_cv_t<std::remove_reference_t<decltype(rhs_val)>>;
if (auto lhs_child = lhs_it->second.as<rhs_type>())
{
merge_left(*lhs_child, std::move(rhs_val));
return;
}
}
// replace lhs value with rhs
lhs.insert_or_assign(rhs_key, std::move(rhs_val));
});
}

View File

@ -4,7 +4,7 @@
#
# [Category Name]
# location_name = "interior_id, position_x, position_y, position_z"
#########
##############################################################################
[Custom]

View File

@ -1,90 +1,93 @@
##############################################################################
# Particle Names
# Example: Category = ["name1", "name2"]
# Example,
# [Category Name]
# particle_name = ""
##############################################################################
Custom = []
Main = [
"prt_blood",
"prt_boatsplash",
"prt_bubbles",
"prt_cardebris",
"prt_collisionsmoke",
"prt_glass",
"prt_gunshell",
"prt_sand",
"prt_sand2",
"prt_smokeII_3_expand",
"prt_smoke_huge",
"prt_spark",
"prt_spark2",
"prt_splash",
"prt_wake",
"prt_watersplash",
"prt_wheeldirt",
"boat_prop",
"camflash",
"exhale",
"explosion_fuel_car",
"explosion_large",
"explosion_medium",
"explosion_molotov",
"explosion_small",
"explosion_tiny",
"extinguisher",
"fire",
"fire_bike",
"fire_car",
"fire_large",
"fire_med",
"flamethrower",
"gunflash",
"gunsmoke",
"heli_dust",
"jetpack",
"jetthrust",
"molotov_flame",
"nitro",
"overheat_car",
"overheat_car_electric",
"riot_smoke",
"spraycan",
"tank_fire",
"teargas",
"teargasAD",
"water_hydrant",
"water_ripples",
"water_speed",
"water_splash",
"water_splsh_big",
"water_splsh_sml",
"water_swim",
"cigarette_smoke",
"flame",
"insects",
"smoke30lit",
"smoke30m",
"smoke50lit",
"vent",
"vent2",
"waterfall_end",
"water_fnt_tme",
"water_fountain",
"tree_hit_fir",
"tree_hit_palm",
"blood_heli",
"carwashspray",
"cement",
"cloudfast",
"coke_puff",
"coke_trail",
"explosion_barrel",
"explosion_crate",
"explosion_door",
"petrolcan",
"puke",
"shootlight",
"smoke_flare",
"wallbust",
"ws_factorysmoke"
]
[Custom]
[Main]
prt_blood = ""
prt_boatsplash = ""
prt_bubbles = ""
prt_cardebris = ""
prt_collisionsmoke = ""
prt_glass = ""
prt_gunshell = ""
prt_sand = ""
prt_sand2 = ""
prt_smokeII_3_expand = ""
prt_smoke_huge = ""
prt_spark = ""
prt_spark2 = ""
prt_splash = ""
prt_wake = ""
prt_watersplash = ""
prt_wheeldirt = ""
boat_prop = ""
camflash = ""
exhale = ""
explosion_fuel_car = ""
explosion_large = ""
explosion_medium = ""
explosion_molotov = ""
explosion_small = ""
explosion_tiny = ""
extinguisher = ""
fire = ""
fire_bike = ""
fire_car = ""
fire_large = ""
fire_med = ""
flamethrower = ""
gunflash = ""
gunsmoke = ""
heli_dust = ""
jetpack = ""
jetthrust = ""
molotov_flame = ""
nitro = ""
overheat_car = ""
overheat_car_electric = ""
riot_smoke = ""
spraycan = ""
tank_fire = ""
teargas = ""
teargasAD = ""
water_hydrant = ""
water_ripples = ""
water_speed = ""
water_splash = ""
water_splsh_big = ""
water_splsh_sml = ""
water_swim = ""
cigarette_smoke = ""
flame = ""
insects = ""
smoke30lit = ""
smoke30m = ""
smoke50lit = ""
vent = ""
vent2 = ""
waterfall_end = ""
water_fnt_tme = ""
water_fountain = ""
tree_hit_fir = ""
tree_hit_palm = ""
blood_heli = ""
carwashspray = ""
cement = ""
cloudfast = ""
coke_puff = ""
coke_trail = ""
explosion_barrel = ""
explosion_crate = ""
explosion_door = ""
petrolcan = ""
puke = ""
shootlight = ""
smoke_flare = ""
wallbust = ""
ws_factorysmoke = ""

View File

@ -143,7 +143,7 @@
"InvalidValue": "Invalid value",
"Language": "Language",
"LanguageChangeFailed": "Failed to change language!",
"LatestVersion" : "Latest version",
"LatestVersion" : "Latest version: ",
"Location": "Location: %s",
"Name": "Name",
"NewVersion" : "A new version of the menu is available.",

View File

@ -53,8 +53,8 @@ void CheatMenu::DrawWindow()
else
m_fMenuSize = ImGui::GetWindowSize();
gConfig.SetValue("window.sizeX", m_fMenuSize.x);
gConfig.SetValue("window.sizeY", m_fMenuSize.y);
gConfig.Set("Window.SizeX", m_fMenuSize.x);
gConfig.Set("Window.SizeY", m_fMenuSize.y);
ImGui::PopStyleVar(2);
ImGui::End();
@ -94,11 +94,11 @@ void CheatMenu::ProcessPages()
* We don't want to be annoying and
* show anniversary screen on every game start
*/
bool flag = gConfig.GetValue("window.anniversaryShown", false);
bool flag = gConfig.Get("Window.AnniversaryShown", false);
if (!flag)
{
gConfig.SetValue("window.anniversaryShown", true);
gConfig.Set("Window.AnniversaryShown", true);
m_nMenuPage = eMenuPages::ANNIVERSARY;
}
}
@ -137,7 +137,7 @@ void CheatMenu::ProcessPages()
{
m_nMenuPage = m_headerList[i].page;
size_t curPage = static_cast<size_t>(m_headerList[i].page);
gConfig.SetValue("window.page", curPage);
gConfig.Set("Window.CurrentPage", curPage);
pCallback = m_headerList[i].pFunc;
Updater::ResetUpdaterState();
}
@ -210,9 +210,9 @@ void CheatMenu::Init()
}
// Load menu settings
m_nMenuPage = (eMenuPages)gConfig.GetValue("window.page", (size_t)eMenuPages::WELCOME);
m_fMenuSize.x = gConfig.GetValue("window.sizeX", screen::GetScreenWidth() / 4.0f);
m_fMenuSize.y = gConfig.GetValue("window.sizeY", screen::GetScreenHeight() / 1.2f);
m_nMenuPage = (eMenuPages)gConfig.Get("Window.CurrentPage", (size_t)eMenuPages::WELCOME);
m_fMenuSize.x = gConfig.Get("Window.SizeX", screen::GetScreenWidth() / 4.0f);
m_fMenuSize.y = gConfig.Get("Window.SizeY", screen::GetScreenHeight() / 1.2f);
srand(CTimer::m_snTimeInMilliseconds);
ApplyStyle();

View File

@ -1,10 +1,16 @@
#include "datastore.h"
#include "pch.h"
DataStore::DataStore(const char* fileName, bool isConfig) noexcept
DataStore::DataStore(const char* fileName, bool isPathPredefined) noexcept
{
// Output config file in the same directory as the asi
path = PLUGIN_PATH((char*)(isConfig ? "/" : "/CheatMenu/data/")) + std::string(fileName) + fileExt;
if (isPathPredefined)
{
path = std::string(fileName) + fileExt;
}
else
{
path = PLUGIN_PATH((char*)"/CheatMenu/data/") + std::string(fileName) + fileExt;
}
if (std::filesystem::exists(path))
{
@ -21,7 +27,7 @@ DataStore::DataStore(const char* fileName, bool isConfig) noexcept
{
pTable = std::make_unique<toml::table>();
if (isConfig)
if (fileName == FILE_NAME)
{
Log::Print<eLogLevel::Info>("Creating {}{}", fileName, fileExt);
}
@ -59,7 +65,7 @@ void DataStore::RemoveKey(const char* key, const char* entry) noexcept
{
if (pTable)
{
(*pTable)[key].as_table()->erase(entry);
(*pTable).at_path(key).as_table()->erase(entry);
}
}

View File

@ -1,8 +1,9 @@
#pragma once
#define TOML_EXCEPTIONS 0
#include "../depend/toml.hpp"
#include "../depend/toml_addon.hpp"
#include <memory>
/*
DataStore Class
Stores & loads data from disk
@ -18,44 +19,63 @@ private:
public:
typedef toml::table Table;
DataStore(const char* fileName, bool isConfig = false) noexcept;
DataStore(const char* fileName, bool isPathPredefined = false) noexcept;
// Returns data from store structure
std::string Get(const char* key, const char* defaultVal) noexcept
{
if (pTable)
{
return (*pTable).at_path(key).value_or(defaultVal);
}
return defaultVal;
}
template<typename T>
T Get(const char* key, const T& defaultVal) noexcept
{
if (pTable)
{
return (*pTable)[key].value_or(defaultVal);
return (*pTable).at_path(key).value_or(defaultVal);
}
return defaultVal;
}
std::string Get(const char* key, std::string&& defaultVal) noexcept
{
if (pTable)
{
return (*pTable)[key].value_or(defaultVal);
}
return defaultVal;
}
// Sets data in store structure
// Adds data to the structure
template <typename T>
void Set(const char* key, const T& value) noexcept
void Set(const char* key, T&& value)
{
if (pTable)
std::stringstream ss(key);
std::vector<std::string> paths;
while(ss.good())
{
(*pTable)[key] = value;
std::string s1 = "";
getline(ss, s1, '.');
if (s1 != "")
{
paths.push_back(std::move(s1));
}
}
void Set(const char* key, std::string&& value) noexcept
// assign the value
toml::table tbl;
int startIndex = paths.size()-1;
for (int i = startIndex; i >= 0; --i)
{
if (pTable)
if (i == startIndex)
{
(*pTable)[key].ref<std::string>() = value;
tbl.insert_or_assign(paths[i], std::move(value));
}
else
{
toml::table temp;
temp.insert_or_assign(paths[i], std::move(tbl));
tbl = std::move(temp);
}
}
merge_left(*pTable, std::move(tbl));
}
// If store contains element

View File

@ -9,7 +9,7 @@
#define MENU_NAME "Cheat Menu"
#define MENU_VERSION_NUMBER "3.3"
#define MENU_VERSION MENU_VERSION_NUMBER"-beta"
#define BUILD_NUMBER "20220612"
#define BUILD_NUMBER "20220616"
#define MENU_TITLE MENU_NAME " v" MENU_VERSION
#ifdef GTASA

View File

@ -69,18 +69,18 @@ void MenuThread(void* param)
}
#endif
Log::Print<eLogLevel::None>("\nVersion: " MENU_TITLE "\nAuthor: Grinch_\nDiscord: " DISCORD_INVITE "\nMore Info: " GITHUB_LINK "\n");
Log::Print<eLogLevel::None>("Version: " MENU_TITLE "\nAuthor: Grinch_\nDiscord: " DISCORD_INVITE "\nMore Info: " GITHUB_LINK "\n");
CheatMenu::Init();
// Checking for updates once a day
SYSTEMTIME st;
GetSystemTime(&st);
if (gConfig.GetValue("config.update_date", 0) != st.wDay)
if (gConfig.Get("config.update_date", 0) != st.wDay)
{
Updater::CheckUpdate();
Updater::IncrementDailyUsageCounter();
gConfig.SetValue("config.update_date", st.wDay);
gConfig.Set("config.update_date", st.wDay);
}
while (true)

View File

@ -4,7 +4,7 @@
class Game
{
private:
static inline ResourceStore m_MissionData{ "mission", eResourceType::TYPE_TEXT };
static inline ResourceStore m_MissionData{ "missions", eResourceType::TYPE_TEXT };
static inline bool m_bDisableCheats;
static inline bool m_bDisableReplay;
static inline bool m_bMissionTimer;

View File

@ -179,8 +179,8 @@ Hotkey::Hotkey(int key1, int key2, const std::string& configPath)
{
if (m_ConfigPath != "")
{
m_key1 = gConfig.GetValue(m_ConfigPath + ".1", m_key1);
m_key2 = gConfig.GetValue(m_ConfigPath + ".2", m_key2);
m_key1 = gConfig.Get((m_ConfigPath + ".Key1").c_str(), m_key1);
m_key2 = gConfig.Get((m_ConfigPath + ".Key2").c_str(), m_key2);
}
}
@ -232,8 +232,8 @@ bool Hotkey::DrawUI(const char* label)
// Save the hotkeys in config file
if (m_ConfigPath != "")
{
gConfig.SetValue(m_ConfigPath + "1", m_key1);
gConfig.SetValue(m_ConfigPath + "2", m_key2);
gConfig.Set((m_ConfigPath + ".Key1").c_str(), m_key1);
gConfig.Set((m_ConfigPath + ".Key2").c_str(), m_key2);
}
}

View File

@ -1,54 +0,0 @@
#include "json.h"
#include "pch.h"
CJson::CJson(const char* name, bool pathPredefined)
{
if (name == "" || !std::filesystem::is_directory(PLUGIN_PATH((char*)"CheatMenu")))
{
return;
}
if (pathPredefined)
{
m_FilePath = name;
}
else
{
m_FilePath = PLUGIN_PATH((char*)"/CheatMenu/json/") + std::string(name) + ".json";
}
if (std::filesystem::exists(m_FilePath))
{
try
{
std::ifstream file(m_FilePath);
file >> m_Data;
file.close();
}
catch (...)
{
//gLog << "Error trying to read " << m_FilePath << std::endl;
m_Data = "{}"_json;
}
}
else
{
m_Data = "{}"_json;
if (m_FilePath.find("config"))
{
//gLog << "Creating config.json file" << std::endl;
}
else
{
//gLog << "Failed to locate file " << m_FilePath << std::endl;
}
}
}
void CJson::Save()
{
std::ofstream file(m_FilePath);
file << m_Data.dump(4, ' ', false, nlohmann::json::error_handler_t::replace) << std::endl;
file.close();
}

View File

@ -1,122 +0,0 @@
#pragma once
#include "../depend/json.hpp"
/*
Wrapper class for nlohmann::json
Contains helper methods
*/
class CJson
{
private:
std::string m_FilePath;
public:
nlohmann::json m_Data;
/*
Returns a value from json structure hierarchy using '.'
Example: "Menu.Window.X"
*/
// specialize since typeid(std::string) doesn't work
template <typename T>
T inline GetValue(std::string&& key, const T& defaultVal)
{
try
{
std::stringstream ss(key);
std::string line;
nlohmann::json* json = &m_Data;
while (getline(ss, line, '.'))
{
json = &((*json)[line]);
}
// json library bugs with bool, using int instead
if (typeid(T) == typeid(bool))
{
return ((json->get<int>() == 1) ? true : false);
}
return json->get<T>();
}
catch (...)
{
return defaultVal;
}
}
std::string inline GetValueStr(const std::string& key, const std::string& defaultVal)
{
try
{
std::stringstream ss(key);
std::string line;
nlohmann::json* json = &m_Data;
while (getline(ss, line, '.'))
{
json = &((*json)[line]);
}
return json->get<std::string>();
}
catch (...)
{
return defaultVal;
}
}
/*
Allows to save values in json hierarchy using '.'
Example: "Menu.Window.X"
*/
template <typename T>
void inline SetValue(std::string&& key, const T& val)
{
std::stringstream ss(key);
std::string line;
nlohmann::json* json = &m_Data;
while (getline(ss, line, '.'))
{
json = &((*json)[line]);
}
// json library bugs with bool, using int instead
if (typeid(T) == typeid(bool))
{
*json = (val ? 1 : 0);
}
else
{
*json = val;
}
}
template <>
void inline SetValue(std::string&& key, const std::string& val)
{
std::stringstream ss(key);
std::string line;
nlohmann::json* json = &m_Data;
while (getline(ss, line, '.'))
{
json = &((*json)[line]);
}
*json = val;
}
/*
Saves json data to disk
*/
void Save();
CJson(const char* text, bool pathPredefined = false);
};

View File

@ -34,7 +34,7 @@ Locale::eReturnCodes Locale::Init(const char* path, const char* def, const char*
#endif
for (auto& entry : std::filesystem::directory_iterator(m_path))
{
if (entry.path().extension() == ".json")
if (entry.path().extension() == ".toml")
{
std::string fileName = entry.path().stem().string();
#ifdef _GTA_
@ -44,14 +44,14 @@ Locale::eReturnCodes Locale::Init(const char* path, const char* def, const char*
if (!strcmp(fallback, fileName.c_str()))
{
std::string localePath = m_path + fileName + ".json";
std::string localePath = m_path + fileName;
if(m_pCallbackJson)
if(m_pCallbackData)
{
delete m_pCallbackJson;
m_pCallbackJson = nullptr;
delete m_pCallbackData;
m_pCallbackData = nullptr;
}
m_pCallbackJson = new CJson(localePath.c_str(), true);
m_pCallbackData = new DataStore(localePath.c_str(), true);
}
}
}
@ -113,12 +113,32 @@ Locale::eReturnCodes Locale::SetLocale(size_t index)
{
return eReturnCodes::INVALID_INDEX;
}
std::string localeFile = m_locales[index];
localeFile += ".json";
std::string localePath = m_path + localeFile;
m_pData = new CJson(localePath.c_str(), true);
std::string localePath = m_path + m_locales[index];
m_pData = new DataStore(localePath.c_str(), true);
localeIndex = index;
return eReturnCodes::SUCCESS;
}
std::string Locale::GetText(std::string&& key, std::string&& defaultValue)
{
if (m_pData == nullptr)
{
return defaultValue;
}
// Return keyname if no default value is provided
if (defaultValue == "")
{
defaultValue = "#" + key;
}
std::string rtn = m_pData->Get(key.c_str(), defaultValue);
if (rtn == defaultValue)
{
return m_pCallbackData->Get(key.c_str(), defaultValue);
}
return rtn;
}

View File

@ -1,20 +1,20 @@
#pragma once
#include <vector>
#include <string>
#include "json.h"
#include "datastore.h"
/*
A custom i18n library
Loads strings from a json file
Requires the CJson class
Requires the DataStore class
*/
class Locale
{
private:
static inline std::vector<std::string> m_locales;
static inline std::string m_path;
static inline CJson *m_pData = nullptr;
static inline CJson *m_pCallbackJson = nullptr;
static inline DataStore *m_pData = nullptr;
static inline DataStore *m_pCallbackData = nullptr;
static inline size_t localeIndex;
public:
@ -49,28 +49,7 @@ public:
You need to call SetLanguage once before calling this function
By default, the language is set to "en"
*/
static inline std::string GetText(std::string&& key, std::string&& defaultValue = "")
{
if (m_pData == nullptr)
{
return defaultValue;
}
// Return keyname if no default value is provided
if (defaultValue == "")
{
defaultValue = "#" + key;
}
std::string rtn = m_pData->GetValueStr(key, defaultValue);
if (rtn == defaultValue)
{
return m_pCallbackJson->GetValueStr(key, defaultValue);
}
return rtn;
}
static std::string GetText(std::string&& key, std::string&& defaultValue = "");
/*
Sets the language to use

View File

@ -16,22 +16,22 @@ void Menu::Init()
{
// TODO: use structs
// Load config data
m_Overlay::bCoord = gConfig.GetValue("overlay.coord", false);
m_Overlay::bCpuUsage = gConfig.GetValue("overlay.cpu_usage", false);
m_Overlay::bFPS = gConfig.GetValue("overlay.fps", false);
m_Overlay::bLocName = gConfig.GetValue("overlay.loc_name", false);
m_Overlay::bTransparent = gConfig.GetValue("overlay.transparent", false);
m_Overlay::bMemUsage = gConfig.GetValue("overlay.mem_usage", false);
m_Overlay::bVehHealth = gConfig.GetValue("overlay.veh_health", false);
m_Overlay::bVehSpeed = gConfig.GetValue("overlay.veh_speed", false);
m_Overlay::mSelectedPos = (DisplayPos)gConfig.GetValue("overlay.selected_pos", (int)DisplayPos::BOTTOM_RIGHT);
m_Overlay::fPosX = gConfig.GetValue("overlay.pox", 0);
m_Overlay::fPosY = gConfig.GetValue("overlay.posy", 0);
m_Overlay::textColor[0] = gConfig.GetValue("overlay.text_color.r", 1.0f);
m_Overlay::textColor[1] = gConfig.GetValue("overlay.text_color.g", 1.0f);
m_Overlay::textColor[2] = gConfig.GetValue("overlay.text_color.b", 1.0f);
m_Overlay::textColor[3] = gConfig.GetValue("overlay.text_color.a", 1.0f);
m_bDiscordRPC = gConfig.GetValue("menu.discord_rpc", false);
m_Overlay::bCoord = gConfig.Get("Overlay.ShowCoordinates", false);
m_Overlay::bCpuUsage = gConfig.Get("Overlay.ShowCPUUsage", false);
m_Overlay::bFPS = gConfig.Get("Overlay.ShowFPS", false);
m_Overlay::bLocName = gConfig.Get("Overlay.ShowLocationName", false);
m_Overlay::bTransparent = gConfig.Get("Overlay.Transparent", false);
m_Overlay::bMemUsage = gConfig.Get("Overlay.ShowMemoryUsage", false);
m_Overlay::bVehHealth = gConfig.Get("Overlay.ShowVehicleName", false);
m_Overlay::bVehSpeed = gConfig.Get("Overlay.ShowVehicleSpeed", false);
m_Overlay::mSelectedPos = (DisplayPos)gConfig.Get("Overlay.SelectedPosition", (int)DisplayPos::BOTTOM_RIGHT);
m_Overlay::fPosX = gConfig.Get("Overlay.PosX", 0);
m_Overlay::fPosY = gConfig.Get("Overlay.PosY", 0);
m_Overlay::textColor[0] = gConfig.Get("Overlay.TextColor.Red", 1.0f);
m_Overlay::textColor[1] = gConfig.Get("Overlay.TextColor.Green", 1.0f);
m_Overlay::textColor[2] = gConfig.Get("Overlay.TextColor.Blue", 1.0f);
m_Overlay::textColor[3] = gConfig.Get("Overlay.TextColor.Alpha", 1.0f);
m_bDiscordRPC = gConfig.Get("Menu.DiscordRPC", false);
Util::GetCPUUsageInit();
MEMORYSTATUSEX memInfo;
@ -63,8 +63,8 @@ void Menu::DrawOverlay()
{
if (m_Overlay::fPosX != NULL && m_Overlay::fPosY != NULL)
{
gConfig.SetValue("overlay.posx", m_Overlay::fPosX);
gConfig.SetValue("overlay.posy", m_Overlay::fPosY);
gConfig.Set("Overlay.PosX", m_Overlay::fPosX);
gConfig.Set("Overlay.PosY", m_Overlay::fPosY);
ImGui::SetNextWindowPos(ImVec2(m_Overlay::fPosX, m_Overlay::fPosY), ImGuiCond_Once);
}
}
@ -323,13 +323,7 @@ void Menu::ShowPage()
if (ImGui::BeginTabItem(TEXT("Menu.Config")))
{
ImGui::Spacing();
if (ImGui::Button(TEXT("Menu.ResetConfig"), ImVec2(Ui::GetSize(2))))
{
gConfig.m_Data.clear();
SetHelpMessage(TEXT("Menu.ResetConfigMSG"));
}
ImGui::SameLine();
if (ImGui::Button(TEXT("Menu.ResetSize"), ImVec2(Ui::GetSize(2))))
if (ImGui::Button(TEXT("Menu.ResetSize"), ImVec2(Ui::GetSize(1))))
{
CheatMenu::ResetMenuSize();
}
@ -366,7 +360,7 @@ void Menu::ShowPage()
{
RPC::Shutdown();
}
gConfig.SetValue("menu.discord_rpc", m_bDiscordRPC);
gConfig.Set("Menu.DiscordRPC", m_bDiscordRPC);
}
ImGui::NextColumn();
ImGui::Columns(1);
@ -380,17 +374,17 @@ void Menu::ShowPage()
ImGui::SameLine();
if (Ui::ListBox(TEXT("Menu.Position"), m_Overlay::posNames, (int&)m_Overlay::mSelectedPos))
{
gConfig.SetValue("overlay.selected_pos", m_Overlay::mSelectedPos);
gConfig.Set<int>("Overlay.SelectedPosition", static_cast<int>(m_Overlay::mSelectedPos));
}
ImGui::Spacing();
ImGui::SameLine();
if (ImGui::ColorEdit4(TEXT("Menu.TextColor"), m_Overlay::textColor))
{
gConfig.SetValue("overlay.text_color.r", m_Overlay::textColor[0]);
gConfig.SetValue("overlay.text_color.g", m_Overlay::textColor[1]);
gConfig.SetValue("overlay.text_color.b", m_Overlay::textColor[2]);
gConfig.SetValue("overlay.text_color.a", m_Overlay::textColor[3]);
gConfig.Set("Overlay.TextColor.Red", m_Overlay::textColor[0]);
gConfig.Set("Overlay.TextColor.Green", m_Overlay::textColor[1]);
gConfig.Set("Overlay.TextColor.Blue", m_Overlay::textColor[2]);
gConfig.Set("Overlay.TextColor.Alpha", m_Overlay::textColor[3]);
}
ImGui::Spacing();
@ -398,44 +392,44 @@ void Menu::ShowPage()
ImGui::Columns(2, nullptr, false);
if (ImGui::Checkbox(TEXT("Menu.NoBG"), &m_Overlay::bTransparent))
{
gConfig.SetValue("overlay.transparent", m_Overlay::bTransparent);
gConfig.Set("Overlay.Transparent", m_Overlay::bTransparent);
}
if (ImGui::Checkbox(TEXT("Menu.ShowCoords"), &m_Overlay::bCoord))
{
gConfig.SetValue("overlay.coord", m_Overlay::bCoord);
gConfig.Set("Overlay.ShowCoordinates", m_Overlay::bCoord);
}
if (ImGui::Checkbox(TEXT("Menu.ShowCPU"), &m_Overlay::bCpuUsage))
{
gConfig.SetValue("overlay.cpu_usage", m_Overlay::bCpuUsage);
gConfig.Set("Overlay.ShowCPUUsage", m_Overlay::bCpuUsage);
}
if (ImGui::Checkbox(TEXT("Menu.ShowFPS"), &m_Overlay::bFPS))
{
gConfig.SetValue("overlay.fps", m_Overlay::bFPS);
gConfig.Set("Overlay.ShowFPS", m_Overlay::bFPS);
}
ImGui::NextColumn();
if (ImGui::Checkbox(TEXT("Menu.ShowLocation"), &m_Overlay::bLocName))
{
gConfig.SetValue("overlay.loc_name", m_Overlay::bLocName);
gConfig.Set("Overlay.ShowLocationName", m_Overlay::bLocName);
}
if (ImGui::Checkbox(TEXT("Menu.ShowRAM"), &m_Overlay::bMemUsage))
{
gConfig.SetValue("overlay.mem_usage", m_Overlay::bMemUsage);
gConfig.Set("Overlay.ShowMemoryUsage", m_Overlay::bMemUsage);
}
if (ImGui::Checkbox(TEXT("Menu.ShowVehHealth"), &m_Overlay::bVehHealth))
{
gConfig.SetValue("overlay.veh_health", m_Overlay::bVehHealth);
gConfig.Set("Overlay.ShowVehicleHealth", m_Overlay::bVehHealth);
}
if (ImGui::Checkbox(TEXT("Menu.ShowVehSpeed"), &m_Overlay::bVehSpeed))
{
gConfig.SetValue("overlay.veh_speed", m_Overlay::bVehSpeed);
gConfig.Set("Overlay.ShowVehicleSpeed", m_Overlay::bVehSpeed);
}
ImGui::Columns(1);

View File

@ -1,6 +1,6 @@
#include "pch.h"
eRenderer gRenderer = Render_Unknown;
CJson gConfig = CJson("config");
DataStore gConfig = DataStore(FILE_NAME, true);
Hotkey aimSkinChanger {VK_RETURN, VK_RETURN, "AimSkinChanger"};
Hotkey freeCam {VK_F6, VK_F6, "Freecam.Toggle"};

View File

@ -57,7 +57,6 @@
#include "defines.h"
#include "log.h"
#include "datastore.h"
#include "json.h"
#include "hotkeys.h"
#include "resourcestore.h"
#include "fontmgr.h"
@ -76,7 +75,7 @@ enum eRenderer
};
extern eRenderer gRenderer;
extern CJson gConfig;
extern DataStore gConfig;
// Fix function clashes
static void SetHelpMessage(const char *message, bool b1 = false, bool b2 = false, bool b3 = false)

View File

@ -52,9 +52,9 @@ private:
public:
#ifdef GTASA
static inline DataStore m_SpecialPedData {"special_peds"};
static inline ResourceStore m_PedData{"ped", eResourceType::TYPE_BOTH, ImVec2(65, 110)};
static inline ResourceStore m_PedData{"peds", eResourceType::TYPE_BOTH, ImVec2(65, 110)};
#else
static inline ResourceStore m_PedData {"ped", eResourceType::TYPE_TEXT};
static inline ResourceStore m_PedData {"peds", eResourceType::TYPE_TEXT};
#endif
Ped() = delete;

View File

@ -88,7 +88,7 @@ void Player::Init()
#ifdef GTASA
// Fix player model being broken after rebuild
patch::RedirectCall(0x5A834D, &PlayerModelBrokenFix);
m_bAimSkinChanger = gConfig.GetValue("aim_skin_changer", false);
m_bAimSkinChanger = gConfig.Get("aim_skin_changer", false);
#endif
// Custom skins setup
@ -477,7 +477,7 @@ void Player::ShowPage()
Ui::CheckboxAddress(TEXT("Player.InfO2"), 0x96916E);
if (Ui::CheckboxBitFlag(TEXT("Player.InvisPlayer"), pPlayer->m_nPedFlags.bDontRender))
{
pPlayer->m_nPedFlags.bDontRender != pPlayer->m_nPedFlags.bDontRender;
pPlayer->m_nPedFlags.bDontRender = !pPlayer->m_nPedFlags.bDontRender;
}
Ui::CheckboxAddress(TEXT("Player.InfSprint"), 0xB7CEE4);
#else
@ -489,7 +489,7 @@ void Player::ShowPage()
#ifdef GTASA
if (Ui::CheckboxBitFlag(TEXT("Player.LockControl"), pad->bPlayerSafe))
{
pad->bPlayerSafe != pad->bPlayerSafe;
pad->bPlayerSafe = !pad->bPlayerSafe;
}
Ui::CheckboxAddressEx(TEXT("Player.MaxAppeal"), 0x969180, 1, 0);
Ui::CheckboxAddress(TEXT("Player.MegaJump"), 0x96916C);
@ -766,7 +766,7 @@ void Player::ShowPage()
if (Ui::CheckboxWithHint(TEXT("Player.AimSkinChanger"), &m_bAimSkinChanger, TEXT("Player.AimSkinChangerTip") + aimSkinChanger.Pressed()))
{
gConfig.SetValue("aim_skin_changer", m_bAimSkinChanger);
gConfig.Set("aim_skin_changer", m_bAimSkinChanger);
}
if (ImGui::BeginTabBar("AppearanceTabBar"))
{

View File

@ -35,7 +35,7 @@ void Teleport::FetchRadarSpriteData()
void Teleport::Init()
{
m_bQuickTeleport = gConfig.GetValue("quick_teleport", false);
m_bQuickTeleport = gConfig.Get("quick_teleport", false);
Events::processScriptsEvent += []
{
@ -219,7 +219,7 @@ void Teleport::ShowPage()
std::string(TEXT_S("Teleport.QuickTeleportHint")
+ quickTeleport.GetNameString()).c_str()))
{
gConfig.SetValue("quick_teleport", m_bQuickTeleport);
gConfig.Set("quick_teleport", m_bQuickTeleport);
}
#endif
ImGui::Columns(1);

View File

@ -37,7 +37,7 @@ void Updater::Process()
}
const char* link = "https://api.github.com/repos/user-grinch/Cheat-Menu/tags";
char* path = PLUGIN_PATH((char*)"CheatMenu/json/versioninfo.json");
char* path = PLUGIN_PATH((char*)"CheatMenu/data/versioninfo.json");
HRESULT res = URLDownloadToFile(NULL, link, path, 0, NULL);
if (res == E_OUTOFMEMORY || res == INET_E_DOWNLOAD_FAILURE)
@ -46,17 +46,26 @@ void Updater::Process()
return;
}
CJson verinfo = CJson("versioninfo");
// fetch the version number
if (verinfo.m_Data.empty())
// Extract the version number
FILE *pFile= fopen(path, "r");
if (pFile != NULL)
{
latestVer = MENU_VERSION_NUMBER;
}
else
char buf[64];
float version = 0.0f;
while (fgets(buf, 64, pFile) != NULL)
{
latestVer = verinfo.m_Data.items().begin().value()["name"].get<std::string>();
sscanf(buf, "[{\"name\": \"%f\",", &version);
if (version != 0.0f)
{
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << version;
latestVer = ss.str();
break;
}
}
fclose(pFile);
}
remove(path);
if (latestVer > MENU_VERSION_NUMBER)
{