Skip to content

Commit

Permalink
Cleanup and add proper validation system.
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinW1998 committed Nov 13, 2015
1 parent 85818ff commit 9214dc0
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 53 deletions.
3 changes: 2 additions & 1 deletion LunadllNewLauncher/SMBXLauncher/SMBXLauncher.pro
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ HEADERS += mainlauncherwindow.h \
PGE_File_Formats/smbx64_macro.h \
PGE_File_Formats/wld_filedata.h \
controlconfig.h \
launcherconfiguration.h
launcherconfiguration.h \
qjsonutil.h

FORMS += mainlauncherwindow.ui

Expand Down
32 changes: 30 additions & 2 deletions LunadllNewLauncher/SMBXLauncher/launcherconfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QApplication>
#include "qjsonutil.h"


QJsonDocument LauncherConfiguration::generateDefault()
{
Expand All @@ -26,6 +28,9 @@ QJsonDocument LauncherConfiguration::generateDefault()

}

LauncherConfiguration::LauncherConfiguration() : LauncherConfiguration(generateDefault())
{}

LauncherConfiguration::LauncherConfiguration(const QJsonDocument &settingsToParse)
{
QJsonObject mainObject = settingsToParse.object();
Expand All @@ -37,6 +42,31 @@ LauncherConfiguration::LauncherConfiguration(const QJsonDocument &settingsToPars
version4 = gameValue.value("version-4").toInt(0);
}

bool LauncherConfiguration::setConfigurationAndValidate(const QJsonDocument &settingsToParse, const std::function<void (VALIDATE_ERROR, const QString &)> &errFunc)
{
if(!settingsToParse.isObject()){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_NO_CHILD, "<root>");
return false;
}

QJsonObject mainObject = settingsToParse.object();
if(!qJsonValidate<QJsonObject>(mainObject, "game", errFunc)) return false;

QJsonObject gameObject = mainObject.value("game").toObject();
if(!qJsonValidate<QString>(gameObject, "update-check-website", errFunc)) return false;
if(!qJsonValidate<int>(gameObject, "version-1", errFunc)) return false;
if(!qJsonValidate<int>(gameObject, "version-2", errFunc)) return false;
if(!qJsonValidate<int>(gameObject, "version-3", errFunc)) return false;
if(!qJsonValidate<int>(gameObject, "version-4", errFunc)) return false;
updateCheckWebsite = gameObject.value("update-check-website").toString(".");
version1 = gameObject.value("version-1").toInt(0);
version2 = gameObject.value("version-2").toInt(0);
version3 = gameObject.value("version-3").toInt(0);
version4 = gameObject.value("version-4").toInt(0);
return true;
}

#include <iostream>

