Bug fixes.

Fixed resource paths in report being wrong, updating masterlist no
longer displays command line window, settings file is now read after
creation if creation is necessary, and fixed some error handling during
sorting.
This commit is contained in:
WrinklyNinja
2013-06-12 15:47:48 +01:00
parent 9947bdf251
commit 7544aca77f
8 changed files with 103 additions and 72 deletions
+3 -3
View File
@@ -129,11 +129,11 @@ namespace boss {
node = head.append_child();
node.set_name("link");
node.append_attribute("rel").set_value("stylesheet");
node.append_attribute("href").set_value("../resources/style.css");
node.append_attribute("href").set_value(ToFileURL(css_path).c_str());
node = head.append_child();
node.set_name("script");
node.append_attribute("src").set_value("../resources/polyfill.js");
node.append_attribute("src").set_value(ToFileURL(polyfill_path).c_str());
node.text().set(" ");
}
@@ -448,7 +448,7 @@ namespace boss {
node = body.append_child();
node.set_name("script");
node.append_attribute("src").set_value("../resources/script.js");
node.append_attribute("src").set_value(ToFileURL(js_path).c_str());
node.text().set(" ");
}
+4 -1
View File
@@ -49,10 +49,13 @@ namespace boss {
const unsigned int VERSION_PATCH = 0;
//Common paths.
const boost::filesystem::path readme_path = "Docs/BOSS Readme.html";
const boost::filesystem::path readme_path = "docs/BOSS Readme.html";
const boost::filesystem::path libespm_options_path = "resources/libespm.yaml";
const boost::filesystem::path svn_path = "resources/svn/svn.exe";
const boost::filesystem::path local_path = GetLocalAppDataPath() / "BOSS";
const boost::filesystem::path css_path = boost::filesystem::current_path() / "resources" / "style.css";
const boost::filesystem::path js_path = boost::filesystem::current_path() / "resources" / "script.js";
const boost::filesystem::path polyfill_path = boost::filesystem::current_path() / "resources" / "polyfill.js";
const boost::filesystem::path settings_path = local_path / "settings.yaml";
const boost::filesystem::path log_path = local_path / "BOSSDebugLog.txt";
}
+3
View File
@@ -54,6 +54,9 @@ namespace boss {
extern const boost::filesystem::path readme_path;
extern const boost::filesystem::path settings_path;
extern const boost::filesystem::path libespm_options_path;
extern const boost::filesystem::path css_path;
extern const boost::filesystem::path js_path;
extern const boost::filesystem::path polyfill_path;
extern const boost::filesystem::path svn_path;
extern const boost::filesystem::path log_path;
}
+25
View File
@@ -220,6 +220,31 @@ namespace boss {
return fs::path("");
#endif
}
//Turns an absolute filesystem path into a valid file:// URL.
std::string ToFileURL(const fs::path& file) {
//URLs are UTF-8 encoded then any characters (equiv. their corresponding bytes) not in the unreserved set (equiv. their corresponding bytes) are replaced by a percentage sign followed by the hex representation of their binary value.
string unreserved = "-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; //Unreserved in byte value order, plus the colon character since that's allowed for drive paths.
string url = "file://";
for (boost::filesystem::path::const_iterator it=file.begin(), endit=file.end(); it != endit; ++it) {
string part = it->string();
if (part == "/") //Skip exta backslash after drive path.
continue;
//String iterator is byte-by-byte, not character-by-character, which is good.
for (string::const_iterator jt=part.begin(), endjt=part.end(); jt != endjt; ++jt) {
if (!binary_search(unreserved.begin(), unreserved.end(), *jt))
//Replace with percentage-hex value.
url += '%' + IntToHexString(*jt);
else
url += *jt;
}
url += '/';
}
url.resize(url.length()-1); //Get rid of trailing forward slash.
return url;
}
//////////////////////////////
+3
View File
@@ -66,6 +66,9 @@ namespace boss {
//Get the local application data path.
boost::filesystem::path GetLocalAppDataPath();
//Turns an absolute filesystem path into a valid file:// URL.
std::string ToFileURL(const boost::filesystem::path& file);
//Version class for more robust version comparisons.
class Version {
private:
+25 -23
View File
@@ -73,7 +73,8 @@ namespace boss {
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = consoleWrite;
siStartInfo.hStdOutput = consoleWrite;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_HIDE;
const int utf16Len = MultiByteToWideChar(CP_UTF8, 0, command.c_str(), -1, NULL, 0);
wchar_t * cmdLine = new wchar_t[utf16Len];
@@ -126,36 +127,37 @@ namespace boss {
if (!RunCommand(command, output))
throw error(ERROR_SUBVERSION_ERROR, "Subversion could not update the masterlist. Details: " + output);
//Now test masterlist to see if it parses OK.
bool good = false;
while (!good) {
string revision;
while (true) {
try {
//Now get the masterlist revision.
command = svn_path.string() + " info \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output))
throw error(ERROR_SUBVERSION_ERROR, "Subversion could not read the masterlist revision number. Details: " + output);
size_t pos1 = output.rfind("Revision: ");
size_t pos2 = output.find('\n', pos1);
revision = output.substr(pos1+10, pos2-pos1-10);
pos1 = output.find("Last Changed Date: ", pos2);
pos2 = output.find(' ', pos1+19);
string date = output.substr(pos1+19, pos2-pos1-19);
//Now test masterlist to see if it parses OK.
YAML::Node mlist = YAML::LoadFile(game.MasterlistPath().string());
good = true;
return revision + " (" + date + ")";
} catch (YAML::Exception& e) {
//Roll back one revision if there's an error.
parsingErrors.push_back(e.what());
parsingErrors.push_back("Masterlist revision " + revision + ": " + e.what());
command = svn_path.string() + " update --revision PREV \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output))
throw error(ERROR_SUBVERSION_ERROR, "Subversion could not update the masterlist. Details: " + output);
}
}
//Now get the masterlist revision. Can either create a pipe using the Win32 API (http://msdn.microsoft.com/en-us/library/ms682499.aspx), or output to a file, read it, then delete it.
command = svn_path.string() + " info \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output))
throw error(ERROR_SUBVERSION_ERROR, "Subversion could not read the masterlist revision number. Details: " + output);
size_t pos1 = output.rfind("Revision: ");
size_t pos2 = output.find('\n', pos1);
string revision = output.substr(pos1+10, pos2-pos1-10);
pos1 = output.find("Last Changed Date: ", pos2);
pos2 = output.find(' ', pos1+19);
string date = output.substr(pos1+19, pos2-pos1-19);
return revision + " (" + date + ")";
}
}
+27 -32
View File
@@ -79,19 +79,7 @@ bool BossGUI::OnInit() {
}
//Load settings.
if (fs::exists(settings_path)) {
try {
_settings = YAML::LoadFile(settings_path.string());
} catch (YAML::ParserException& e) {
//LOG_ERROR("Error: %s", e.getString().c_str());
wxMessageBox(
FromUTF8(format(loc::translate("Error: Settings parsing failed. %1%")) % e.what()),
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
NULL);
return false;
}
} else {
if (!fs::exists(settings_path)) {
try {
if (!fs::exists(settings_path.parent_path()))
fs::create_directory(settings_path.parent_path());
@@ -105,6 +93,19 @@ bool BossGUI::OnInit() {
}
GenerateDefaultSettingsFile(settings_path.string());
}
if (fs::exists(settings_path)) {
try {
_settings = YAML::LoadFile(settings_path.string());
} catch (YAML::ParserException& e) {
//LOG_ERROR("Error: %s", e.getString().c_str());
wxMessageBox(
FromUTF8(format(loc::translate("Error: Settings parsing failed. %1%")) % e.what()),
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
NULL);
return false;
}
}
//Skip logging initialisation for tester.
/* if (gl_log_debug_output)
@@ -327,6 +328,11 @@ void Launcher::OnClose(wxCloseEvent& event) {
void Launcher::OnSortPlugins(wxCommandEvent& event) {
YAML::Node mlist, ulist;
list<boss::Message> messages, mlist_messages, ulist_messages;
list<boss::Plugin> mlist_plugins, ulist_plugins;
time_t start, end;
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);
@@ -334,7 +340,6 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
ofstream out((local_path / "out.txt").string().c_str());
out << "Updating masterlist..." << endl;
time_t start, end;
start = time(NULL);
vector<string> parsingErrors;
@@ -342,13 +347,10 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
try {
revision = UpdateMasterlist(_game, parsingErrors);
} catch (boss::error& e) {
//LOG_ERROR("Error: %s", e.what());
wxMessageBox(
FromUTF8(format(loc::translate("Error: Condition evaluation failed. %1%")) % e.what()),
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
this);
return;
messages.push_back(boss::Message(boss::MESSAGE_ERROR, string("Masterlist update failed. Details: ") + e.what()));
}
for (vector<string>::const_iterator it=parsingErrors.begin(), endit=parsingErrors.end(); it != endit; ++it) {
messages.push_back(boss::Message(boss::MESSAGE_ERROR, *it));
}
end = time(NULL);
@@ -376,10 +378,6 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
out << "Time taken to read plugins: " << (end - start) << " seconds." << endl;
start = time(NULL);
YAML::Node mlist, ulist;
list<boss::Message> messages, mlist_messages, ulist_messages;
list<boss::Plugin> mlist_plugins, ulist_plugins;
if (fs::exists(_game.MasterlistPath())) {
out << "Parsing masterlist..." << endl;
@@ -392,6 +390,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
this);
progDia->Destroy();
return;
}
if (mlist["globals"])
@@ -416,6 +415,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
this);
progDia->Destroy();
return;
}
if (ulist["plugins"])
@@ -461,13 +461,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
try {
it->EvalAllConditions(_game, lang);
} catch (boss::error& e) {
//LOG_ERROR("Error: %s", e.what());
wxMessageBox(
FromUTF8(format(loc::translate("Error: Condition evaluation failed. %1%")) % e.what()),
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
this);
return;
messages.push_back(boss::Message(boss::MESSAGE_ERROR, "\"" + it->Name() + "\" contains a condition that could not be evaluated. Details: " + e.what()));
}
progDia->Pulse();
@@ -652,6 +646,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
translate("BOSS: Error"),
wxOK | wxICON_ERROR,
this);
progDia->Destroy();
return;
}
+13 -13
View File
@@ -262,14 +262,14 @@ LangString TEXT_USERFILES ${LANG_SIMPCHINESE} "BOSS的userlist和BOSS.ini文件
File "..\build\libboss64.dll"
;Now install readme files.
SetOutPath "$INSTDIR\Docs"
SetOutPath "$INSTDIR\docs"
File "..\docs\BOSS API Readme.html"
File "..\docs\BOSS Metadata Syntax.html"
File "..\docs\BOSS Readme.html"
File "..\docs\Licenses.txt"
;Now install readme images.
SetOutPath "$INSTDIR\Docs\images"
SetOutPath "$INSTDIR\docs\images"
File "..\docs\images\editor.png"
File "..\docs\images\main.png"
File "..\docs\images\settings.png"
@@ -383,19 +383,19 @@ LangString TEXT_USERFILES ${LANG_SIMPCHINESE} "BOSS的userlist和BOSS.ini文件
RMDir "$INSTDIR\API"
;Remove readme files.
Delete "$INSTDIR\Docs\BOSS API Readme.html"
Delete "$INSTDIR\Docs\BOSS Metadata Syntax.html"
Delete "$INSTDIR\Docs\BOSS Readme.html"
Delete "$INSTDIR\Docs\Licenses.txt"
RMDir "$INSTDIR\Docs"
Delete "$INSTDIR\docs\BOSS API Readme.html"
Delete "$INSTDIR\docs\BOSS Metadata Syntax.html"
Delete "$INSTDIR\docs\BOSS Readme.html"
Delete "$INSTDIR\docs\Licenses.txt"
RMDir "$INSTDIR\docs"
;Remove readme images.
Delete "$INSTDIR\Docs\images\editor.png"
Delete "$INSTDIR\Docs\images\main.png"
Delete "$INSTDIR\Docs\images\settings.png"
Delete "$INSTDIR\Docs\images\viewer-1.png"
Delete "$INSTDIR\Docs\images\viewer-2.png"
RMDir "$INSTDIR\Docs\images"
Delete "$INSTDIR\docs\images\editor.png"
Delete "$INSTDIR\docs\images\main.png"
Delete "$INSTDIR\docs\images\settings.png"
Delete "$INSTDIR\docs\images\viewer-1.png"
Delete "$INSTDIR\docs\images\viewer-2.png"
RMDir "$INSTDIR\docs\images"
;Remove resource files.
Delete "$INSTDIR\resources\libespm.yaml"