mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Added command-line parameters.
However, there's an issue with initialisation and the whole multi-process thing making that difficult.
This commit is contained in:
+2
-1
@@ -64,7 +64,7 @@ set (LOOT_GUI_SRC ${LOOT_SRC}
|
||||
set (LOOT_API_SRC ${LOOT_SRC}
|
||||
"${CMAKE_SOURCE_DIR}/src/api/api.cpp")
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS log log_setup locale thread chrono date_time filesystem system regex iostreams)
|
||||
find_package(Boost REQUIRED COMPONENTS log log_setup locale thread chrono date_time filesystem program_options system regex iostreams)
|
||||
|
||||
# Include source and library directories.
|
||||
include_directories ("${CMAKE_SOURCE_DIR}/src"
|
||||
@@ -113,6 +113,7 @@ IF (MINGW)
|
||||
boost_chrono
|
||||
boost_date_time
|
||||
boost_filesystem
|
||||
boost_program_options
|
||||
boost_system
|
||||
boost_regex
|
||||
version
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ These instructions were used to build LOOT using Microsoft Visual Studio 2012 an
|
||||
|
||||
```
|
||||
bootstrap.bat
|
||||
b2 toolset=msvc threadapi=win32 link=static runtime-link=static variant=release address-model=32 --with-log --with-date_time --with-thread --with-filesystem --with-locale --with-regex --with-system --with-iostreams
|
||||
b2 toolset=msvc threadapi=win32 link=static runtime-link=static variant=release address-model=32 --with-log --with-date_time --with-thread --with-filesystem --with-program_options --with-locale --with-regex --with-system --with-iostreams
|
||||
```
|
||||
|
||||
`link`, `runtime-link` and `address-model` can all be modified if shared linking or 64 bit builds are desired. LOOT uses statically-linked Boost libraries by default: to change this, edit [CMakeLists.txt](../CMakeLists.txt).
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ These instructions were used to build LOOT using mingw-w64 on Ubuntu and Debian
|
||||
```
|
||||
./bootstrap.sh
|
||||
echo "using gcc : 4.6.3 : i686-w64-mingw32-g++ : <rc>i686-w64-mingw32-windres <archiver>i686-w64-mingw32-ar <ranlib>i686-w64-mingw32-ranlib ;" > tools/build/v2/user-config.jam
|
||||
./b2 toolset=gcc-4.6.3 target-os=windows threadapi=win32 link=static runtime-link=static variant=release address-model=32 cxxflags=-fPIC --with-log --with-date_time --with-thread --with-filesystem --with-locale --with-regex --with-system --with-iostreams --stagedir=stage-32
|
||||
./b2 toolset=gcc-4.6.3 target-os=windows threadapi=win32 link=static runtime-link=static variant=release address-model=32 cxxflags=-fPIC --with-log --with-date_time --with-thread --with-filesystem --with-program_options --with-locale --with-regex --with-system --with-iostreams
|
||||
```
|
||||
|
||||
#### Chromium Embedded Framework
|
||||
|
||||
+112
-2
@@ -27,13 +27,104 @@
|
||||
|
||||
#include <include/cef_browser.h>
|
||||
#include <include/cef_task.h>
|
||||
#include <include/cef_runnable.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/locale.hpp>
|
||||
|
||||
using namespace std;
|
||||
using boost::locale::translate;
|
||||
using boost::format;
|
||||
|
||||
namespace loot {
|
||||
|
||||
LootApp::LootApp(YAML::Node& settings) : _settings(settings) {}
|
||||
LootApp::LootApp() {}
|
||||
|
||||
void LootApp::Init(YAML::Node& settings, std::string& cmdLineGame) {
|
||||
_settings = settings;
|
||||
|
||||
string initError;
|
||||
|
||||
// Detect Games
|
||||
//-------------
|
||||
|
||||
int gameIndex = -1;
|
||||
|
||||
//Detect installed games.
|
||||
BOOST_LOG_TRIVIAL(debug) << "Detecting installed games.";
|
||||
try {
|
||||
_games = GetGames(settings);
|
||||
}
|
||||
catch (YAML::Exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Games' settings parsing failed. " << e.what();
|
||||
initError = (format(translate("Error: Games' settings parsing failed. %1%")) % e.what()).str();
|
||||
return;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Game-specific settings could not be initialised. " << e.what();
|
||||
initError = (format(translate("Error: Game-specific settings could not be initialised. %1%")) % e.what()).str();
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Selecting game.";
|
||||
|
||||
if (cmdLineGame.empty()) {
|
||||
if (_settings["Game"] && _settings["Game"].as<string>() != "auto")
|
||||
cmdLineGame = _settings["Game"].as<string>();
|
||||
else if (_settings["Last Game"] && _settings["Last Game"].as<string>() != "auto")
|
||||
cmdLineGame = _settings["Last Game"].as<string>();
|
||||
}
|
||||
|
||||
if (!cmdLineGame.empty()) {
|
||||
for (size_t i = 0, max = _games.size(); i < max; ++i) {
|
||||
if (cmdLineGame == _games[i].FolderName() && _games[i].IsInstalled())
|
||||
gameIndex = i;
|
||||
}
|
||||
}
|
||||
if (gameIndex < 0) {
|
||||
//Set gameIndex to the first installed game.
|
||||
for (size_t i = 0, max = _games.size(); i < max; ++i) {
|
||||
if (_games[i].IsInstalled()) {
|
||||
gameIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gameIndex < 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << "None of the supported games were detected.";
|
||||
initError = translate("Error: None of the supported games were detected.").str();
|
||||
return;
|
||||
}
|
||||
}
|
||||
loot::Game& game(_games[gameIndex]);
|
||||
BOOST_LOG_TRIVIAL(debug) << "Game selected is " << game.Name();
|
||||
|
||||
//Now that game is selected, initialise it.
|
||||
BOOST_LOG_TRIVIAL(debug) << "Initialising game-specific settings.";
|
||||
try {
|
||||
game.Init();
|
||||
*find(_games.begin(), _games.end(), game) = game; //Sync changes.
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Game-specific settings could not be initialised. " << e.what();
|
||||
initError = (format(translate("Error: Game-specific settings could not be initialised. %1%")) % e.what()).str();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the message object.
|
||||
CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("initJSVars");
|
||||
|
||||
// Retrieve the argument list object.
|
||||
CefRefPtr<CefListValue> args = msg>GetArgumentList();
|
||||
|
||||
// Populate the argument values.
|
||||
args->SetString(0, “my string”);
|
||||
args->SetInt(0, 10);
|
||||
|
||||
// Send the process message to the render process.
|
||||
// Use PID_BROWSER instead when sending a message to the browser process.
|
||||
browser->SendProcessMessage(PID_RENDERER, msg);
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserProcessHandler> LootApp::GetBrowserProcessHandler() {
|
||||
return this;
|
||||
@@ -90,8 +181,24 @@ namespace loot {
|
||||
// Register javascript functions.
|
||||
message_router_->OnContextCreated(browser, frame, context);
|
||||
|
||||
_context = context;
|
||||
}
|
||||
|
||||
void LootApp::OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Context> context) {
|
||||
|
||||
_context = NULL;
|
||||
}
|
||||
|
||||
void LootApp::InitJSVars() {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Populating JS object variable initial values.";
|
||||
|
||||
if (_context == NULL)
|
||||
return;
|
||||
|
||||
// Retrieve the context's window object.
|
||||
CefRefPtr<CefV8Value> object = context->GetGlobal();
|
||||
CefRefPtr<CefV8Value> object = _context->GetGlobal();
|
||||
|
||||
// Here the initialisation values should be set.
|
||||
|
||||
@@ -167,6 +274,9 @@ namespace loot {
|
||||
|
||||
lootObj->SetValue("languages", langsArr, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
|
||||
// Load Order
|
||||
//-----------
|
||||
|
||||
object->SetValue("loot", lootObj, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -38,7 +38,9 @@ namespace loot {
|
||||
public CefBrowserProcessHandler,
|
||||
public CefRenderProcessHandler {
|
||||
public:
|
||||
LootApp(YAML::Node& settings);
|
||||
LootApp();
|
||||
|
||||
void Init(YAML::Node& settings, std::string& cmdLineGame);
|
||||
|
||||
// Override CefApp methods.
|
||||
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE;
|
||||
@@ -59,6 +61,14 @@ namespace loot {
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Context> context) OVERRIDE;
|
||||
|
||||
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Context> context) OVERRIDE;
|
||||
|
||||
void InitJSVars();
|
||||
|
||||
CefRefPtr<CefV8Context> _context;
|
||||
|
||||
YAML::Node _settings;
|
||||
std::vector<loot::Game> _games;
|
||||
|
||||
|
||||
+85
-38
@@ -40,8 +40,10 @@
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
using namespace std;
|
||||
using namespace loot;
|
||||
@@ -50,11 +52,91 @@ using boost::format;
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
|
||||
|
||||
// Do application init
|
||||
//--------------------
|
||||
// Do all the standard CEF setup stuff.
|
||||
//-------------------------------------
|
||||
|
||||
// Set up CEF sandbox.
|
||||
CefScopedSandboxInfo scoped_sandbox;
|
||||
void * sandbox_info = scoped_sandbox.sandbox_info();
|
||||
|
||||
// Read command line arguments.
|
||||
CefMainArgs main_args(hInstance);
|
||||
|
||||
// Create the process reference.
|
||||
CefRefPtr<loot::LootApp> app(new loot::LootApp);
|
||||
|
||||
// Run the process.
|
||||
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
|
||||
if (exit_code >= 0) {
|
||||
// The sub-process has completed so return here.
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
string initError;
|
||||
string gameStr;
|
||||
YAML::Node settings;
|
||||
unsigned int verbosity = 0;
|
||||
|
||||
// Check if LOOT is already running
|
||||
//---------------------------------
|
||||
|
||||
HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"LOOT.Shell.Instance");
|
||||
if (hMutex != NULL) {
|
||||
// An instance of LOOT is already running, so quit.
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
//Create the mutex so that future instances will not run.
|
||||
hMutex = ::CreateMutex(NULL, FALSE, L"LOOT.Shell.Instance");
|
||||
}
|
||||
|
||||
// Handle command line args (not CEF args)
|
||||
//----------------------------------------
|
||||
|
||||
// declare the supported options
|
||||
po::options_description opts("Options");
|
||||
opts.add_options()
|
||||
("help,h", translate("produces this help message").str().c_str())
|
||||
("version,V", translate("prints the version banner").str().c_str())
|
||||
("game,g", po::value(&gameStr),
|
||||
translate("Override game autodetection. Valid values are the folder "
|
||||
"names defined in the settings file.").str().c_str());
|
||||
|
||||
// parse command line arguments
|
||||
po::variables_map vm;
|
||||
try{
|
||||
vector<wstring> args = po::split_winmain(lpCmdLine);
|
||||
po::store(po::wcommand_line_parser(args).options(opts).run(), vm);
|
||||
po::notify(vm);
|
||||
}
|
||||
catch (po::multiple_occurrences &){
|
||||
BOOST_LOG_TRIVIAL(error) << "Cannot specify options multiple times; please use the '--help' option to see usage instructions";
|
||||
std::cout << "Cannot specify options multiple times; please use the '--help' option to see usage instructions";
|
||||
return 1;
|
||||
}
|
||||
catch (exception & e){
|
||||
BOOST_LOG_TRIVIAL(error) << e.what() << "; please use the '--help' option to see usage instructions";
|
||||
std::cout << e.what() << "; please use the '--help' option to see usage instructions";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vm.count("help")) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Displaying command line help...";
|
||||
std::cout << opts << std::endl;
|
||||
if (hMutex != NULL)
|
||||
ReleaseMutex(hMutex);
|
||||
return 0;
|
||||
}
|
||||
if (vm.count("version")) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Displaying command line version...";
|
||||
std::cout << "LOOT v" << g_version_major << "." << g_version_minor << "." << g_version_patch << std::endl;
|
||||
if (hMutex != NULL)
|
||||
ReleaseMutex(hMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Do application init
|
||||
//--------------------
|
||||
|
||||
//Load settings.
|
||||
if (!fs::exists(g_path_settings)) {
|
||||
@@ -64,7 +146,6 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmd
|
||||
}
|
||||
catch (fs::filesystem_error& /*e*/) {
|
||||
initError = "Error: Could not create local app data LOOT folder.";
|
||||
return 1;
|
||||
}
|
||||
GenerateDefaultSettingsFile(g_path_settings.string());
|
||||
}
|
||||
@@ -75,7 +156,6 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmd
|
||||
}
|
||||
catch (YAML::ParserException& e) {
|
||||
initError = (format(translate("Error: Settings parsing failed. %1%")) % e.what()).str();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Set up logging.
|
||||
@@ -90,7 +170,6 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmd
|
||||
)
|
||||
);
|
||||
boost::log::add_common_attributes();
|
||||
unsigned int verbosity = 0;
|
||||
if (settings["Debug Verbosity"]) {
|
||||
verbosity = settings["Debug Verbosity"].as<unsigned int>();
|
||||
}
|
||||
@@ -128,39 +207,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmd
|
||||
cout.imbue(locale());
|
||||
boost::filesystem::path::imbue(locale());
|
||||
|
||||
// Now do all the standard CEF setup stuff.
|
||||
//----------------------------
|
||||
|
||||
// Set up CEF sandbox.
|
||||
CefScopedSandboxInfo scoped_sandbox;
|
||||
void * sandbox_info = scoped_sandbox.sandbox_info();
|
||||
|
||||
// Read command line arguments.
|
||||
CefMainArgs main_args(hInstance);
|
||||
|
||||
// Create the process reference.
|
||||
CefRefPtr<loot::LootApp> app(new loot::LootApp(settings));
|
||||
|
||||
// Run the process.
|
||||
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
|
||||
if (exit_code >= 0) {
|
||||
// The sub-process has completed so return here.
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
|
||||
// Check if LOOT is already running
|
||||
//---------------------------------
|
||||
|
||||
HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"LOOT.Shell.Instance");
|
||||
if (hMutex != NULL) {
|
||||
// An instance of LOOT is already running, so quit.
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
//Create the mutex so that future instances will not run.
|
||||
hMutex = ::CreateMutex(NULL, FALSE, L"LOOT.Shell.Instance");
|
||||
}
|
||||
app.get()->Init(settings, gameStr);
|
||||
|
||||
// Back to CEF
|
||||
//------------
|
||||
|
||||
Reference in New Issue
Block a user