bool LauncherConfiguration::checkForUpdate(QJsonDocument *result, UpdateCheckerErrCodes& errCode, QString& errDescription)
Expand Down Expand Up @@ -71,8 +101,6 @@ bool LauncherConfiguration::checkForUpdate(QJsonDocument *result, UpdateCheckerE
while(!replyFinished)
qApp->processEvents();



QByteArray data = rpl->readAll();
if(data.isEmpty()){
errCode = UERR_CONNECTION_FAILED;
Expand Down
6 changes: 6 additions & 0 deletions LunadllNewLauncher/SMBXLauncher/launcherconfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <QJsonDocument>
#include <QPair>
#include <functional>
#include "qjsonutil.h"

class LauncherConfiguration
{
Expand All @@ -22,7 +24,11 @@ class LauncherConfiguration
UERR_INVALID_JSON
};

LauncherConfiguration();
LauncherConfiguration(const QJsonDocument &settingsToParse);

bool setConfigurationAndValidate(const QJsonDocument &settingsToParse, const std::function<void(VALIDATE_ERROR, const QString&)>& errFunc);

bool checkForUpdate(QJsonDocument *result, UpdateCheckerErrCodes &errCode, QString& errDescription);
bool hasHigherVersion(int ver1, int ver2, int ver3, int ver4);

Expand Down
99 changes: 49 additions & 50 deletions LunadllNewLauncher/SMBXLauncher/mainlauncherwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QWebFrame>
#include <QMessageBox>


MainLauncherWindow::MainLauncherWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainLauncherWindow)
Expand Down Expand Up @@ -36,7 +37,9 @@ void MainLauncherWindow::loadDefaultWebpage()

void MainLauncherWindow::loadConfig(const QString &configName)
{

auto errFunc = [this](VALIDATE_ERROR errType, const QString& errChild){
jsonErrHandler(errType, errChild);
};
// FIXME: This is a fast hack written for Horikawa, however I would like to remove the old INI at the end anyway.
// In addition I would like to put all launcher data in the "launcher" folder.

Expand All @@ -58,7 +61,17 @@ void MainLauncherWindow::loadConfig(const QString &configName)

// The errors are surpressed.
if(configurationJSON.open(QIODevice::ReadOnly)){
m_launcherSettings.reset(new LauncherConfiguration(QJsonDocument::fromJson(configurationJSON.readAll())));
QByteArray rawData = configurationJSON.readAll();

QJsonParseError jsonErrCode;
QJsonDocument jsonSettingsFile = QJsonDocument::fromJson(rawData, &jsonErrCode);
if(jsonErrCode.error != QJsonParseError::NoError){
QMessageBox::warning(this, "Error", QString("Failed to parse settings.json:\n") + jsonErrCode.errorString());
m_launcherSettings.reset(new LauncherConfiguration(LauncherConfiguration::generateDefault()));
}else{
m_launcherSettings.reset(new LauncherConfiguration());
m_launcherSettings->setConfigurationAndValidate(jsonSettingsFile, errFunc);
}
}else{
QMessageBox::warning(this, "Error", "Failed to load config, using default!");
m_launcherSettings.reset(new LauncherConfiguration(LauncherConfiguration::generateDefault()));
Expand Down Expand Up @@ -122,57 +135,35 @@ void MainLauncherWindow::checkForUpdates()
LauncherConfiguration::UpdateCheckerErrCodes err;
QString errDesc;
if(m_launcherSettings->checkForUpdate(&output, err, errDesc)){
try{
if(!output.isObject())
throw "Invalid Update Server JSON: Root is not object!";

QJsonObject outputObj = output.object();
if(!outputObj.contains("current-version"))
throw "Invalid Update Server JSON: No \"current-version\" JSON object!";

QJsonValue currentVersionVal = outputObj.value("current-version");
if(!currentVersionVal.isObject())
throw "Invalid Update Server JSON: Invalid \"current-version\" Node. Must be object!";

QJsonObject currentVersionObj = currentVersionVal.toObject();
if(!currentVersionObj.contains("version-1"))
throw "Invalid Update Server JSON: No version-1 value!";
if(!currentVersionObj.contains("version-2"))
throw "Invalid Update Server JSON: No version-2 value!";
if(!currentVersionObj.contains("version-3"))
throw "Invalid Update Server JSON: No version-3 value!";
if(!currentVersionObj.contains("version-4"))
throw "Invalid Update Server JSON: No version-4 value!";

QJsonValue version1Val = currentVersionObj.value("version-1");
QJsonValue version2Val = currentVersionObj.value("version-2");
QJsonValue version3Val = currentVersionObj.value("version-3");
QJsonValue version4Val = currentVersionObj.value("version-4");
if(!version1Val.isDouble())
throw "Invalid Update Server JSON: Invalid \"version-1\" Node. Must be double/number!";
if(!version2Val.isDouble())
throw "Invalid Update Server JSON: Invalid \"version-2\" Node. Must be double/number!";
if(!version3Val.isDouble())
throw "Invalid Update Server JSON: Invalid \"version-3\" Node. Must be double/number!";
if(!version4Val.isDouble())
throw "Invalid Update Server JSON: Invalid \"version-4\" Node. Must be double/number!";

if(!outputObj.contains("update-message"))
throw "Invalid Update Server JSON: No \"update-message\" JSON value!";

QJsonValue updateMessageVal = outputObj.value("update-message");
if(!updateMessageVal.isString())
throw "Invalid Update Server JSON: Invalid \"update-message\" Value. Must be string!";


if(m_launcherSettings->hasHigherVersion(version1Val.toInt(), version2Val.toInt(), version3Val.toInt(), version4Val.toInt())){
QMessageBox::information(this, "New Update!", updateMessageVal.toString());
}
}catch(const char* err){
QMessageBox::warning(this, "Error", err);
auto errFunc = [this](VALIDATE_ERROR errType, const QString& errChild){
jsonErrHandler(errType, errChild);
};

if(!output.isObject()){
errFunc(VALIDATE_ERROR::VALIDATE_NO_CHILD, "<root>");
return;
}

QJsonObject outputObj = output.object();
if(!qJsonValidate<QJsonObject>(outputObj, "current-version", errFunc)) return;
if(!qJsonValidate<QString>(outputObj, "update-message", errFunc)) return;

QJsonObject currentVersionObj = outputObj.value("current-version").toObject();
if(!qJsonValidate<int>(currentVersionObj, "version-1", errFunc)) return;
if(!qJsonValidate<int>(currentVersionObj, "version-2", errFunc)) return;
if(!qJsonValidate<int>(currentVersionObj, "version-3", errFunc)) return;
if(!qJsonValidate<int>(currentVersionObj, "version-4", errFunc)) return;


if(m_launcherSettings->hasHigherVersion(currentVersionObj.value("version-1").toInt(),
currentVersionObj.value("version-2").toInt(),
currentVersionObj.value("version-3").toInt(),
currentVersionObj.value("version-4").toInt())){
QMessageBox::information(this, "New Update!", outputObj.value("update-message").toString());
}



}else{
switch (err) {
case LauncherConfiguration::UERR_CONNECTION_FAILED:
Expand All @@ -190,6 +181,14 @@ void MainLauncherWindow::checkForUpdates()
}
}

void MainLauncherWindow::jsonErrHandler(VALIDATE_ERROR errType, const QString &errChild)
{
if(errType == VALIDATE_ERROR::VALIDATE_NO_CHILD)
QMessageBox::warning(this, "Error", QString("Invalid Update Server JSON: No \"") + errChild + "\" JSON value.");
if(errType == VALIDATE_ERROR::VALIDATE_WRONG_TYPE)
QMessageBox::warning(this, "Error", QString("Invalid Update Server JSON: Invalid \"") + errChild + "\" JSON value. (Wrong Type?)");
}

void MainLauncherWindow::writeLunaConfig()
{
AutostartConfig& config = *m_smbxConfig->Autostart();
Expand Down
3 changes: 3 additions & 0 deletions LunadllNewLauncher/SMBXLauncher/mainlauncherwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public slots:
//General stuff
void checkForUpdates();

//Error handlers
void jsonErrHandler(VALIDATE_ERROR errType, const QString& errChild);

private:
void writeLunaConfig();
void internalRunSMBX(const QString& smbxExeFile, const QList<QString>& args);
Expand Down
73 changes: 73 additions & 0 deletions LunadllNewLauncher/SMBXLauncher/qjsonutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef QJSONUTIL_H
#define QJSONUTIL_H

#include <QJsonValue>
#include <QJsonObject>
#include <functional>


enum class VALIDATE_ERROR {
VALIDATE_NO_CHILD,
VALIDATE_WRONG_TYPE
};

template<typename T>
inline bool qJsonValidate(const QJsonObject& val, const QString& child, const std::function<void(VALIDATE_ERROR, const QString&)>& errFunc)
{
throw "err";
return true;
}

template<>
inline bool qJsonValidate<int>(const QJsonObject& val, const QString& child, const std::function<void(VALIDATE_ERROR, const QString&)>& errFunc)
{
if(!val.contains(child)){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_NO_CHILD, child);
return false;
}
QJsonValue containedValue = val.value(child);
if(!containedValue.isDouble()){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_WRONG_TYPE, child);
return false;
}
return true;
}

template<>
inline bool qJsonValidate<QJsonObject>(const QJsonObject& val, const QString& child, const std::function<void(VALIDATE_ERROR, const QString&)>& errFunc)
{
if(!val.contains(child)){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_NO_CHILD, child);
return false;
}
QJsonValue containedValue = val.value(child);
if(!containedValue.isObject()){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_WRONG_TYPE, child);
return false;
}
return true;
}

template<>
inline bool qJsonValidate<QString>(const QJsonObject& val, const QString& child, const std::function<void(VALIDATE_ERROR, const QString&)>& errFunc)
{
if(!val.contains(child)){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_NO_CHILD, child);
return false;
}
QJsonValue containedValue = val.value(child);
if(!containedValue.isString()){
if(errFunc)
errFunc(VALIDATE_ERROR::VALIDATE_WRONG_TYPE, child);
return false;
}
return true;
}


#endif // QJSONUTIL_H

0 comments on commit 9214dc0

Please sign in to comment.