/*
* Switch GTA 1.0 or 3.0 to open
* by Fábio
* http://g...content-available-to-author-only...t.com/
* http://b...content-available-to-author-only...s.com/
* More info about this program: http://b...content-available-to-author-only...s.com/t2903-
*
* Licensed under WTFPLv2 (http://w...content-available-to-author-only...l.net/txt/copying/)
*/
#include <fstream>
#include <iostream>
#include <string>
//#include <cstring>
//#include <cstdlib>
#include <vector>
#include <cstdio>
#include <exception>
#include <Windows.h>
#include "dirent.h"
void uninstallMods();
void installMods();
int main(){
switch(MessageBox(0, "Deseja iniciar o GTA com mods?", "Pergunta", MB_YESNOCANCEL)){
case IDCANCEL:
break;
case IDNO:
uninstallMods();
system(".\\gta-sa.exe");
break;
case IDYES:
installMods();
system(".\\gta_sa.exe");
break;
default:
break;
}
return 0;
}
class Exception : std::exception{
std::string whatString;
public:
const char *what(){
return whatString.c_str();
}
Exception(const char *WhatStr) : std::exception(){
whatString = WhatStr;
MessageBox(0, WhatStr, "Error!!!", 0); // Show error string
}
};
struct fileContent{
std::streamsize size;
char *Content;
fileContent(){
size = 0L;
Content = nullptr;
}
};
template<class T>
std::streamsize FileSize(T &fileStream){
fileStream.seekg(0, fileStream.end);
std::streamsize size = fileStream.tellg();
fileStream.seekg(0, fileStream.beg);
return size;
}
template<class T>
fileContent readFile(T &fileStream){
fileContent FContent;
FContent.size = FileSize(fileStream);
FContent.Content = new char[FContent.size + 1];
memset(FContent.Content, 0, FContent.size + 1);
fileStream.read(FContent.Content, FContent.size);
std::cout << "Config file size is: " << FContent.size << "\n";
return FContent;
}
typedef void (*fileCallbackFunction)(const char *, const char *); // callback function type
void toCallBack(const char *fileName, const char *fullName){ // Function LoopFiles callback (RLY?)
if(MoveFileA(fullName, fileName)){
std::cout << "Moved " << fileName << "\n";
}
}
std::vector<std::string> listOfModsToMove;
std::fstream configFile;
bool isInList(const char *name){ // Check if file is in list of mods to move
for(unsigned int i = 0, size = listOfModsToMove.size(); i < size; i++){
if(listOfModsToMove[i] == name) return true;
}
return false;
}
void LoopFiles(const char *Folder, fileCallbackFunction callback){ // Get folder files
struct dirent *pent = nullptr;
DIR *ScriptsFolder = nullptr;
ScriptsFolder = opendir(Folder); // Open directory
if(ScriptsFolder == nullptr) return; // Return if directory doesn't openned
std::string FileName;
while(pent = readdir(ScriptsFolder)){
if(isInList(pent->d_name)){
FileName = Folder;
FileName += "\\";
FileName += pent->d_name; // Folder\\Name Of Searched File
callback(pent->d_name, FileName.c_str()); // call the callback
}
}
}
void ParseConfig(const char *configFileName){ // Get list of mods in configuration file
std::cout << "Openning configuration file\n";
configFile.open(configFileName, std::ios::in | std::ios::out); // Open config file to i/o
if(!configFile.is_open()){ // Open fail?
configFile.open(configFileName, std::ios::out); // Create file
if(!configFile.is_open()) throw Exception("Can't create configuration file!!!"); // Creation failed?
configFile.close(); // Created with sucessfull
configFile.open(configFileName, std::ios::in | std::ios::out); // Open file to i/o
}
std::cout << "Reading configuration file\n";
fileContent cfgContent = readFile(configFile);
std::cout << "Getting mods to move list\n";
unsigned int sPoint = 0, ePoint = 0;
for(unsigned int i = 0; i < cfgContent.size; i++, ePoint++){
if(cfgContent.Content[i] == '\n'){
cfgContent.Content[i] = 0;
if(sPoint != ePoint) listOfModsToMove.push_back(&cfgContent.Content[sPoint]);
sPoint = ePoint = i++;
}
}
if(sPoint != ePoint && cfgContent.Content[sPoint] != '\n') listOfModsToMove.push_back(&cfgContent.Content[sPoint]);
std::cout << "Search finished\n";
configFile.close();
}
void uninstallMods(){ // Remove mods from game folder
ParseConfig("Mods to Move list.cfg");
std::string fullNamePath;
for(unsigned int i = 0, size = listOfModsToMove.size(); i < size; i++){
fullNamePath = ".\\Mods\\";
fullNamePath += listOfModsToMove.at(i).c_str();
if(MoveFileA(listOfModsToMove.at(i).c_str(), fullNamePath.c_str())){
std::cout << "Moved " << listOfModsToMove.at(i).c_str() << "\n";
}
}
}
void installMods(){ // Put mods on game folder
ParseConfig("Mods to Move list.cfg");
LoopFiles("Mods", toCallBack);
}