Made the es_systems.cfg template install to the home directory during the first application startup.

This commit is contained in:
Leon Styhre 2020-07-09 19:26:48 +02:00
parent 9ba4f01a29
commit adb5cb6664
5 changed files with 96 additions and 67 deletions

View file

@ -9,6 +9,7 @@
#include "SystemData.h" #include "SystemData.h"
#include "resources/ResourceManager.h"
#include "utils/FileSystemUtil.h" #include "utils/FileSystemUtil.h"
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
@ -218,16 +219,17 @@ bool SystemData::loadConfig()
LOG(LogInfo) << "Loading system config file " << path << "..."; LOG(LogInfo) << "Loading system config file " << path << "...";
if (!Utils::FileSystem::exists(path)) { if (!Utils::FileSystem::exists(path)) {
LOG(LogError) << "Error - es_systems.cfg file does not exist!"; LOG(LogWarning) << "Warning - es_systems.cfg does not exist.";
writeExampleConfig(getConfigPath(true)); if (copyConfigTemplate(getConfigPath(true)))
return false; return false;
path = getConfigPath(false);
} }
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_parse_result res = doc.load_file(path.c_str()); pugi::xml_parse_result res = doc.load_file(path.c_str());
if (!res) { if (!res) {
LOG(LogError) << "Error - Could not parse es_systems.cfg file!"; LOG(LogError) << "Error - Could not parse es_systems.cfg";
LOG(LogError) << res.description(); LOG(LogError) << res.description();
return false; return false;
} }
@ -331,50 +333,28 @@ bool SystemData::loadConfig()
return true; return true;
} }
void SystemData::writeExampleConfig(const std::string& path) bool SystemData::copyConfigTemplate(const std::string& path)
{ {
std::ofstream file(path.c_str()); std::string systemsTemplateFile;;
file << "<!-- This is the EmulationStation Systems configuration file.\n" LOG(LogInfo) << "Attempting to copy template es_systems.cfg file from the resources directory.";
"All systems must be contained within the <systemList> tag.-->\n"
"\n"
"<systemList>\n"
" <!-- Here's an example system to get you started. -->\n"
" <system>\n"
"\n"
" <!-- A short name, used internally. Traditionally lower-case. -->\n"
" <name>nes</name>\n"
"\n"
" <!-- A \"pretty\" name, displayed in menus and such. -->\n"
" <fullname>Nintendo Entertainment System</fullname>\n"
"\n"
" <!-- The path to start searching for ROMs in. '~' will be expanded to $HOME on Linux or %HOMEPATH% on Windows. -->\n"
" <path>~/roms/nes</path>\n"
"\n"
" <!-- A list of extensions to search for, delimited by any of the whitespace characters (\", \\r\\n\\t\").\n"
" You MUST include the period at the start of the extension! It's also case sensitive. -->\n"
" <extension>.nes .NES</extension>\n"
"\n"
" <!-- The shell command executed when a game is selected. A few special tags are replaced if found in a command:\n"
" %ROM% is replaced by a bash-special-character-escaped absolute path to the ROM.\n"
" %BASENAME% is replaced by the \"base\" name of the ROM. For example, \"/foo/bar.rom\" would have a basename of \"bar\". Useful for MAME.\n"
" %ROM_RAW% is the raw, unescaped path to the ROM. -->\n"
" <command>retroarch -L ~/cores/libretro-fceumm.so %ROM%</command>\n"
"\n"
" <!-- The platform to use when scraping. You can see the full list of accepted platforms in src/PlatformIds.cpp.\n"
" It's case sensitive, but everything is lowercase. This tag is optional.\n"
" You can use multiple platforms too, delimited with any of the whitespace characters (\", \\r\\n\\t\"), eg: \"genesis, megadrive\" -->\n"
" <platform>nes</platform>\n"
"\n"
" <!-- The theme to load from the current theme set. See THEMES.md for more information.\n"
" This tag is optional. If not set, it will default to the value of <name>. -->\n"
" <theme>nes</theme>\n"
" </system>\n"
"</systemList>\n";
file.close(); #if defined (_WIN64)
systemsTemplateFile = ResourceManager::getInstance()->
getResourcePath(":/templates/es_systems.cfg_windows");
#elif defined(__unix__)
systemsTemplateFile = ResourceManager::getInstance()->
getResourcePath(":/templates/es_systems.cfg_unix");
#endif
LOG(LogError) << "Example config written! Go read it at \"" << path << "\"!"; if (Utils::FileSystem::copyFile(systemsTemplateFile, path, false)) {
LOG(LogError) << "Error - Copying of es_systems.cfg template file failed.";
return true;
}
LOG(LogInfo) << "Template es_systems.cfg file copied successfully.";
return false;
} }
void SystemData::deleteSystems() void SystemData::deleteSystems()

