From bfba994d0794ccc61610e4ed5fa00778cba0d1c2 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Sat, 21 May 2022 11:43:17 +0200 Subject: [PATCH] Added an %INJECT% variable for injecting launch arguments from game config files. --- es-app/src/FileData.cpp | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 4b151b7a7..3a190324e 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1282,6 +1282,99 @@ void FileData::launchGame() } } + std::string injectFile; + const size_t injectPos {command.find("%INJECT%")}; + + if (injectPos != std::string::npos) { + bool invalidEntry {false}; + + if (injectPos + 10 >= command.size()) + invalidEntry = true; + else if (command[injectPos + 8] != '=') + invalidEntry = true; + + if (!invalidEntry && command[injectPos + 9] == '\"') { + size_t closingQuotation {command.find("\"", injectPos + 10)}; + + if (closingQuotation != std::string::npos) { + injectFile = command.substr(injectPos + 10, closingQuotation - injectPos - 10); + command = command.replace(injectPos, closingQuotation - injectPos + 2, ""); + } + else { + invalidEntry = true; + } + } + else if (!invalidEntry) { + size_t spacePos {command.find(" ", injectPos)}; + if (spacePos != std::string::npos) { + injectFile = command.substr(injectPos + 9, spacePos - injectPos - 9); + command = command.replace(injectPos, spacePos - injectPos + 1, ""); + } + else { + injectFile = command.substr(injectPos + 9, command.size() - injectPos); + command = command.replace(injectPos, command.size() - injectPos, ""); + } + } + + if (invalidEntry) { + LOG(LogError) << "Couldn't launch game, invalid %INJECT% entry"; + LOG(LogError) << "Raw emulator launch command:"; + LOG(LogError) << commandRaw; + + window->queueInfoPopup("ERROR: INVALID %INJECT% VARIABLE ENTRY", 6000); + window->setAllowTextScrolling(true); + window->setAllowFileAnimation(true); + return; + } + } + + if (injectFile != "") { +#if defined(_WIN64) + injectFile = Utils::String::replace(injectFile, "\\", "/"); + injectFile = Utils::String::replace(injectFile, "%BASENAME%", + Utils::String::replace(baseName, "\"", "")); + if (injectFile.size() < 3 || !(injectFile[1] == ':' && injectFile[2] == '/')) + injectFile = Utils::FileSystem::getParent(Utils::String::replace(romPath, "\"", "")) + + "/" + injectFile; + injectFile = Utils::String::replace(injectFile, "/", "\\"); +#else + injectFile = Utils::String::replace(injectFile, "%BASENAME%", + Utils::String::replace(baseName, "\\", "")); + if (injectFile.front() != '/') + injectFile = Utils::FileSystem::getParent(Utils::String::replace(romPath, "\\", "")) + + "/" + injectFile; +#endif + + if (Utils::FileSystem::isRegularFile(injectFile) || + Utils::FileSystem::isSymlink(injectFile)) { + LOG(LogDebug) << "FileData::launchGame(): Injecting arguments from file \"" + << injectFile << "\""; + std::string arguments; + std::ifstream injectFileStream; + injectFileStream.open(injectFile); + for (std::string line; getline(injectFileStream, line);) + arguments += line; + injectFileStream.close(); + + if (arguments.empty()) { + LOG(LogDebug) << "FileData::launchGame(): File empty or insufficient permissions, " + "nothing to inject"; + } + else if (arguments.size() > 4096) { + LOG(LogWarning) + << "FileData::launchGame(): Arguments file exceeding maximum allowed size of " + "4096 bytes, skipping injection"; + } + else { + command.insert(injectPos, arguments + " "); + } + } + else { + LOG(LogDebug) << "FileData::launchGame(): Arguments file \"" << injectFile + << "\" does not exist, skipping injection"; + } + } + #if defined(_WIN64) if (escapeSpecials) { bool foundSpecial {false};