I've been to C++ lessons a long time ago and now I want to create a simple console program for switching Steam accounts. Please help me analyze my code and find my mistakes or better ways of doing something.
Main
#include "stdafx.h"
#include "functions.h"
using namespace std;
bool getNumberOrQuit(int &num, const int lcounter);
int main()
{
//system("chcp 1251");
//system("cls")
SetConsoleTitle(L"Steam Account Switcher v0.02");
bool repeatProgram = false, emergencyExit = 0;;
string temp;
map<int, string> login, pass;
int lcounter, num;
string::size_type pos = 0;
wstring wSteamDir;
do
{
screenClear();
firstStart(); //First start with check
lcounter = 0; //Account counter
if (repeatProgram == false)
{
temp = steamLocation();
pos = temp.find("steam.exe");
stringToWString(wSteamDir, temp.substr(0, pos));
}
repeatProgram = false;
parseAccsFromDB(login, pass, lcounter); //Parsing accounts from accfile
//Viewing accounts
//----------------------------------------------------------------------------------------------
screenClear();
cout << "The list of accounts in datebase:\nType your account's number ('0' for more options, 'q' for exit)." << endl;
showAccs(login, lcounter); //Show accounts on the screen
emergencyExit = getNumberOrQuit(num, lcounter); //Get user's choice of account or choice to quit the program
if (emergencyExit) return 0;
switch (num)
{
case 0:
{ //If user choose '0'
showHelp(lcounter, login);
repeatProgram = true;
break;
}
default:
{
launchSteam(login[num - 1], pass[num - 1], wSteamDir);
break;
}
}
} while (repeatProgram == true);
return 0;
}
bool getNumberOrQuit(int &num, const int lcounter)
{
char temp;
do
{
temp = _getch();
if (temp >= '0' && temp <= lcounter + '0')
{
num = temp - '0';
return 0;
}
else if (temp == 'q')
{
return 1;
}
} while (temp < 0 || temp > lcounter);
cout << "\nThe Application has encountered a critical error! (Error code: 11)\n"; //"ERRORCODE11"
screenPause();
return 1;
}
bool firstStart(bool override)
{
CSimpleIniA ini;
ini.SetUnicode();
bool fs = true, iniExist;
string fileEmpty;
ifstream accFile("accounts");
getline(accFile, fileEmpty);
accFile.close();
iniExist = iniExistCheck();
ini.LoadFile("settings.ini");
if (fileEmpty != "") fs = false;
else if (!override)
{
fs = ini.GetBoolValue("General", "firststart");
}
//else if (fileEmpty != "" && override) fs = false;
if (fs) //First time message and first ini setup
{
cout << "Welcome to Steam Account Switcher!\nI'm glad you're using my simple program.\nNow you have to add your steam account.\nEnter it below.\n";
addAccount();
screenClear();
}
ini.SetBoolValue("General", "firststart", false);
ini.SaveFile("settings.ini");
return fs;
}
Functions.h
#ifndef _ST_ACC_F_
#define _ST_ACC_F_
#pragma once
#include "SimpleIni.h" //Ini File Read\Write Library
#include <fstream>
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
bool writeAccToDB(string login, string pass); //Write in a file login and pass
bool addAccount(); //Message about addiding account and writing it
void runSteam(const string login, const string pass, const wstring wSteamDir);
void parseAccsFromDB(map<int, string> &login, map<int, string> &pass, int &lcounter);
void showAccs(map<int, string> &login, const int lcounter);
string getPassword();
bool deleteAccount(const int acc_num);
void showHelp(const int lcounter, map<int, string> &login);
bool firstStart(bool override = 0); //Firststart check and message
void stringToWString(wstring &ws, const string &s);
void launchSteam(const string login, const string pass, const wstring wSteamDir);
string steamLocation();
string getSteamLocation();
bool iniExistCheck();
void screenClear();
void screenPause(const string customMessage = "");
#endif // !_ST_ACC_F_
Steam_acc_funcs.cpp
#include "stdafx.h"
#include "functions.h"
using namespace std;
void runSteam(const string login, const string pass, const wstring wSteamDir)
{
wstring wLogin, wPass;
stringToWString(wLogin, login);
stringToWString(wPass, pass);
wstring wParameters = L"-login " + wLogin + L" " + wPass, wSteam = wSteamDir;
wSteam += L"steam.exe";
const HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
ShellExecute(NULL, L"open", wSteam.c_str(), wParameters.c_str(), wSteamDir.c_str(), SW_SHOWMINIMIZED);
}
void stringToWString(wstring &ws, const string &s)
{
wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
}
bool writeAccToDB(string login, string pass)
{
fstream accfile("accounts", ios::out | ios::app);
if (accfile << login << ";" << pass << endl)
{
accfile.close();
return 1;
}
accfile.close();
return 0;
}
bool addAccount()
{
bool repeat = 1, add_result;
string login, pass;
char input;
while (repeat == 1)
{
cout << "Login = ";
cin >> login;
cout << "Pass = ";
pass = getPassword();
add_result = writeAccToDB(login, pass);
if (!add_result)
{
cout << "Application has encountered an error: Can not write the account's file! (Error Code: 1)" << endl; //"ERRORCODE1"
screenPause();
return 0;
}
cout << "Account added succesfully!";
cout << "\nAdd one more account?(1\\0 or y\\n)";
do
{
input = _getch();
switch (input)
{
case ('0'):
{
repeat = 0;
break;
}
case ('n'):
{
repeat = 0;
break;
}
case ('1'):
{
repeat = 1;
break;
}
case ('y'):
{
repeat = 1;
break;
}
default:
break;
}
} while (input != '0' && input != '1' && input != 'n' && input != 'y');
}
return 1;
}
string getPassword()
{
string passString = ""; //holds the password string
char ch = _getch();
while (true)
{
if (ch == '\r' && passString != "") break;
else if (ch == '\b' && passString != "")
{
//passString = passString.substr(0, passString.size() - 1);
passString.pop_back();
cout << "\b"
<< " "
<< "\b";
}
else if (ch != '\b')
{
cout << '*';
passString += ch;
}
ch = _getch();
}
cout << endl;
return passString;
}
void parseAccsFromDB(map<int, string> &login, map<int, string> &pass, int &lcounter)
{
ifstream accfile("accounts");
string::size_type pos = 0;
string line;
accfile.seekg(0);
while (getline(accfile, line)) //Getting lines
{
pos = line.find(";"); //Locating sparator
if (pos == string::npos) continue; // For safety
login[lcounter] = line.substr(0, pos); //Setting login var substr - to get line from specific pos
pass[lcounter] = line.substr(pos + 1); //Setting pass var
lcounter++;
}
accfile.close();
}
void showAccs(map<int, string> &login, const int lcounter)
{
for (int i = 0; i < lcounter;i++)
cout << i + 1 << "=" << login[i] << endl;
}
bool deleteAccount(const int acc_num)
{
bool result = 0;
ifstream accfile("accounts");
ofstream new_accfile("newaccfile");
string line;
int lcounter = 0;
if (!accfile.is_open()) return 0;
else if (!new_accfile.is_open()) return 0;
while (getline(accfile, line))
{
lcounter++;
if (lcounter == acc_num) continue;
new_accfile << line << endl;
}
accfile.close();
new_accfile.close();
remove("accounts");
rename("newaccfile", "accounts");
return 1;
}
void showHelp(const int lcounter, map<int, string> &login)
{
screenClear();
char input, input2;
int input2_5;
cout << "Type 1 to add a new account." << endl
<< "Type 2 to delete an account." << endl;
do
{
input = _getch();
switch (input)
{
case('1'):
{
cout << "Enter a new account below." << endl;
addAccount();
break;
}
case('2'):
{
cout << "Enter the number of the account you want to delete.\n";
showAccs(login, lcounter);
do
{
input2 = _getch();
input2_5 = input2 - '0';
if (input2_5 >= 1 && input2_5 <= lcounter)
{
bool delResult = deleteAccount(input2_5);
if (delResult) cout << "Account \"" << login[input2_5 - 1] << "\" succesfully deleted." << endl;
else cout << "Error deleting account.";
screenPause("Press any key to return to main menu. . .");
break;
}
else cout << "Account with this number doesn't exist! Type a right one.\n";
} while (input2_5 < 1 || input2_5 > lcounter);
break;
}
//default:
//{
// break;
//}
}
} while (input != '1' && input != '2');
}
void launchSteam(const string login, const string pass, const wstring wSteamDir)
{
system("taskkill /F /IM GameOverlayUI.exe > nul 2>&1");
system("taskkill /F /IM Steam.exe > nul 2>&1");
system("timeout /t 1 > nul 2>&1");
runSteam(login, pass, wSteamDir);
}
string steamLocation()
{
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile("settings.ini");
bool iniExist;
iniExist = iniExistCheck();
if (iniExist)
{
string locSet = ini.GetValue("Steam", "location");
if (locSet != "") return locSet;
}
ifstream checkSteam("C:\\Program Files (x86)\\Steam\\steam.exe");
if (checkSteam.good())
{
checkSteam.close();
ini.SetValue("Steam", "location", "C:\\Program Files (x86)\\Steam\\steam.exe", NULL, true);
ini.SaveFile("settings.ini");
return "C:\\Program Files (x86)\\Steam\\steam.exe";
}
else
{
checkSteam.close();
cout << "Steam isn't located in default location. Please, enter it manually.\n(Example: D:\\Programs\\Steam\\steam.exe)" << endl;
return getSteamLocation();
}
}
string getSteamLocation()
{
ifstream checkSteam;
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile("settings.ini");
string loc;
bool customMessage = 0;
do
{
if (customMessage) cout << "Steam isn't located in path you entered. Try again." << endl;
//cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
while (getline(cin, loc))
{
if (loc != "") break;
}
checkSteam.open(loc);
if (checkSteam.good())
{
checkSteam.close();
ini.SetValue("Steam", "location", loc.c_str(), NULL, true);
ini.SaveFile("settings.ini");
return loc;
}
customMessage = 1;
} while (true);
}
bool iniExistCheck()
{
CSimpleIniA ini;
ini.SetUnicode();
int iniExist = ini.LoadFile("settings.ini");
if (iniExist < 0)
{
ini.SetBoolValue("General", "firststart", true);
ini.SetValue("Steam", "location", "");
ini.SaveFile("settings.ini");
return 0;
}
return 1;
}
void screenClear()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coordScreen = { 0, 0 }; // home for the cursor
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
// Get the number of character cells in the current buffer.
if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
return;
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
// Fill the entire screen with blanks.
if (!FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
dwConSize, coordScreen, &cCharsWritten))
return;
// Get the current text attribute.
if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
return;
// Set the buffer's attributes accordingly.
if (!FillConsoleOutputAttribute(hConsole, csbi.wAttributes,
dwConSize, coordScreen, &cCharsWritten))
return;
// Put the cursor at its home coordinates.
SetConsoleCursorPosition(hConsole, coordScreen);
}
void screenPause(const string customMessage)
{
if (customMessage == "") cout << "Press any key to continue . . .";
else cout << customMessage;
_getch();
}