View file

@ -70,7 +70,7 @@ public:
// Returns true if no errors were encountered. // Returns true if no errors were encountered.
// An example will be written if the file doesn't exist. // An example will be written if the file doesn't exist.
static bool loadConfig(); static bool loadConfig();
static void writeExampleConfig(const std::string& path); static bool copyConfigTemplate(const std::string& path);
static std::string getConfigPath(bool forWrite); static std::string getConfigPath(bool forWrite);
static std::vector<SystemData*> sSystemVector; static std::vector<SystemData*> sSystemVector;

View file

@ -50,13 +50,6 @@
#include <iostream> #include <iostream>
#include <time.h> #include <time.h>
enum eErrorCodes {
NO_ERRORS,
NO_SYSTEMS_FILE,
NO_ROMS
};
#ifdef _WIN64 #ifdef _WIN64
enum eConsoleType { enum eConsoleType {
NO_CONSOLE, NO_CONSOLE,
@ -336,31 +329,36 @@ bool verifyHomeFolderExists()
// Returns NO_ERRORS if everything is OK. // Returns NO_ERRORS if everything is OK.
// Otherwise returns either NO_SYSTEMS_FILE or NO_ROMS. // Otherwise returns either NO_SYSTEMS_FILE or NO_ROMS.
unsigned int loadSystemConfigFile(std::string& errorMsg) bool loadSystemConfigFile(std::string& errorMsg)
{ {
if (!SystemData::loadConfig()) { if (!SystemData::loadConfig()) {
LOG(LogError) << "Error while parsing systems configuration file!"; LOG(LogError) << "Error - Could not parse systems configuration file.";
errorMsg = "COULDN'T FIND THE SYSTEMS CONFIGURATION FILE.\n" errorMsg = "COULDN'T FIND THE SYSTEMS CONFIGURATION FILE.\n"
"WILL ATTEMPT TO INSTALL A TEMPLATE ES_SYSTEMS.CFG FILE FROM " "ATTEMPTED TO COPY A TEMPLATE ES_SYSTEMS.CFG FILE\n"
"THE EMULATIONSTATION RESOURCES DIRECTORY.\n" "FROM THE EMULATIONSTATION RESOURCES DIRECTORY,\n"
"PLEASE RESTART THE APPLICATION."; "BUT THIS FAILED. HAS EMULATIONSTATION BEEN PROPERLY\n"
return NO_SYSTEMS_FILE; "INSTALLED AND DO YOU HAVE WRITE PERMISSIONS TO \n"
"YOUR HOME DIRECTORY?";
return true;
} }
if (SystemData::sSystemVector.size() == 0) if (SystemData::sSystemVector.size() == 0)
{ {
LOG(LogError) << "No systems found! Does at least one system have a game present? (check " LOG(LogError) << "Error - No systems found, does at least one system have a game present? "
"that extensions match!)\n"; "(Check that the file extensions are supported.)";
errorMsg = "THE SYSTEMS CONFIGURATION FILE EXISTS BUT NO GAME " errorMsg = "THE SYSTEMS CONFIGURATION FILE EXISTS, BUT NO\n"
"ROM FILES WERE FOUND. PLEASE MAKE SURE THAT THE 'ROMDIRECTORY' " "GAME FILES WERE FOUND. PLEASE MAKE SURE THAT\n"
"SETTING IN ES_SYSTEMS.CFG IS POINTING TO YOUR ROM DIRECTORY " "THE 'ROMDIRECTORY' SETTING IN ES_SETTINGS.CFG IS\n"
"AND THAT YOUR GAME ROMS ARE USING SUPPORTED FILE EXTENSIONS. " "POINTING TO YOUR ROM DIRECTORY AND THAT YOUR\n"
"GAME FILES ARE USING SUPPORTED FILE EXTENSIONS.\n"
"THE GAME SYSTEMS SUBDIRECTORIES ALSO NEED TO\n"
"MATCH THE PLATFORM TAGS IN ES_SYSTEMS.CFG.\n"
"THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n"; "THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n";
errorMsg += FileData::getROMDirectory(); errorMsg += FileData::getROMDirectory();
return NO_ROMS; return true;
} }
return NO_ERRORS; return false;
} }
// Called on exit, assuming we get far enough to have the log initialized. // Called on exit, assuming we get far enough to have the log initialized.
@ -437,7 +435,7 @@ int main(int argc, char* argv[])
std::string errorMsg; std::string errorMsg;
if (loadSystemConfigFile(errorMsg) != NO_ERRORS) { if (loadSystemConfigFile(errorMsg)) {
// Something went terribly wrong. // Something went terribly wrong.
if (errorMsg == "") { if (errorMsg == "") {
LOG(LogError) << "Unknown error occured while parsing system config file."; LOG(LogError) << "Unknown error occured while parsing system config file.";

View file

@ -9,8 +9,10 @@
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include "utils/FileSystemUtil.h" #include "utils/FileSystemUtil.h"
#include "Log.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <fstream>
#include <string.h> #include <string.h>
#if defined(_WIN64) #if defined(_WIN64)
@ -516,6 +518,53 @@ namespace Utils
return resolved; return resolved;
} }
bool copyFile(const std::string& _source_path,
const std::string& _destination_path, bool _overwrite)
{
if (!exists(_source_path)) {
LOG(LogError) << "Error - Can't copy file, source file does not exist:";
LOG(LogError) << _source_path;
return true;
}
if(isDirectory(_destination_path)) {
LOG(LogError) << "Error - Destination file is actually a directory:";
LOG(LogError) << _destination_path;
return true;
}
if (!_overwrite && exists(_destination_path)) {
LOG(LogError) << "Error - Destination file exists and the overwrite flag "
"has not been set.";
return true;
}
std::ifstream sourceFile(_source_path, std::ios::binary);
if (sourceFile.fail()) {
LOG(LogError) << "Error - Couldn't read from source file (" << _source_path <<
"), permission problems?";
sourceFile.close();
return true;
}
std::ofstream targetFile(_destination_path, std::ios::binary);
if (targetFile.fail()) {
LOG(LogError) << "Error - Couldn't write to target file (" << _destination_path <<
"), permission problems?";
targetFile.close();
return true;
}
targetFile << sourceFile.rdbuf();
sourceFile.close();
targetFile.close();
return false;
}
bool removeFile(const std::string& _path) bool removeFile(const std::string& _path)
{ {
std::string path = getGenericPath(_path); std::string path = getGenericPath(_path);

View file

@ -45,6 +45,8 @@ namespace Utils
std::string removeCommonPath(const std::string& _path, std::string removeCommonPath(const std::string& _path,
const std::string& _common, bool& _contains); const std::string& _common, bool& _contains);
std::string resolveSymlink(const std::string& _path); std::string resolveSymlink(const std::string& _path);
bool copyFile(const std::string& _source_path,
const std::string& _destination_path, bool _overwrite);
bool removeFile(const std::string& _path); bool removeFile(const std::string& _path);
bool createDirectory(const std::string& _path); bool createDirectory(const std::string& _path);
bool exists(const std::string& _path); bool exists(const std::string& _path);