[C++][Tutorial]How to read ini files
-
As a GTA V mod user, it aggravates me when a script that involves a keypress doesn’t include an ini file. The key the author has selected may overlap with one of your controls and just piss you off. In order to prevent this, ini parsing can be implemented. With this class(below), you can read Booleans, integers, floats, or strings. For this example we will be reading strings.
The most common use of an ini is to configure a key press, and that’s what we’ll be doing. It gets a little complicated, but that's why I made this guide; to make ini parsing easier and to teach those who don’t know how to do it.
For this example I will be using my Quick Waypoint Remover, and xiaohe521’s “A Small Class to Read INI File”
Xiaohe521’s class is great because it is simple, stable, and open-source.
Let’s get started.
First make a file called delmarker.ini, put it in X:\Grand Theft Auto V, and paste the following into it:
[config]
button=0x08The 0x08 is a key from here; YOU MUST USE THESE HEX CODES
Create a new header called “IniReader.h” and paste the following into it:
#pragma once // For Visual Studio
#ifndef INIREADER_H
#define INIREADER_H
class CIniReader
{
public:
CIniReader(char* szFileName);
int ReadInteger(char* szSection, char* szKey, int iDefaultValue);
float ReadFloat(char* szSection, char* szKey, float fltDefaultValue);
bool ReadBoolean(char* szSection, char* szKey, bool bolDefaultValue);
char* ReadString(char* szSection, char* szKey, const char* szDefaultValue);
private:
char m_szFileName[255];
};
#endif//INIREADER_HThen create a new sourcefile called “IniReader.cpp” and paste the following:
#include "IniReader.h"
#include <iostream>
#include <Windows.h>CIniReader::CIniReader(char* szFileName)
{
memset(m_szFileName, 0x00, 255);
memcpy(m_szFileName, szFileName, strlen(szFileName));
}
int CIniReader::ReadInteger(char* szSection, char* szKey, int iDefaultValue)
{
int iResult = GetPrivateProfileInt(szSection, szKey, iDefaultValue, m_szFileName);
return iResult;
}
float CIniReader::ReadFloat(char* szSection, char* szKey, float fltDefaultValue)
{
char szResult[255];
char szDefault[255];
float fltResult;
sprintf(szDefault, "%f",fltDefaultValue);
GetPrivateProfileString(szSection, szKey, szDefault, szResult, 255, m_szFileName);
fltResult = atof(szResult);
return fltResult;
}
bool CIniReader::ReadBoolean(char* szSection, char* szKey, bool bolDefaultValue)
{
char szResult[255];
char szDefault[255];
bool bolResult;
sprintf(szDefault, "%s", bolDefaultValue? "True" : "False");
GetPrivateProfileString(szSection, szKey, szDefault, szResult, 255, m_szFileName);
bolResult = (strcmp(szResult, "True") == 0 ||
strcmp(szResult, "true") == 0) ? true : false;
return bolResult;
}
char* CIniReader::ReadString(char* szSection, char* szKey, const char* szDefaultValue)
{
char* szResult = new char[255];
memset(szResult, 0x00, 255);
GetPrivateProfileString(szSection, szKey,
szDefaultValue, szResult, 255, m_szFileName);
return szResult;
}Here is my script with a basic breakdown:
#include "script.h" // GTAV Library; This includes all GTA functions and stuff
#include "IniReader.h" // The ini reader header
CIniReader iniReader(".\delmarker.ini"); // Opens delmarker.ini
char *temp = iniReader.ReadString("config", "Key", "0x08"); // Gets the key and stores it in a char
DWORD key = strtol(temp, NULL, 0); // Converts the char into a DWORD
void update()
{
if (GetAsyncKeyState(key)) // Checks if key was pressed
{
UI::SET_WAYPOINT_OFF(); // Removes waypoint
AUDIO::PLAY_SOUND(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1); // Plays a sound
}
}
void main()
{
while (true) // Infinite loop
{
update(); // Calls the function defined above
WAIT(0); // Waits
}
}
// Ignore this below
void ScriptMain()
{
srand(GetTickCount());
main(); // Calls main function
}Here is a more advanced breakdown:
CIniReader iniReader(".\delmarker.ini");
This creates a "CiniReader" called iniReader that is referring to delmarker.inichar *temp = iniReader.ReadString("config", "button", "0x08");
This stores the string of text in a char
Syntax: (string section, string key, string defaultOption)
btw a "key" is just a part of an ini file, not a button on the keyboard.
DWORD key = strtol(temp, NULL, 0);
In order to get key presses, we need a DWORD, so the above converts a hex number into a DWORD
Syntax: (char *input, NULL, int base);
The base is the number before the x in the hex. For VK keys it's always 0...
GetAsyncKeyState(key)
Syntax: GetAsyncKeyState(DWORD key)I hope this all made sense, reply with any questions
-
@Frazzlee Yeah LOL!