diff --git a/BOSS.ico b/BOSS.ico
new file mode 100644
index 00000000..568cbaf2
Binary files /dev/null and b/BOSS.ico differ
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 47c938ec..f3dd0ad8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,8 @@ include_directories ("${PROJECT_LIBS_DIR}/alphanum" "${PROJECT_LIBS_DIR}/utf8" "
# Settings when compiling for Windows.
IF (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ add_definitions (-DUNICODE -D_UNICODE)
+ set (BOSS_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/resource.rc")
IF (${PROJECT_LINK} MATCHES "STATIC")
add_definitions (-DLIBLO_STATIC)
add_definitions (-DBOSS_STATIC)
@@ -52,8 +54,10 @@ IF (CMAKE_HOST_SYSTEM_NAME MATCHES "Linux")
set (CMAKE_MODULE_LINKER_FLAGS "-static-libstdc++ -static-libgcc")
IF (CMAKE_SYSTEM_NAME MATCHES "Windows")
- link_directories ("${PROJECT_LIBS_DIR}/boost/stage-mingw-${PROJECT_ARCH}/lib")
- set (BOSS_LIBS version)
+ link_directories ("${PROJECT_LIBS_DIR}/boost/stage-mingw-${PROJECT_ARCH}/lib" "${PROJECT_LIBS_DIR}/wxWidgets/build-msw/lib")
+ include_directories ("${PROJECT_LIBS_DIR}/wxWidgets/build-msw/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9" "${PROJECT_LIBS_DIR}/wxWidgets/include")
+ set (BOSS_LIBS version wx_mswu_core-2.9-i586-mingw32msvc wx_baseu-2.9-i586-mingw32msvc wx_mswu_adv-2.9-i586-mingw32msvc wxpng-2.9-i586-mingw32msvc wxzlib-2.9-i586-mingw32msvc comctl32)
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--subsystem,windows")
ENDIF ()
set (BOSS_LIBS ${BOSS_LIBS} zlibstatic loadorder yaml-cpp boost_locale boost_filesystem boost_system boost_regex)
@@ -65,14 +69,23 @@ IF (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
set (CMAKE_CXX_FLAGS "/EHsc")
ENDIF ()
+##############################
+# More General Settings
+##############################
+
+set (BOSS_GUI_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/gui/ids.cpp" "${CMAKE_SOURCE_DIR}/src/gui/main.cpp" "${CMAKE_SOURCE_DIR}/src/gui/settings.cpp")
+
+set (BOSS_API_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/api.cpp")
+
+
##############################
# Actual Building
##############################
# Build API.
-#add_library (boss ${PROJECT_LINK} "${CMAKE_SOURCE_DIR}/src/api.cpp" ${BOSS_SRC})
+#add_library (boss ${PROJECT_LINK} ${BOSS_API_SRC})
#target_link_libraries (boss ${BOSS_LIBS})
# Build tester.
-add_executable (tester "${CMAKE_SOURCE_DIR}/src/tester.cpp" ${BOSS_SRC})
-target_link_libraries (tester ${BOSS_LIBS})
+add_executable (BOSS ${BOSS_GUI_SRC})
+target_link_libraries (BOSS ${BOSS_LIBS})
diff --git a/examples/settings.yaml b/examples/settings.yaml
index 28041a9b..cf7c04aa 100644
--- a/examples/settings.yaml
+++ b/examples/settings.yaml
@@ -3,8 +3,8 @@
Language: eng # An ISO 639-3 language string.
-Game: auto # auto, oblivion, skyrim, fallout3, falloutnv
-Last Game: auto # auto, oblivion, skyrim, fallout3, falloutnv
+Game: auto # auto, oblivion, nehrim, skyrim, fallout3, falloutnv
+Last Game: auto # auto, oblivion, nehrim, skyrim, fallout3, falloutnv
Debug Verbosity: 0 # 0, 1, 2, 3. Logging takes place if > 0.
Update Masterlist: true
diff --git a/resource.rc b/resource.rc
new file mode 100644
index 00000000..15abb9f5
--- /dev/null
+++ b/resource.rc
@@ -0,0 +1,22 @@
+#include "wx/msw/wx.rc"
+1 VERSIONINFO
+ FILEVERSION 3,0,0,0
+ PRODUCTVERSION 3,0,0,0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileVersion", "3.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2013 WrinklyNinja"
+ VALUE "ProductVersion", "3.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+MAINICON ICON "BOSS.ico"
diff --git a/src/game.cpp b/src/game.cpp
index dc6fcc7d..acf6bf66 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -43,9 +43,7 @@ namespace fs = boost::filesystem;
namespace boss {
- Game::Game() {
- throw error(ERROR_INVALID_ARGS, "No arguments supplied.");
- }
+ Game::Game() {}
Game::Game(const unsigned int gameCode, const string path, const bool noPathInit)
: id(gameCode) {
diff --git a/src/globals.h b/src/globals.h
index c574624a..a4a267e8 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -30,6 +30,7 @@ namespace boss {
const unsigned int GAME_TES5 = 2;
const unsigned int GAME_FO3 = 3;
const unsigned int GAME_FONV = 4;
+ const unsigned int GAME_NEHRIM = 5;
const unsigned int VERSION_MAJOR = 3;
const unsigned int VERSION_MINOR = 0;
diff --git a/src/gui/ids.cpp b/src/gui/ids.cpp
new file mode 100644
index 00000000..df7ec623
--- /dev/null
+++ b/src/gui/ids.cpp
@@ -0,0 +1,38 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#include "ids.h"
+
+#include
+
+wxString translate(const std::string& str) {
+ return wxString(boost::locale::translate(str).str().c_str(), wxConvUTF8);
+}
+
+wxString FromUTF8(const std::string& str) {
+ return wxString(str.c_str(), wxConvUTF8);
+}
+
+wxString FromUTF8(const boost::format& f) {
+ return FromUTF8(f.str());
+}
diff --git a/src/gui/ids.h b/src/gui/ids.h
new file mode 100644
index 00000000..a2836dcb
--- /dev/null
+++ b/src/gui/ids.h
@@ -0,0 +1,74 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#ifndef __BOSS_GUI_IDS__
+#define __BOSS_GUI_IDS__
+
+#include
+#include
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+# include "wx/wx.h"
+#endif
+
+
+enum {
+ //Main window.
+ OPTION_EditMetadata = wxID_HIGHEST + 1, // declares an id which will be used to call our button
+ OPTION_ViewLastReport,
+ OPTION_SortPlugins,
+ MENU_Quit,
+ MENU_OpenMainReadMe,
+ MENU_OpenSyntaxReadMe,
+ MENU_OpenAPIReadMe,
+ MENU_OpenVersionHistory,
+ MENU_OpenLicenses,
+ MENU_ShowAbout,
+ MENU_ShowSettings,
+ MENU_Oblivion,
+ MENU_Nehrim,
+ MENU_Skyrim,
+ MENU_Fallout3,
+ MENU_FalloutNewVegas,
+ //Settings window.
+ OPTION_OKExitSettings,
+ OPTION_CancelExitSettings
+};
+
+wxString translate(const std::string& str);
+
+wxString FromUTF8(const std::string& str);
+
+wxString FromUTF8(const boost::format& f);
+
+// Temporary hacks.
+const char * const libespm_options_path = "libespm.cfg";
+const char * const libespm_game = "Skyrim";
+
+const char * const masterlist_path = "masterlist.yaml";
+const char * const userlist_path = "userlist.yaml";
+const char * const results_path = "results.yaml";
+const char * const settings_path = "settings.yaml";
+
+#endif
diff --git a/src/gui/main.cpp b/src/gui/main.cpp
new file mode 100644
index 00000000..c2674f83
--- /dev/null
+++ b/src/gui/main.cpp
@@ -0,0 +1,519 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#include "../globals.h"
+#include "../metadata.h"
+#include "../parsers.h"
+#include "main.h"
+#include "settings.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+BEGIN_EVENT_TABLE ( Launcher, wxFrame )
+ EVT_MENU ( MENU_Quit, Launcher::OnQuit )
+ EVT_MENU ( OPTION_EditMetadata, Launcher::OnEditMetadata )
+ EVT_MENU ( OPTION_ViewLastReport, Launcher::OnViewLastReport )
+ EVT_MENU ( OPTION_SortPlugins, Launcher::OnSortPlugins )
+ EVT_MENU ( MENU_OpenMainReadMe, Launcher::OnOpenFile )
+ EVT_MENU ( MENU_OpenSyntaxReadMe, Launcher::OnOpenFile )
+ EVT_MENU ( MENU_OpenAPIReadMe, Launcher::OnOpenFile )
+ EVT_MENU ( MENU_OpenVersionHistory, Launcher::OnOpenFile )
+ EVT_MENU ( MENU_OpenLicenses, Launcher::OnOpenFile )
+ EVT_MENU ( MENU_ShowAbout, Launcher::OnAbout )
+ EVT_MENU ( MENU_ShowSettings, Launcher::OnOpenSettings )
+ EVT_MENU ( MENU_Oblivion, Launcher::OnGameChange )
+ EVT_MENU ( MENU_Nehrim, Launcher::OnGameChange )
+ EVT_MENU ( MENU_Skyrim, Launcher::OnGameChange )
+ EVT_MENU ( MENU_Fallout3, Launcher::OnGameChange )
+ EVT_MENU ( MENU_FalloutNewVegas, Launcher::OnGameChange )
+ EVT_BUTTON ( OPTION_SortPlugins, Launcher::OnSortPlugins )
+ EVT_BUTTON ( OPTION_EditMetadata, Launcher::OnEditMetadata )
+ EVT_BUTTON ( OPTION_ViewLastReport, Launcher::OnViewLastReport )
+END_EVENT_TABLE()
+
+IMPLEMENT_APP(BossGUI);
+
+using namespace boss;
+using namespace std;
+
+namespace fs = boost::filesystem;
+namespace loc = boost::locale;
+
+// Temporary hacks.
+const fs::path readme_path = fs::path("Docs") / "BOSS Readme.html";
+const fs::path syntax_doc_path = fs::path("Docs") / "BOSS Metadata File Syntax.html";
+const fs::path api_doc_path = fs::path("Docs") / "BOSS API Readme.html";
+const fs::path version_history_path = fs::path("Docs") / "BOSS Version History.html";
+const fs::path licenses_path = fs::path("Docs") / "Licenses.txt";
+
+bool BossGUI::OnInit() {
+ //Check if GUI is already running.
+ wxSingleInstanceChecker *checker = new wxSingleInstanceChecker;
+
+ if (checker->IsAnotherRunning()) {
+ //Should print error message here.
+ delete checker; // OnExit() won't be called if we return false
+ checker = NULL;
+
+ return false;
+ }
+
+ //Load settings.
+ YAML::Node settings;
+ if (fs::exists(settings_path)) {
+ settings = YAML::LoadFile(settings_path);
+ }
+
+ //Apply logging and language settings (skipping for tester though).
+
+ //Also skipping game detection.
+ Game game(GAME_TES5);
+ vector detected;
+ detected.push_back(GAME_TES5);
+
+ //Create launcher window.
+ Launcher * launcher = new Launcher(wxT("BOSS"), settings, game, detected);
+
+ launcher->SetIcon(wxIconLocation("BOSS.exe"));
+ launcher->Show();
+ SetTopWindow(launcher);
+
+ return true;
+}
+
+Launcher::Launcher(const wxChar *title, const YAML::Node& settings, const Game& game, const vector& detectedGames) : wxFrame(NULL, wxID_ANY, title), _game(game), _detectedGames(detectedGames), _settings(settings) {
+
+ //Set up menu bar first.
+ MenuBar = new wxMenuBar();
+ // File Menu
+ FileMenu = new wxMenu();
+ FileMenu->Append(OPTION_ViewLastReport, translate("&View Last Report"), translate("Opens your last report."));
+ FileMenu->Append(OPTION_SortPlugins, translate("&Sort Plugins"), translate("Sorts your installed plugins."));
+ FileMenu->AppendSeparator();
+ FileMenu->Append(MENU_Quit, translate("&Quit"), translate("Quit BOSS."));
+ MenuBar->Append(FileMenu, translate("&File"));
+ //Edit Menu
+ EditMenu = new wxMenu();
+ EditMenu->Append(OPTION_EditMetadata, translate("&Metadata..."), translate("Opens a window where you can edit plugin metadata."));
+ EditMenu->Append(MENU_ShowSettings, translate("&Settings..."), translate("Opens the Settings window."));
+ MenuBar->Append(EditMenu, translate("&Edit"));
+ //Game menu
+ GameMenu = new wxMenu();
+ GameMenu->AppendRadioItem(MENU_Oblivion, wxT("&Oblivion"), translate("Switch to running BOSS for Oblivion."));
+ GameMenu->AppendRadioItem(MENU_Nehrim, wxT("&Nehrim"), translate("Switch to running BOSS for Nehrim."));
+ GameMenu->AppendRadioItem(MENU_Skyrim, wxT("&Skyrim"), translate("Switch to running BOSS for Skyrim."));
+ GameMenu->AppendRadioItem(MENU_Fallout3, wxT("&Fallout 3"), translate("Switch to running BOSS for Fallout 3."));
+ GameMenu->AppendRadioItem(MENU_FalloutNewVegas, wxT("&Fallout: New Vegas"), translate("Switch to running BOSS for Fallout: New Vegas."));
+ MenuBar->Append(GameMenu, translate("&Active Game"));
+ // About menu
+ HelpMenu = new wxMenu();
+ HelpMenu->Append(MENU_OpenMainReadMe, translate("Open &Main Readme"), translate("Opens the main BOSS readme in your default web browser."));
+ HelpMenu->Append(MENU_OpenSyntaxReadMe, translate("Open &Metadata File Syntax Doc"), translate("Opens the BOSS metadata file syntax documentation in your default web browser."));
+ HelpMenu->Append(MENU_OpenAPIReadMe, translate("&Open API Readme"), translate("Opens the BOSS API readme in your default web browser."));
+ HelpMenu->Append(MENU_OpenVersionHistory, translate("Open &Version History"), translate("Opens the BOSS version history in your default web browser."));
+ HelpMenu->Append(MENU_OpenLicenses, translate("View &Copyright Licenses"), translate("View the GNU General Public License v3.0 and GNU Free Documentation License v1.3."));
+ HelpMenu->AppendSeparator();
+ HelpMenu->Append(MENU_ShowAbout, translate("&About BOSS..."), translate("Shows information about BOSS."));
+ MenuBar->Append(HelpMenu, translate("&Help"));
+ SetMenuBar(MenuBar);
+
+ //Set up stuff in the frame.
+ SetBackgroundColour(wxColour(255,255,255));
+
+ //Add the three buttons.
+ wxBoxSizer *buttonBox = new wxBoxSizer(wxVERTICAL);
+ buttonBox->Add(EditButton = new wxButton(this,OPTION_EditMetadata, translate("Edit Metadata")), 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
+ buttonBox->Add(SortButton = new wxButton(this,OPTION_SortPlugins, translate("Sort Plugins")), 1, wxEXPAND|wxALIGN_CENTRE|wxLEFT|wxRIGHT, 10);
+ buttonBox->Add(ViewButton = new wxButton(this,OPTION_ViewLastReport, translate("View Last Report")), 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
+
+ SortButton->SetDefault();
+
+ if (_game.Id() == GAME_TES4)
+ GameMenu->FindItem(MENU_Oblivion)->Check();
+ else if (_game.Id() == GAME_NEHRIM)
+ GameMenu->FindItem(MENU_Nehrim)->Check();
+ else if (_game.Id() == GAME_TES5)
+ GameMenu->FindItem(MENU_Skyrim)->Check();
+ else if (_game.Id() == GAME_FO3)
+ GameMenu->FindItem(MENU_Fallout3)->Check();
+ else if (_game.Id() == GAME_FONV)
+ GameMenu->FindItem(MENU_FalloutNewVegas)->Check();
+
+ DisableUndetectedGames();
+
+ //Now set the layout and sizes.
+ SetSizerAndFit(buttonBox);
+ SetSize(wxSize(250, 200));
+}
+
+//Called when the frame exits.
+void Launcher::OnQuit(wxCommandEvent& event) {
+ Close(true); // Tells the OS to quit running this process
+}
+
+void Launcher::OnSortPlugins(wxCommandEvent& event) {
+
+ wxProgressDialog *progDia = new wxProgressDialog(translate("BOSS: Working..."),translate("BOSS working..."), 1000, this, wxPD_APP_MODAL|wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME);
+
+ time_t t0 = time(NULL);
+
+ /* Stuff still missing from a normal execution of BOSS:
+
+ - Reading of settings file.
+ - Detecting game to run for.
+ - Error handling.
+ - Masterlist updating.
+ - Checks for metadata self-consistency.
+ - Checks for cyclic dependencies and incompatibilities.
+ - Setting of load order.
+
+ Need to include libespm setup into game setup, once the former is made to be not global.
+ */
+
+ ofstream out("out.txt");
+
+ out << "Setting up libespm and BOSS..." << endl;
+
+ // Set up libesm.
+ common::options::setGame(libespm_game);
+ ifstream input(libespm_options_path);
+ common::readOptions(input);
+ input.close();
+
+ //Set up BOSS vars.
+ boss::Game game(boss::GAME_TES5);
+
+ out << "Reading plugins in Data folder..." << endl;
+ time_t start, end;
+ start = time(NULL);
+
+ // Get a list of the plugins.
+ list plugins;
+ for (fs::directory_iterator it(game.DataPath()); it != fs::directory_iterator(); ++it) {
+ if (fs::is_regular_file(it->status()) && (it->path().extension().string() == ".esp" || it->path().extension().string() == ".esm")) {
+
+ string filename = it->path().filename().string();
+ if (filename == "Skyrim.esm"
+ || filename == "Tamriel Compendium.esp"
+ || filename == "Tamriel Compendium - Skill Books.esp")
+ continue; // Libespm crashes with these plugins.
+
+ out << "Reading plugin: " << filename << endl;
+ boss::Plugin plugin(game, filename);
+ plugins.push_back(plugin);
+
+ progDia->Pulse();
+ }
+ }
+
+ end = time(NULL);
+ out << "Time taken to read plugins: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+
+ YAML::Node mlist, ulist;
+ list messages, mlist_messages, ulist_messages;
+ list mlist_plugins, ulist_plugins;
+
+ if (fs::exists(masterlist_path)) {
+ out << "Parsing masterlist..." << endl;
+
+ mlist = YAML::LoadFile(masterlist_path);
+ if (mlist["globals"])
+ mlist_messages = mlist["globals"].as< list >();
+ if (mlist["plugins"])
+ mlist_plugins = mlist["plugins"].as< list >();
+
+ end = time(NULL);
+ out << "Time taken to parse masterlist: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+ }
+
+ if (fs::exists(userlist_path)) {
+ out << "Parsing userlist..." << endl;
+
+ ulist = YAML::LoadFile(userlist_path);
+ if (ulist["globals"])
+ ulist_messages = ulist["globals"].as< list >();
+ if (ulist["plugins"])
+ ulist_plugins = ulist["plugins"].as< list >();
+
+ end = time(NULL);
+ out << "Time taken to parse userlist: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+ }
+
+ progDia->Pulse();
+
+ if (fs::exists(masterlist_path) || fs::exists(userlist_path)) {
+ out << "Merging plugin lists..." << endl;
+
+ //Merge all global message lists.
+ messages = mlist_messages;
+ messages.insert(messages.end(), ulist_messages.begin(), ulist_messages.end());
+
+ //Merge plugin list, masterlist and userlist plugin data.
+ for (list::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
+ //Check if there is already a plugin in the 'plugins' list or not.
+ list::iterator pos = std::find(mlist_plugins.begin(), mlist_plugins.end(), *it);
+
+ if (pos != mlist_plugins.end()) {
+ //Need to merge plugins.
+ it->Merge(*pos);
+ }
+
+ pos = std::find(ulist_plugins.begin(), ulist_plugins.end(), *it);
+
+ if (pos != ulist_plugins.end()) {
+ //Need to merge plugins.
+ it->Merge(*pos);
+ }
+ }
+
+ end = time(NULL);
+ out << "Time taken to merge lists: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+ }
+
+ progDia->Pulse();
+
+ out << "Evaluating any conditions in plugin list..." << endl;
+
+ for (list::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
+ try {
+ it->EvalAllConditions(game);
+ } catch (boss::error& e) {
+ out << e.what() << endl;
+ }
+ }
+
+ end = time(NULL);
+ out << "Time taken to evaluate plugin list: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+
+ progDia->Pulse();
+
+ out << "Checking install validity..." << endl;
+
+ for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
+ map issues = it->CheckInstallValidity(game);
+ for (map::const_iterator jt=issues.begin(), endJt=issues.end(); jt != endJt; ++jt) {
+ if (jt->second)
+ out << "Error: Invalid install detected! \"" << jt->first << "\" is incompatible with \"" << it->Name() << "\" and is present." << endl;
+ else
+ out << "Error: Invalid install detected! \"" << jt->first << "\" is required by \"" << it->Name() << "\" but is missing." << endl;
+ }
+ }
+
+
+
+ progDia->Pulse();
+
+ out << "Printing plugin details..." << endl;
+
+ for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
+ out << it->Name() << endl
+ << '\t' << "Number of records: " << it->FormIDs().size() << endl
+ << '\t' << "Is Master: " << it->IsMaster() << endl
+ << '\t' << "Masters:" << endl;
+
+ vector masters = it->Masters();
+ for(int i = 0; i < masters.size(); ++i)
+ out << '\t' << '\t' << i << ": " << masters[i] << endl;
+
+ out << '\t' << "Conflicts with:" << endl;
+ for (list::iterator jt=plugins.begin(), endJt = plugins.end(); jt != endJt; ++jt) {
+ if (*jt != *it && !jt->MustLoadAfter(*it)) {
+ size_t overlap = jt->OverlapFormIDs(*it).size();
+ if (overlap > 0)
+ out << '\t' << '\t' << jt->Name() << " (" << overlap << " records)" << endl;
+ }
+ }
+ }
+
+ progDia->Pulse();
+
+ end = time(NULL);
+ out << "Time taken to print plugins' details: " << (end - start) << " seconds." << endl;
+ start = time(NULL);
+
+ out << "Sorting plugins..." << endl;
+
+ plugins.sort();
+
+ end = time(NULL);
+ out << "Time taken to sort plugins: " << (end - start) << " seconds." << endl;
+
+ progDia->Pulse();
+
+ for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it)
+ out << it->Name() << endl;
+
+ out << "Writing results file..." << endl;
+
+ YAML::Emitter yout;
+ yout.SetIndent(2);
+ yout << YAML::BeginMap
+ << YAML::Key << "globals" << YAML::Value << messages
+ << YAML::Key << "plugins" << YAML::Value << plugins
+ << YAML::EndMap;
+
+ ofstream results_out(results_path);
+ results_out << yout.c_str();
+ results_out.close();
+
+ progDia->Pulse();
+
+ out << "Tester finished. Total time taken: " << time(NULL) - t0 << endl;
+ out.close();
+
+ progDia->Destroy();
+}
+
+void Launcher::OnEditMetadata(wxCommandEvent& event) {
+
+}
+
+void Launcher::OnViewLastReport(wxCommandEvent& event) {
+
+}
+
+void Launcher::OnOpenSettings(wxCommandEvent& event) {
+ //Tell the user that stuff is happenining.
+ SettingsFrame *settings = new SettingsFrame(translate("BOSS: Settings"), this, _settings);
+ settings->SetIcon(wxIconLocation("BOSS.exe"));
+ settings->Show();
+}
+
+void Launcher::OnGameChange(wxCommandEvent& event) {
+ try {
+ switch (event.GetId()) {
+ case MENU_Oblivion:
+ _game = Game(GAME_TES4);
+ _settings["Last Game"] = "oblivion";
+ break;
+ case MENU_Nehrim:
+ _game = Game(GAME_NEHRIM);
+ _settings["Last Game"] = "nehrim";
+ break;
+ case MENU_Skyrim:
+ _game = Game(GAME_TES5);
+ _settings["Last Game"] = "skyrim";
+ break;
+ case MENU_Fallout3:
+ _game = Game(GAME_FO3);
+ _settings["Last Game"] = "fallout3";
+ break;
+ case MENU_FalloutNewVegas:
+ _game = Game(GAME_FONV);
+ _settings["Last Game"] = "falloutnv";
+ break;
+ }
+ } catch (error& e) {
+ wxMessageBox(e.what(), translate("BOSS: Error"), wxOK | wxICON_ERROR, this);
+ }
+ _game.CreateBOSSGameFolder();
+ SetTitle(wxT("BOSS - " + _game.Name())); //Don't need to convert name, known to be only ASCII chars.
+}
+
+void Launcher::OnOpenFile(wxCommandEvent& event) {
+ string file;
+ if (event.GetId() == MENU_OpenMainReadMe)
+ file = readme_path.string();
+ else if (event.GetId() == MENU_OpenSyntaxReadMe)
+ file = syntax_doc_path.string();
+ else if (event.GetId() == MENU_OpenAPIReadMe)
+ file = api_doc_path.string();
+ else if (event.GetId() == MENU_OpenVersionHistory)
+ file = version_history_path.string();
+ else if (event.GetId() == MENU_OpenLicenses)
+ file = licenses_path.string();
+ //Look for file.
+ if (fs::exists(file)) {
+ wxLaunchDefaultApplication(file);
+ } else //No ReadMe exists, show a pop-up message saying so.
+ wxMessageBox(
+ FromUTF8(boost::format(loc::translate("Error: \"%1%\" cannot be found.")) % file),
+ translate("BOSS: Error"),
+ wxOK | wxICON_ERROR,
+ this);
+}
+
+void Launcher::OnAbout(wxCommandEvent& event) {
+ wxAboutDialogInfo aboutInfo;
+ aboutInfo.SetName("BOSS");
+ aboutInfo.SetVersion(IntToString(VERSION_MAJOR)+"."+IntToString(VERSION_MINOR)+"."+IntToString(VERSION_PATCH));
+ aboutInfo.SetDescription(translate("A utility that optimises \nTES IV: Oblivion, Nehrim - At Fate's Edge, TES V: Skyrim, Fallout 3 and Fallout: New Vegas mod load orders."));
+ aboutInfo.SetCopyright("Copyright (C) 2009-2013 BOSS Development Team.");
+ aboutInfo.SetWebSite("http://code.google.com/p/better-oblivion-sorting-software/");
+ aboutInfo.SetLicence("This program is free software: you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation, either version 3 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program. If not, see .");
+ aboutInfo.SetIcon(wxIconLocation("BOSS.exe"));
+ wxAboutBox(aboutInfo);
+}
+
+void Launcher::DisableUndetectedGames() {
+ GameMenu->FindItem(MENU_Oblivion)->Enable(false);
+ GameMenu->FindItem(MENU_Nehrim)->Enable(false);
+ GameMenu->FindItem(MENU_Skyrim)->Enable(false);
+ GameMenu->FindItem(MENU_Fallout3)->Enable(false);
+ GameMenu->FindItem(MENU_FalloutNewVegas)->Enable(false);
+ for (size_t i=0; i < _detectedGames.size(); i++) {
+ if (_detectedGames[i] == GAME_TES4)
+ GameMenu->FindItem(MENU_Oblivion)->Enable();
+ else if (_detectedGames[i] == GAME_NEHRIM)
+ GameMenu->FindItem(MENU_Nehrim)->Enable();
+ else if (_detectedGames[i] == GAME_TES5)
+ GameMenu->FindItem(MENU_Skyrim)->Enable();
+ else if (_detectedGames[i] == GAME_FO3)
+ GameMenu->FindItem(MENU_Fallout3)->Enable();
+ else if (_detectedGames[i] == GAME_FONV)
+ GameMenu->FindItem(MENU_FalloutNewVegas)->Enable();
+ }
+
+ SetTitle(wxT("BOSS - " + _game.Name())); //Don't need to convert name, known to be only ASCII chars.
+}
diff --git a/src/gui/main.h b/src/gui/main.h
new file mode 100644
index 00000000..9153fc2b
--- /dev/null
+++ b/src/gui/main.h
@@ -0,0 +1,71 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#ifndef __BOSS_GUI_MAIN__
+#define __BOSS_GUI_MAIN__
+
+#include "ids.h"
+#include "../game.h"
+
+#include
+#include
+
+//Program class.
+class BossGUI : public wxApp {
+public:
+ bool OnInit(); //Load settings, apply logging and language settings, check if BOSS is already running, detect games, set game to last game or to first detected game if auto, create launcher window.
+};
+
+class Launcher : public wxFrame {
+public:
+ Launcher(const wxChar *title, const YAML::Node& settings, const boss::Game& inGame, const std::vector& inGames);
+
+ void OnSortPlugins(wxCommandEvent& event);
+ void OnEditMetadata(wxCommandEvent& event);
+ void OnViewLastReport(wxCommandEvent& event);
+
+ void OnOpenSettings(wxCommandEvent& event);
+ void OnGameChange(wxCommandEvent& event);
+ void OnOpenFile(wxCommandEvent& event);
+ void OnAbout(wxCommandEvent& event);
+ void OnQuit(wxCommandEvent& event);
+
+ DECLARE_EVENT_TABLE()
+private:
+ wxMenuBar *MenuBar;
+ wxMenu *FileMenu;
+ wxMenu *EditMenu;
+ wxMenu *GameMenu;
+ wxMenu *HelpMenu;
+ wxButton *SortButton;
+ wxButton *ViewButton;
+ wxButton *EditButton;
+
+ std::vector _detectedGames;
+ boss::Game _game;
+ YAML::Node _settings; //BOSS Settings.
+
+ void DisableUndetectedGames();
+};
+
+#endif
diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp
new file mode 100644
index 00000000..cad68914
--- /dev/null
+++ b/src/gui/settings.cpp
@@ -0,0 +1,239 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#include "settings.h"
+#include
+
+BEGIN_EVENT_TABLE ( SettingsFrame, wxFrame )
+ EVT_BUTTON ( OPTION_OKExitSettings, SettingsFrame::OnQuit)
+ EVT_BUTTON ( OPTION_CancelExitSettings, SettingsFrame::OnQuit)
+END_EVENT_TABLE()
+
+using namespace std;
+
+SettingsFrame::SettingsFrame(const wxString title, wxFrame *parent, YAML::Node& settings) : wxFrame(parent, wxID_ANY, title), _settings(settings) {
+
+ wxString DebugVerbosity[] = {
+ translate("None"),
+ translate("Low"),
+ translate("Medium"),
+ translate("High")
+ };
+
+ wxString Game[] = {
+ translate("Autodetect"),
+ wxT("Oblivion"),
+ wxT("Nehrim"),
+ wxT("Skyrim"),
+ wxT("Fallout 3"),
+ wxT("Fallout: New Vegas"),
+ };
+
+ wxString Language[] = {
+ wxT("English"),
+ /* wxString("Español", wxConvUTF8),
+ wxT("Deutsch"),
+ wxString("Русский", wxConvUTF8),
+ wxString("简体中文", wxConvUTF8)*/
+ };
+
+ //Set up stuff in the frame.
+ SetBackgroundColour(wxColour(255,255,255));
+
+ wxSizerFlags leftItem(1);
+ leftItem.Border(wxALL, 10).Expand().Left();
+
+ wxSizerFlags rightItem(0);
+ rightItem.Border(wxALL, 10).Expand().Right();
+
+ wxSizerFlags wholeItem(1);
+ wholeItem.Border(wxALL, 10).Expand();
+
+ wxBoxSizer *bigBox = new wxBoxSizer(wxVERTICAL);
+
+ wxFlexGridSizer *GridSizer = new wxFlexGridSizer(2, 5, 5);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Default Game:")), leftItem);
+ GridSizer->Add(GameChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 6, Game), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Language:")), leftItem);
+ GridSizer->Add(LanguageChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, Language), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Debug Verbosity:")), leftItem);
+ GridSizer->Add(DebugVerbosityChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 4, DebugVerbosity), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Oblivion Masterlist URL:")), leftItem);
+ GridSizer->Add(OblivionURL = new wxTextCtrl(this, wxID_ANY), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Nehrim Masterlist URL:")), leftItem);
+ GridSizer->Add(NehrimURL = new wxTextCtrl(this, wxID_ANY), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Skyrim Masterlist URL:")), leftItem);
+ GridSizer->Add(SkyrimURL = new wxTextCtrl(this, wxID_ANY), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Fallout 3 Masterlist URL:")), leftItem);
+ GridSizer->Add(FO3URL = new wxTextCtrl(this, wxID_ANY), rightItem);
+
+ GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Fallout: New Vegas Masterlist URL:")), leftItem);
+ GridSizer->Add(FONVURL = new wxTextCtrl(this, wxID_ANY), rightItem);
+
+ bigBox->Add(GridSizer);
+
+ bigBox->Add(UpdateMasterlistBox = new wxCheckBox(this, wxID_ANY, translate("Update masterlist before sorting.")), wholeItem);
+
+ wxString text = translate("Language settings will be applied after the BOSS GUI is restarted.");
+ bigBox->Add(new wxStaticText(this, wxID_ANY, text), wholeItem);
+
+ //Need to add 'OK' and 'Cancel' buttons.
+ wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
+ hbox->Add(new wxButton(this, OPTION_OKExitSettings, translate("OK"), wxDefaultPosition, wxSize(70, 30)));
+ hbox->Add(new wxButton(this, OPTION_CancelExitSettings, translate("Cancel"), wxDefaultPosition, wxSize(70, 30)), 0, wxLEFT, 20);
+
+ //Now add TabHolder and OK button to window sizer.
+ bigBox->Add(hbox, 0, wxCENTER|wxALL, 10);
+
+ //Initialise options with values. For checkboxes, they are off by default.
+ SetDefaultValues();
+
+ //Tooltips.
+ DebugVerbosityChoice->SetToolTip(translate("The output is logged to the BOSSDebugLog.txt file"));
+
+ //Now set the layout and sizes.
+ SetSizerAndFit(bigBox);
+}
+
+void SettingsFrame::SetDefaultValues() {
+
+ if (_settings["Language"]) {
+ string lang = _settings["Language"].as();
+ if (lang == "eng")
+ LanguageChoice->SetSelection(0);
+ }
+
+ if (_settings["Game"]) {
+ string game = _settings["Game"].as();
+ if (game == "auto")
+ GameChoice->SetSelection(0);
+ else if (game == "oblivion")
+ GameChoice->SetSelection(1);
+ else if (game == "nehrim")
+ GameChoice->SetSelection(2);
+ else if (game == "skyrim")
+ GameChoice->SetSelection(3);
+ else if (game == "fallout3")
+ GameChoice->SetSelection(4);
+ else if (game == "falloutnv")
+ GameChoice->SetSelection(5);
+ }
+
+ if (_settings["Debug Verbosity"]) {
+ unsigned int verbosity = _settings["Debug Verbosity"].as();
+ DebugVerbosityChoice->SetSelection(verbosity);
+ }
+
+ if (_settings["Update Masterlist"]) {
+ bool update = _settings["Update Masterlist"].as();
+ UpdateMasterlistBox->SetValue(update);
+ }
+
+ if (_settings["Masterlist URLs"]) {
+ YAML::Node urls = _settings["Masterlist URLs"];
+
+ if (urls["Oblivion"])
+ OblivionURL->SetValue(urls["Oblivion"].as());
+
+ if (urls["Nehrim"])
+ NehrimURL->SetValue(urls["Nehrim"].as());
+
+ if (urls["Skyrim"])
+ SkyrimURL->SetValue(urls["Skyrim"].as());
+
+ if (urls["Fallout 3"])
+ FO3URL->SetValue(urls["Fallout 3"].as());
+
+ if (urls["Fallout New Vegas"])
+ FONVURL->SetValue(urls["Fallout New Vegas"].as());
+ }
+}
+
+void SettingsFrame::OnQuit(wxCommandEvent& event) {
+ if (event.GetId() == OPTION_OKExitSettings) {
+
+ switch (GameChoice->GetSelection()) {
+ case 0:
+ _settings["Game"] = "auto";
+ break;
+ case 1:
+ _settings["Game"] = "oblivion";
+ break;
+ case 2:
+ _settings["Game"] = "nehrim";
+ break;
+ case 3:
+ _settings["Game"] = "skyrim";
+ break;
+ case 4:
+ _settings["Game"] = "fallout3";
+ break;
+ case 5:
+ _settings["Game"] = "falloutnv";
+ break;
+ }
+
+ switch (LanguageChoice->GetSelection()) {
+ case 0:
+ _settings["Language"] = "eng";
+ break;
+ }
+
+ _settings["Debug Verbosity"] = DebugVerbosityChoice->GetSelection();
+
+ _settings["Update Masterlist"] = UpdateMasterlistBox->IsChecked();
+
+ _settings["Masterlist URLs"]["Oblivion"] = string(OblivionURL->GetValue().ToUTF8());
+
+ _settings["Masterlist URLs"]["Nehrim"] = string(NehrimURL->GetValue().ToUTF8());
+
+ _settings["Masterlist URLs"]["Skyrim"] = string(SkyrimURL->GetValue().ToUTF8());
+
+ _settings["Masterlist URLs"]["Fallout 3"] = string(FO3URL->GetValue().ToUTF8());
+
+ _settings["Masterlist URLs"]["Fallout New Vegas"] = string(FONVURL->GetValue().ToUTF8());
+
+ //Also set the logger settings now.
+ /* g_logger.setOriginTracking(gl_debug_with_source);
+ g_logger.setVerbosity(static_cast(LV_WARN + gl_debug_verbosity));
+ if (gl_log_debug_output)
+ g_logger.setStream(debug_log_path.string().c_str());*/
+
+ YAML::Emitter yout;
+ yout.SetIndent(2);
+ yout << _settings;
+
+ ofstream out(settings_path);
+ out << yout.c_str();
+ out.close();
+ }
+
+ this->Close();
+}
diff --git a/src/gui/settings.h b/src/gui/settings.h
new file mode 100644
index 00000000..addff22a
--- /dev/null
+++ b/src/gui/settings.h
@@ -0,0 +1,50 @@
+/* BOSS
+
+ A plugin load order optimiser for games that use the esp/esm plugin system.
+
+ Copyright (C) 2013 WrinklyNinja
+
+ This file is part of BOSS.
+
+ BOSS is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ BOSS is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BOSS. If not, see
+ .
+*/
+
+#ifndef __BOSS_GUI_SETTINGS__
+#define __BOSS_GUI_SETTINGS__
+
+#include "ids.h"
+#include
+#include
+
+class SettingsFrame : public wxFrame {
+public:
+ SettingsFrame(const wxString title, wxFrame *parent, YAML::Node& settings);
+ void OnQuit(wxCommandEvent& event);
+ void SetDefaultValues();
+ DECLARE_EVENT_TABLE()
+private:
+ wxChoice *DebugVerbosityChoice;
+ wxChoice *GameChoice;
+ wxChoice *LanguageChoice;
+ wxCheckBox *UpdateMasterlistBox;
+ wxTextCtrl *OblivionURL;
+ wxTextCtrl *NehrimURL;
+ wxTextCtrl *SkyrimURL;
+ wxTextCtrl *FO3URL;
+ wxTextCtrl *FONVURL;
+
+ YAML::Node _settings;
+};
+#endif
diff --git a/src/helpers.cpp b/src/helpers.cpp
index dfce504b..87bddc5b 100644
--- a/src/helpers.cpp
+++ b/src/helpers.cpp
@@ -63,10 +63,10 @@
namespace boss {
using namespace std;
- using namespace boost;
using boost::algorithm::replace_all;
using boost::algorithm::replace_first;
namespace karma = boost::spirit::karma;
+ namespace fs = boost::filesystem;
//Calculate the CRC of the given file for comparison purposes.
uint32_t GetCrc32(const fs::path& filename) {
diff --git a/src/helpers.h b/src/helpers.h
index fa10083d..05d3567e 100644
--- a/src/helpers.h
+++ b/src/helpers.h
@@ -33,14 +33,13 @@
#include
namespace boss {
- namespace fs = boost::filesystem;
//////////////////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////////////////
//Calculate the CRC of the given file for comparison purposes.
- uint32_t GetCrc32(const fs::path& filename);
+ uint32_t GetCrc32(const boost::filesystem::path& filename);
//Converts an integer to a string using BOOST's Spirit.Karma. Faster than a stringstream conversion.
std::string IntToString(const int n);
@@ -65,7 +64,7 @@ namespace boss {
Version();
Version(const char * ver);
Version(const std::string ver);
- Version(const fs::path file);
+ Version(const boost::filesystem::path file);
std::string AsString() const;
diff --git a/src/metadata.cpp b/src/metadata.cpp
index 781b2d86..1351fea2 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -479,16 +479,16 @@ namespace boss {
map issues;
if (tags.find(Tag("Filter")) == tags.end()) {
for (vector::const_iterator it=masters.begin(), endIt=masters.end(); it != endIt; ++it) {
- if (!fs::exists(game.DataPath() / *it))
+ if (!boost::filesystem::exists(game.DataPath() / *it))
issues.insert(pair(*it,false));
}
}
for (set::const_iterator it=requirements.begin(), endIt=requirements.end(); it != endIt; ++it) {
- if (!fs::exists(game.DataPath() / it->Name()))
+ if (!boost::filesystem::exists(game.DataPath() / it->Name()))
issues.insert(pair(it->Name(),false));
}
for (set::const_iterator it=incompatibilities.begin(), endIt=incompatibilities.end(); it != endIt; ++it) {
- if (fs::exists(game.DataPath() / it->Name()))
+ if (boost::filesystem::exists(game.DataPath() / it->Name()))
issues.insert(pair(it->Name(),true));
}
return issues;
diff --git a/src/parsers.h b/src/parsers.h
index 575ba4bf..92c85e9d 100644
--- a/src/parsers.h
+++ b/src/parsers.h
@@ -436,7 +436,7 @@ namespace boss {
throw boss::error(boss::ERROR_INVALID_ARGS, "The regex string \"" + filename + "\" is invalid.");
}
- for (fs::directory_iterator itr(parent_path); itr != fs::directory_iterator(); ++itr) {
+ for (boost::filesystem::directory_iterator itr(parent_path); itr != boost::filesystem::directory_iterator(); ++itr) {
if (boost::regex_match(itr->path().filename().string(), regex)) {
result = true;
return;
diff --git a/src/tester.cpp b/src/tester.cpp
deleted file mode 100644
index d1fd5689..00000000
--- a/src/tester.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/* BOSS
-
- A plugin load order optimiser for games that use the esp/esm plugin system.
-
- Copyright (C) 2012 WrinklyNinja
-
- This file is part of BOSS.
-
- BOSS is free software: you can redistribute
- it and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- BOSS is distributed in the hope that it will
- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BOSS. If not, see
- .
-*/
-
-#include
-#include "metadata.h"
-#include "parsers.h"
-#include "game.h"
-#include "error.h"
-#include "globals.h"
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-
-namespace fs = boost::filesystem;
-
-using namespace std;
-
-// Temporary hack.
-const char * const libespm_options_path = "libespm.cfg";
-const char * const libespm_game = "Skyrim";
-
-const char * const masterlist_path = "masterlist.yaml";
-const char * const userlist_path = "userlist.yaml";
-const char * const results_path = "results.yaml";
-
-int main(int argc, char *argv[]) {
-
- time_t t0 = time(NULL);
-
- /* Stuff still missing from a normal execution of BOSS:
-
- - Reading of settings file.
- - Detecting game to run for.
- - Error handling.
- - Masterlist updating.
- - Checks for metadata self-consistency.
- - Checks for cyclic dependencies and incompatibilities.
- - Setting of load order.
-
- Need to include libespm setup into game setup, once the former is made to be not global.
- */
-
- cout << "Setting up libespm and BOSS..." << endl;
-
- // Set up libesm.
- common::options::setGame(libespm_game);
- ifstream input(libespm_options_path);
- common::readOptions(input);
- input.close();
-
- //Set up BOSS vars.
- boss::Game game(boss::GAME_TES5);
-
- cout << "Reading plugins in Data folder..." << endl;
- time_t start, end;
- start = time(NULL);
-
- // Get a list of the plugins.
- list plugins;
- for (fs::directory_iterator it(game.DataPath()); it != fs::directory_iterator(); ++it) {
- if (fs::is_regular_file(it->status()) && (it->path().extension().string() == ".esp" || it->path().extension().string() == ".esm")) {
-
- string filename = it->path().filename().string();
- if (filename == "Skyrim.esm"
- || filename == "Tamriel Compendium.esp"
- || filename == "Tamriel Compendium - Skill Books.esp")
- continue; // Libespm crashes with these plugins.
-
- cout << "Reading plugin: " << filename << endl;
- boss::Plugin plugin(game, filename);
- plugins.push_back(plugin);
- }
- }
-
- end = time(NULL);
- cout << "Time taken to read plugins: " << (end - start) << " seconds." << endl;
- start = time(NULL);
-
- YAML::Node mlist, ulist;
- list messages, mlist_messages, ulist_messages;
- list mlist_plugins, ulist_plugins;
-
- if (fs::exists(masterlist_path)) {
- cout << "Parsing masterlist..." << endl;
-
- mlist = YAML::LoadFile(masterlist_path);
- if (mlist["globals"])
- mlist_messages = mlist["globals"].as< list >();
- if (mlist["plugins"])
- mlist_plugins = mlist["plugins"].as< list >();
-
- end = time(NULL);
- cout << "Time taken to parse masterlist: " << (end - start) << " seconds." << endl;
- start = time(NULL);
- }
-
- if (fs::exists(userlist_path)) {
- cout << "Parsing userlist..." << endl;
-
- ulist = YAML::LoadFile(userlist_path);
- if (ulist["globals"])
- ulist_messages = ulist["globals"].as< list >();
- if (ulist["plugins"])
- ulist_plugins = ulist["plugins"].as< list >();
-
- end = time(NULL);
- cout << "Time taken to parse userlist: " << (end - start) << " seconds." << endl;
- start = time(NULL);
- }
-
- if (fs::exists(masterlist_path) || fs::exists(userlist_path)) {
- cout << "Merging plugin lists..." << endl;
-
- //Merge all global message lists.
- messages = mlist_messages;
- messages.insert(messages.end(), ulist_messages.begin(), ulist_messages.end());
-
- //Merge plugin list, masterlist and userlist plugin data.
- for (list::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
- //Check if there is already a plugin in the 'plugins' list or not.
- list::iterator pos = std::find(mlist_plugins.begin(), mlist_plugins.end(), *it);
-
- if (pos != mlist_plugins.end()) {
- //Need to merge plugins.
- it->Merge(*pos);
- }
-
- pos = std::find(ulist_plugins.begin(), ulist_plugins.end(), *it);
-
- if (pos != ulist_plugins.end()) {
- //Need to merge plugins.
- it->Merge(*pos);
- }
- }
-
- end = time(NULL);
- cout << "Time taken to merge lists: " << (end - start) << " seconds." << endl;
- start = time(NULL);
- }
-
- cout << "Evaluating any conditions in plugin list..." << endl;
-
- for (list::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
- try {
- it->EvalAllConditions(game);
- } catch (boss::error& e) {
- cout << e.what() << endl;
- }
- }
-
- end = time(NULL);
- cout << "Time taken to evaluate plugin list: " << (end - start) << " seconds." << endl;
- start = time(NULL);
-
- cout << "Checking install validity..." << endl;
-
- for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
- map issues = it->CheckInstallValidity(game);
- for (map::const_iterator jt=issues.begin(), endJt=issues.end(); jt != endJt; ++jt) {
- if (jt->second)
- cout << "Error: Invalid install detected! \"" << jt->first << "\" is incompatible with \"" << it->Name() << "\" and is present." << endl;
- else
- cout << "Error: Invalid install detected! \"" << jt->first << "\" is required by \"" << it->Name() << "\" but is missing." << endl;
- }
- }
-
-
-
- cout << "Printing plugin details..." << endl;
-
- for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
- cout << it->Name() << endl
- << '\t' << "Number of records: " << it->FormIDs().size() << endl
- << '\t' << "Is Master: " << it->IsMaster() << endl
- << '\t' << "Masters:" << endl;
-
- vector masters = it->Masters();
- for(int i = 0; i < masters.size(); ++i)
- cout << '\t' << '\t' << i << ": " << masters[i] << endl;
-
- cout << '\t' << "Conflicts with:" << endl;
- for (list::iterator jt=plugins.begin(), endJt = plugins.end(); jt != endJt; ++jt) {
- if (*jt != *it && !jt->MustLoadAfter(*it)) {
- size_t overlap = jt->OverlapFormIDs(*it).size();
- if (overlap > 0)
- cout << '\t' << '\t' << jt->Name() << " (" << overlap << " records)" << endl;
- }
- }
- }
-
- end = time(NULL);
- cout << "Time taken to print plugins' details: " << (end - start) << " seconds." << endl;
- start = time(NULL);
-
- cout << "Sorting plugins..." << endl;
-
- plugins.sort();
-
- end = time(NULL);
- cout << "Time taken to sort plugins: " << (end - start) << " seconds." << endl;
-
- for (list::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it)
- cout << it->Name() << endl;
-
- cout << "Writing results file..." << endl;
-
- YAML::Emitter yout;
- yout.SetIndent(2);
- yout << YAML::BeginMap
- << YAML::Key << "globals" << YAML::Value << messages
- << YAML::Key << "plugins" << YAML::Value << plugins
- << YAML::EndMap;
-
- ofstream out(results_path);
- out << yout.c_str();
- out.close();
-
- cout << "Tester finished. Total time taken: " << time(NULL) - t0 << endl;
- return 0;
-}