wahyu-GTA-Online-OUTDATED-B.../subVersion/settings.cpp
gabrielkheisa 8e431a3e95 upload
2020-11-06 18:55:46 +07:00

649 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Copyright 2016-2017 sub1to
This file is part of subVersion GTA:O SC External Hack.
subVersion GTA:O SC External Hack is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
subVersion GTA:O SC External Hack is distributed in the hope that it
will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with subVersion GTA:O SC External Hack. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
/*
//SETTINGS CLASS
*/
settings::settings()
{
m_iniParser.m_szFile = "settings.ini";
m_iniParser.read();
//keys
m_iKeys[keyExit] = strToVk(m_iniParser.getValue<std::string>("Exit", "Keys"));
m_iKeys[keyMenu] = strToVk(m_iniParser.getValue<std::string>("Menu", "Keys"));
m_iKeys[keyMenuUp] = strToVk(m_iniParser.getValue<std::string>("MenuUp", "Keys"));
m_iKeys[keyMenuDown] = strToVk(m_iniParser.getValue<std::string>("MenuDown", "Keys"));
m_iKeys[keyMenuLeft] = strToVk(m_iniParser.getValue<std::string>("MenuLeft", "Keys"));
m_iKeys[keyMenuRight] = strToVk(m_iniParser.getValue<std::string>("MenuRight", "Keys"));
m_iKeys[keyMenuSelect] = strToVk(m_iniParser.getValue<std::string>("MenuSelect", "Keys"));
m_iKeys[keyMenuBack] = strToVk(m_iniParser.getValue<std::string>("MenuBack", "Keys"));
m_iKeys[keyMenuTabNext] = strToVk(m_iniParser.getValue<std::string>("MenuTabNext", "Keys"));
m_iKeys[keyMenuTabPrev] = strToVk(m_iniParser.getValue<std::string>("MenuTabPrev", "Keys"));
m_iKeys[keyMenuSave] = strToVk(m_iniParser.getValue<std::string>("MenuSave", "Keys"));
m_iKeys[keyHotTeleport] = strToVk(m_iniParser.getValue<std::string>("HotTeleport", "Keys"));
m_iKeys[keyHotWanted] = strToVk(m_iniParser.getValue<std::string>("HotWanted", "Keys"));
m_iKeys[keyHotHealth] = strToVk(m_iniParser.getValue<std::string>("HotHealth", "Keys"));
m_iKeys[keyHotAmmo] = strToVk(m_iniParser.getValue<std::string>("HotAmmo", "Keys"));
}
settings::~settings()
{
for(int i = 0; i < MAX_MENU_FEATURES; i++)
{
if(m_pFeature[i])
delete m_pFeature[i];
}
for(int i = 0; i < MAX_MENU_TABS; i++)
{
if(m_pFeatureCat[i])
delete m_pFeatureCat[i];
}
}
void settings::toggleMenu()
{
m_bMenuActive = !m_bMenuActive;
return;
}
bool settings::isMenuActive()
{
return m_bMenuActive;
}
void settings::menuDown()
{
if(m_iActiveFeature + 1 < m_nFeatureCur)
{
m_iActiveFeature++;
if (m_iActiveFeature == m_iFeatureCurDisplayOffset + MAX_MENU_FEATURES_DISPLAYED - MENU_FEATURE_SCROLL_PADDING)
{
int displayOffset = m_iActiveFeature - (MAX_MENU_FEATURES_DISPLAYED - 1 - MENU_FEATURE_SCROLL_PADDING);
displayOffset = (displayOffset > m_nFeatureCur - MAX_MENU_FEATURES_DISPLAYED) ? m_nFeatureCur - MAX_MENU_FEATURES_DISPLAYED : displayOffset;
displayOffset = (displayOffset < 0) ? 0 : displayOffset;
m_iFeatureCurDisplayOffset = displayOffset;
}
}
else
{
m_iActiveFeature = 0;
m_iFeatureCurDisplayOffset = 0;
}
return;
}
void settings::menuUp()
{
if(m_iActiveFeature - 1 >= 0)
{
m_iActiveFeature--;
if (m_iActiveFeature == m_iFeatureCurDisplayOffset + MENU_FEATURE_SCROLL_PADDING - 1)
{
int displayOffset = m_iActiveFeature - MENU_FEATURE_SCROLL_PADDING;
displayOffset = (displayOffset > m_nFeatureCur - MAX_MENU_FEATURES_DISPLAYED) ? m_nFeatureCur - MAX_MENU_FEATURES_DISPLAYED : displayOffset;
displayOffset = (displayOffset < 0) ? 0 : displayOffset;
m_iFeatureCurDisplayOffset = displayOffset;
}
}
else
{
m_iActiveFeature = m_nFeatureCur - 1;
int displayOffset = m_nFeatureCur - MAX_MENU_FEATURES_DISPLAYED;
displayOffset = (displayOffset < 0) ? 0 : displayOffset;
m_iFeatureCurDisplayOffset = displayOffset;
}
return;
}
void settings::menuRight()
{
return this->getFeatureCur(m_iActiveFeature)->inc();
}
void settings::menuLeft()
{
return this->getFeatureCur(m_iActiveFeature)->dec();
}
void settings::menuTabRight()
{
while(m_pFeatureCur[0]->m_iCat < 0)
this->menuBack();
m_pFeatureCat[m_iActiveCat]->m_iDisplayOffsetRet = m_iFeatureCurDisplayOffset;
m_pFeatureCat[m_iActiveCat]->m_iActiveFeatureRet = m_iActiveFeature;
if(m_iActiveCat + 1 < m_nFeatureCat)
this->setActiveCat(m_iActiveCat + 1);
else
this->setActiveCat(0);
m_iFeatureCurDisplayOffset = m_pFeatureCat[m_iActiveCat]->m_iDisplayOffsetRet;
m_iActiveFeature = m_pFeatureCat[m_iActiveCat]->m_iActiveFeatureRet;
return;
}
void settings::menuTabLeft()
{
while(m_pFeatureCur[0]->m_iCat < 0)
this->menuBack();
m_pFeatureCat[m_iActiveCat]->m_iDisplayOffsetRet = m_iFeatureCurDisplayOffset;
m_pFeatureCat[m_iActiveCat]->m_iActiveFeatureRet = m_iActiveFeature;
if(m_iActiveCat - 1 >= 0)
this->setActiveCat(m_iActiveCat - 1);
else
this->setActiveCat(m_nFeatureCat - 1);
m_iFeatureCurDisplayOffset = m_pFeatureCat[m_iActiveCat]->m_iDisplayOffsetRet;
m_iActiveFeature = m_pFeatureCat[m_iActiveCat]->m_iActiveFeatureRet;
return;
}
void settings::menuSelect()
{
feat* feat = this->getFeatureCur(m_iActiveFeature);
feat->toggle();
return;
}
void settings::menuBack()
{
if(m_pFeatureCur[0]->m_iParent >= 0) //if the buffer is filled with features that have a parent, not a category
{
featParent* parent = dynamic_cast<featParent*>(m_pFeature[m_pFeatureCur[0]->m_iParent]);
if(parent->m_iCat < 0)
this->fillFeatureCurBuffer(parent->m_iParent, FFB_PARENT);
else
this->fillFeatureCurBuffer(parent->m_iCat, FFB_CATEGORY);
m_iFeatureCurDisplayOffset = parent->m_iDisplayOffsetRet;
m_iActiveFeature = parent->m_iActiveFeatureRet;
}
else
{
toggleMenu();
}
return;
}
int settings::addFeatureCategory(std::wstring name)
{
if(m_nFeatureCat >= MAX_MENU_TABS) //prevent buffer overflow
return -1;
m_pFeatureCat[m_nFeatureCat] = new featCat;
m_pFeatureCat[m_nFeatureCat]->m_iId = m_nFeatureCat;
m_pFeatureCat[m_nFeatureCat]->m_szName = name;
m_nFeatureCat++;
return m_nFeatureCat - 1;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type)
{
if( m_nFeature >= MAX_MENU_FEATURES || //buffer overflow
(parent < 0 && m_pFeatureCat[cat] == nullptr) || //invalid cat
(cat < 0 && (m_pFeature[parent] == nullptr || m_pFeature[parent]->m_type != feat_parent)) || //invalid parent
(cat < 0 && parent < 0) || (cat > 0 && parent > 0)) //both cat and parent were provided
return -1;
switch(type)
{
case feat_toggle:
m_pFeature[m_nFeature] = new feat;
break;
case feat_btn:
m_pFeature[m_nFeature] = new featBtn;
break;
case feat_slider:
m_pFeature[m_nFeature] = new featSlider;
break;
case feat_teleport:
m_pFeature[m_nFeature] = new featTeleport;
break;
case feat_parent:
m_pFeature[m_nFeature] = new featParent;
break;
}
m_pFeature[m_nFeature]->m_iId = m_nFeature;
m_pFeature[m_nFeature]->m_iCat = cat;
m_pFeature[m_nFeature]->m_iParent = parent;
m_pFeature[m_nFeature]->m_type = type;
m_pFeature[m_nFeature]->m_szName = name;
m_nFeature++;
return m_nFeature - 1;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, int index, float arg)
{
int id = this->addFeature(cat, parent, name, type);
if (id < 0)
return id;
dynamic_cast<featBtn*>(m_pFeature[id])->m_iIndex = index;
dynamic_cast<featBtn*>(m_pFeature[id])->m_fArg = arg;
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, std::string iniKey)
{
int id = this->addFeature(cat, parent, name, type);
if(id < 0)
return id;
m_pFeature[id]->m_szIniKey = iniKey;
m_pFeature[id]->m_bOn = (bool) m_iniParser.getValue<bool>(iniKey, "FeatureToggle");
m_pFeature[id]->m_bRestored = (m_pFeature[id]->m_bOn) ? false : true;
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, std::string iniKey, float min, float max)
{
int id = this->addFeature(cat, parent, name, type, iniKey);
if(id < 0)
return id;
dynamic_cast<featSlider*>(m_pFeature[id])->m_fMin = min;
dynamic_cast<featSlider*>(m_pFeature[id])->m_fMax = max;
float v = m_iniParser.getValue<float>(iniKey, "FeatureValue");
if(v <= max && v >= min)
dynamic_cast<featSlider*>(m_pFeature[id])->m_fValue = v;
else
{
dynamic_cast<featSlider*>(m_pFeature[id])->m_fValue = min;
m_iniParser.setValue<float>(iniKey, min, "FeatureValue");
}
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, std::string iniKey, float min, float max, float mod)
{
int id = this->addFeature(cat, parent, name, type, iniKey, min, max);
if(id < 0)
return id;
dynamic_cast<featSlider*>(m_pFeature[id])->m_fMod = mod;
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, std::string iniKey, teleType tpType)
{
if(tpType != tp_saved)
return -1;
int id = this->addFeature(cat, parent, name, type, iniKey);
if(id < 0)
return id;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_tpType = tpType;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.x = m_iniParser.getValue<float>(iniKey + "_x", "Teleport");
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.y = m_iniParser.getValue<float>(iniKey + "_y", "Teleport");
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.z = m_iniParser.getValue<float>(iniKey + "_z", "Teleport");
dynamic_cast<featTeleport*>(m_pFeature[id])->m_szName += L" | " + StringToWString(m_iniParser.getValue<std::string>(iniKey + "_name", "Teleport"));
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, teleType tpType)
{
if(tpType == tp_saved)
return -1;
int id = this->addFeature(cat, parent, name, type);
if(id < 0)
return id;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_tpType = tpType;
return id;
}
int settings::addFeature(int cat, int parent, std::wstring name, featType type, teleType tpType, float x, float y, float z)
{
if(tpType == tp_saved)
return -1;
int id = this->addFeature(cat, parent, name, type, tpType);
if(id < 0)
return id;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.x = x;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.y = y;
dynamic_cast<featTeleport*>(m_pFeature[id])->m_v3Pos.z = z;
return id;
}
int settings::updataFeature(int id, int cat, int parent, std::wstring name, featType type)
{
if (id >= MAX_MENU_FEATURES || //buffer overflow
(parent < 0 && m_pFeatureCat[cat] == nullptr) || //invalid cat
(cat < 0 && (m_pFeature[parent] == nullptr || m_pFeature[parent]->m_type != feat_parent)) || //invalid parent
(cat < 0 && parent < 0) || (cat > 0 && parent > 0)) //both cat and parent were provided
return -1;
m_pFeature[id]->m_iId = id;
m_pFeature[id]->m_iCat = cat;
m_pFeature[id]->m_iParent = parent;
m_pFeature[id]->m_type = type;
m_pFeature[id]->m_szName = name;
return id;
}
int settings::updataFeature(int id, int cat, int parent, std::wstring name, featType type, teleType tpType, float x, float y, float z)
{
if (tpType == tp_saved)
return -1;
int ret = this->updataFeature(id, cat, parent, name, type);
if (ret < 0)
return ret;
dynamic_cast<featTeleport*>(m_pFeature[ret])->m_tpType = tpType;
dynamic_cast<featTeleport*>(m_pFeature[ret])->m_v3Pos.x = x;
dynamic_cast<featTeleport*>(m_pFeature[ret])->m_v3Pos.y = y;
dynamic_cast<featTeleport*>(m_pFeature[ret])->m_v3Pos.z = z;
return ret;
}
int settings::getFeatureCategoryCount()
{
return m_nFeatureCat;
}
featCat* settings::getFeatureCategory(int id)
{
if(id > m_nFeatureCat)
return 0;
return m_pFeatureCat[id];
}
int settings::getActiveCat()
{
return m_iActiveCat;
}
int settings::setActiveCat(int cat)
{
if(cat > m_nFeatureCat)
return 0;
m_iActiveCat = cat;
this->fillFeatureCurBuffer(cat, FFB_CATEGORY);
return 1;
}
bool settings::fillFeatureCurBuffer(int id, BYTE flag)
{
//prevent race conditions
while(!g_pSettings->lockFeatureCur())
Sleep(1);
ZeroMemory(&m_pFeatureCur, sizeof(feat*) * MAX_MENU_FEATURES); //clear buffer
m_nFeatureCur = 0;
m_iActiveFeature = 0;
m_iFeatureCurDisplayOffset = 0;
for(int i = 0; i < m_nFeature; i++) //create a list of features from current category
{
if( (m_pFeature[i]->m_iCat == id && flag & FFB_CATEGORY) ||
(m_pFeature[i]->m_iParent == id && flag & FFB_PARENT))
{
m_pFeatureCur[m_nFeatureCur] = m_pFeature[i];
m_nFeatureCur++;
}
}
this->unlockFeatureCur();
return 1;
}
int settings::getFeatureCurCount()
{
return m_nFeatureCur;
}
feat* settings::getFeatureCur(int i)
{
if(i > m_nFeatureCur)
return 0;
return m_pFeatureCur[i];
}
int settings::getFeatureCount()
{
return m_nFeature;
}
feat* settings::getFeature(int id)
{
if(id > m_nFeature)
return 0;
return m_pFeature[id];
}
int settings::getActiveFeature()
{
return m_iActiveFeature;
}
bool settings::getFeatureCurLock()
{
return m_bFeatureCurLock;
}
bool settings::lockFeatureCur()
{
if(m_bFeatureCurLock)
return false;
m_bFeatureCurLock = true;
return true;
}
bool settings::unlockFeatureCur()
{
m_bFeatureCurLock = false;
return true;
}
int settings::getDisplayOffset()
{
return m_iFeatureCurDisplayOffset;
}
/*
//FEATURE CLASSES
*/
feat::feat() {}
feat::~feat() {}
void feat::toggle()
{
m_bOn = !m_bOn;
if(m_bOn)
m_bRestored = false;
if(m_szIniKey != "")
g_pSettings->m_iniParser.setValue<bool>(m_szIniKey, (int) m_bOn, "FeatureToggle");
return;
}
void feat::inc() {}
void feat::dec() {}
featBtn::featBtn() {}
featBtn::~featBtn() {}
void featBtn::toggle()
{
(*g_pCBMap)[this->m_iIndex]->Exec(&this->m_fArg);
}
featSlider::featSlider() {}
featSlider::~featSlider() {}
void featSlider::inc()
{
float v = (m_fValue + ( (m_fMax - m_fMin) * m_fMod) );
if(v <= m_fMax)
m_fValue = v;
else
m_fValue = m_fMax;
g_pSettings->m_iniParser.setValue<float>(m_szIniKey, m_fValue, "FeatureValue");
return;
}
void featSlider::dec()
{
float v = (m_fValue - ( (m_fMax - m_fMin) * m_fMod) );
if(v >= m_fMin)
m_fValue = v;
else
m_fValue = m_fMin;
g_pSettings->m_iniParser.setValue<float>(m_szIniKey, m_fValue, "FeatureValue");
return;
}
featTeleport::featTeleport() {}
featTeleport::~featTeleport() {}
void featTeleport::toggle()
{
switch(m_tpType)
{
case tp_waypoint:
g_pHack->teleportWaypoint();
break;
case tp_objective:
g_pHack->teleportObjective();
break;
case tp_saved:
case tp_static:
g_pHack->teleport(m_v3Pos);
break;
}
}
featParent::featParent() {}
featParent::~featParent() {}
void featParent::toggle()
{
m_iActiveFeatureRet = g_pSettings->getActiveFeature();
m_iDisplayOffsetRet = g_pSettings->getDisplayOffset();
g_pSettings->fillFeatureCurBuffer(this->m_iId, FFB_PARENT);
return;
}
/*
//INI PARSER CLASS
*/
iniParser::iniParser(){};
iniParser::iniParser(std::string szFile) :
m_szFile(szFile)
{};
iniParser::~iniParser(){};
void iniParser::read()
{
std::ifstream file;
file.open(m_szFile, std::ios::in);
if (!file.is_open())
{
MessageBoxW(nullptr, L"δ<EFBFBD>ҵ<EFBFBD>settings.ini<6E><69><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>뽫ѹ<EBBDAB><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ѹ<EFBFBD><D1B9>ͬһĿ¼!", L"subVersion<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>", MB_OK | MB_ICONERROR);
g_bKillAttach = true;
killProgram();
return;
}
std::string szLine;
int iSection = -1;
std::regex regexSection("^\\[([A-Za-z0-9_]+)\\]$"),
regexKey ("^([A-Za-z0-9_]+)=([A-Za-z0-9_\\-*/+.\\s]+)$"),
regexComment("^(;|#)(.*)$");
while(std::getline(file, szLine, '\n'))
{
std::smatch regexMatch; //std::string match object
if(szLine == "")
continue;
else if(std::regex_search(szLine, regexMatch, regexComment) && regexMatch.size() > 1)
m_key.push_back({"__COMMENT__", regexMatch[2], iSection});
else if(std::regex_search(szLine, regexMatch, regexSection) && regexMatch.size() > 1)
{
iSection = (int) m_section.size();
m_section.push_back(regexMatch[1]);
}
else if(std::regex_search(szLine, regexMatch, regexKey) && regexMatch.size() > 1)
m_key.push_back({regexMatch.str(1), regexMatch[2], iSection});
}
return;
}
void iniParser::write()
{
std::ofstream file;
file.open(m_szFile, std::ios::out | std::ios::trunc);
if(!file.is_open())
return;
for(int j = 0; j <= m_section.size(); j++)
{
if(j > 0)
file << "[" << m_section[j - 1] << "]\n";
for(int i = 0; i < m_key.size(); i++)
{
if(m_key[i].section != j - 1)
continue;
if(m_key[i].key == "__COMMENT__")
file << ";" ;
else
file << m_key[i].key << "=";
file << m_key[i].value << "\n";
}
}
return;
}
int iniParser::findKey(std::string szKey, std::string szSection)
{
for(int i = 0; i < m_key.size(); i++)
if(m_key[i].key == szKey && (szSection == "" || szSection == m_section[m_key[i].section]))
return i;
return -1;
}
int iniParser::createKey(std::string szKey, std::string szSection)
{
int iSection = -1;
if(szSection != "")
{
for(int i = 0; i < m_section.size(); i++)
if(m_section[i] == szSection)
{
iSection = i;
break;
}
}
m_key.push_back({szKey, "", iSection});
return (int) m_key.size() - 1;
}