diff --git a/code/ryzom/tools/client/ryzom_installer/CMakeLists.txt b/code/ryzom/tools/client/ryzom_installer/CMakeLists.txt
index b76b0e20d..a8783ed66 100644
--- a/code/ryzom/tools/client/ryzom_installer/CMakeLists.txt
+++ b/code/ryzom/tools/client/ryzom_installer/CMakeLists.txt
@@ -45,7 +45,7 @@ SOURCE_GROUP("Translation Files" FILES ${CLIENT_INSTALL_TRANS} ${CLIENT_INSTALL_
if(APPLE)
SET(MACOSX_BUNDLE_INFO_STRING "Ryzom Installer")
SET(MACOSX_BUNDLE_ICON_FILE "ryzom.icns")
- SET(MACOSX_BUNDLE_GUI_IDENTIFIER "")
+ SET(MACOSX_BUNDLE_GUI_IDENTIFIER "com.winchgate.RyzomInstaller")
SET(MACOSX_BUNDLE_LONG_VERSION_STRING ${RYZOM_VERSION})
SET(MACOSX_BUNDLE_BUNDLE_NAME "Ryzom Installer")
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING ${RYZOM_VERSION})
diff --git a/code/ryzom/tools/client/ryzom_installer/res/Info.plist b/code/ryzom/tools/client/ryzom_installer/res/Info.plist
index 0f34722db..c8e811f43 100644
--- a/code/ryzom/tools/client/ryzom_installer/res/Info.plist
+++ b/code/ryzom/tools/client/ryzom_installer/res/Info.plist
@@ -10,18 +10,8 @@
$NAME
CFBundleIconFile
ryzom.icns
- CFBundleIdentifier
- $IDENTIFIER
CFBundleInfoDictionaryVersion
6.0
- CFBundleLocalizations
-
- en
- fr
- de
- ru
- es
-
CFBundleLongVersionString
$VERSION
CFBundleName
@@ -38,16 +28,8 @@
CFBundleVersion
1.0
- CSResourcesFileMapped
-
LSApplicationCategoryType
public.app-category.role-playing-games
- LSFileQuarantineEnabled
-
- LSMinimumSystemVersion
- 10.6
- LSRequiresCarbon
-
NSHumanReadableCopyright
$COPYRIGHT
diff --git a/code/ryzom/tools/client/ryzom_installer/src/filesextractor.cpp b/code/ryzom/tools/client/ryzom_installer/src/filesextractor.cpp
index 28b04f82b..535b43b76 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/filesextractor.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/filesextractor.cpp
@@ -502,7 +502,7 @@ bool CFilesExtractor::extract7z()
break;
case SZ_ERROR_INPUT_EOF:
- error = QApplication::tr("Errors in 7z file");
+ error = QApplication::tr("File %1 is corrupted, unable to uncompress it").arg(m_sourceFile);
break;
case SZ_ERROR_FAIL:
diff --git a/code/ryzom/tools/client/ryzom_installer/src/main.cpp b/code/ryzom/tools/client/ryzom_installer/src/main.cpp
index 9e4bdf8a0..a4ec462d9 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/main.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/main.cpp
@@ -216,6 +216,7 @@ int main(int argc, char *argv[])
COperationDialog dialog;
+ dialog.setCurrentServerId(config.getProfile().server);
dialog.setOperation(OperationUninstall);
dialog.setUninstallComponents(components);
@@ -244,6 +245,7 @@ int main(int argc, char *argv[])
if (step != Done)
{
COperationDialog dialog;
+ dialog.setCurrentServerId(config.getProfile().server);
dialog.setOperation(config.getSrcServerDirectory().isEmpty() ? OperationInstall:OperationMigrate);
if (!dialog.exec()) return 1;
diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp
index 4213bec73..9fc47dde3 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp
@@ -126,12 +126,6 @@ void COperationDialog::processInstallNextStep()
{
CConfigFile *config = CConfigFile::getInstance();
- // default server
- const CServer &server = config->getServer();
-
- // default profile
- const CProfile &configuration = config->getProfile();
-
// long operations are done in a thread
OperationStep step = config->getInstallNextStep();
@@ -352,8 +346,10 @@ void COperationDialog::processUpdateProfilesNextStep()
if (server.clientDownloadUrl == defaultServer.clientDownloadUrl)
{
if (QFile::exists(""))
+ {
downloadData();
- return;
+ return;
+ }
}
}
else
@@ -558,12 +554,7 @@ void COperationDialog::extractDownloadedData()
extractor.setSourceFile(config->getInstallationDirectory() + "/" + server.dataDownloadFilename);
extractor.setDestinationDirectory(dest);
- if (extractor.exec())
- {
- }
- else
- {
- }
+ if (!extractor.exec()) return;
emit done();
}
@@ -593,12 +584,7 @@ void COperationDialog::extractDownloadedClient()
extractor.setSourceFile(config->getInstallationDirectory() + "/" + config->expandVariables(server.clientDownloadFilename));
extractor.setDestinationDirectory(destinationDirectory);
- if (extractor.exec())
- {
- }
- else
- {
- }
+ if (!extractor.exec()) return;
launchUpgradeScript(destinationDirectory, server.clientFilename);
@@ -626,12 +612,7 @@ void COperationDialog::copyDataFiles()
copier.setDestinationDirectory(server.getDirectory());
copier.setIncludeFilter(serverFiles);
- if (copier.exec())
- {
- }
- else
- {
- }
+ if (!copier.exec()) return;
emit done();
}
@@ -661,12 +642,7 @@ void COperationDialog::copyProfileFiles()
copier.setDestinationDirectory(profile.getDirectory());
copier.setIncludeFilter(profileFiles);
- if (copier.exec())
- {
- }
- else
- {
- }
+ if (!copier.exec()) return;
// correct path to client_default.cfg
profile.createClientConfig();
@@ -688,7 +664,8 @@ void COperationDialog::extractBnpClient()
CFilesExtractor extractor(this);
extractor.setSourceFile(config->getSrcServerClientBNPFullPath());
extractor.setDestinationDirectory(destinationDirectory);
- extractor.exec();
+
+ if (!extractor.exec()) return;
launchUpgradeScript(destinationDirectory, server.clientFilename);
diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h
index 037cfb016..50f6d761b 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h
+++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h
@@ -40,6 +40,7 @@ public:
void setOperation(OperationType operation);
void setUninstallComponents(const SComponents &components);
+ void setCurrentServerId(const QString &serverId) { m_currentServerId = serverId; }
public slots:
void onAbortClicked();
diff --git a/code/ryzom/tools/client/ryzom_installer/src/profile.cpp b/code/ryzom/tools/client/ryzom_installer/src/profile.cpp
index 79aa74b25..90adb000c 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/profile.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/profile.cpp
@@ -49,6 +49,29 @@ void CProfile::saveToSettings(QSettings &settings) const
settings.setValue("menu_shortcut", menuShortcut);
}
+bool CProfile::isValid(QString &error) const
+{
+ QRegExp idReg("^[0-9a-z_]+$");
+
+ if (!idReg.exactMatch(id))
+ {
+ error = QApplication::tr("Profile ID %1 is using invalid characters (only lowercase letters, numbers and underscore are allowed)").arg(id);
+ return false;
+ }
+
+ QRegExp nameReg("[/\\\\<>?*:.%|\"]");
+
+ int pos = nameReg.indexIn(name);
+
+ if (pos > -1)
+ {
+ error = QApplication::tr("Profile name %1 is using invalid character %2 at position %3").arg(name).arg(name[pos]).arg(pos);
+ return false;
+ }
+
+ return true;
+}
+
QString CProfile::getDirectory() const
{
return CConfigFile::getInstance()->getProfileDirectory() + "/" + id;
@@ -105,7 +128,7 @@ void CProfile::createShortcuts() const
// create desktop shortcut
if (!createShortcut(shortcut, name, exe, profileArguments, icon, workingDir))
{
- qDebug() << "Unable to create desktop directory";
+ qDebug() << "Unable to create desktop shortcut";
}
}
diff --git a/code/ryzom/tools/client/ryzom_installer/src/profile.h b/code/ryzom/tools/client/ryzom_installer/src/profile.h
index 774d55193..5b7f8158f 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/profile.h
+++ b/code/ryzom/tools/client/ryzom_installer/src/profile.h
@@ -40,6 +40,8 @@ public:
void loadFromSettings(const QSettings &settings);
void saveToSettings(QSettings &settings) const;
+ bool isValid(QString &error) const;
+
// helpers
QString getDirectory() const;
QString getClientFullPath() const;
diff --git a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp
index 5bbeb86b2..4aa0b2f27 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp
@@ -56,6 +56,21 @@ void CProfilesDialog::accept()
{
saveProfile(m_currentProfileIndex);
+ const CProfiles &profiles = m_model->getProfiles();
+
+ // check if profiles are valid
+ foreach(const CProfile &profile, profiles)
+ {
+ QString error;
+
+ if (!profile.isValid(error))
+ {
+ // display an error message
+ QMessageBox::critical(this, tr("Error"), error);
+ return;
+ }
+ }
+
m_model->save();
QDialog::accept();
diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp
index 8fadb4610..9a08b4ac8 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp
+++ b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp
@@ -41,36 +41,6 @@ QString qBytesToHumanReadable(qint64 bytes)
return QString::fromUtf8(NLMISC::bytesToHumanReadableUnits(bytes, units).c_str());
}
-QString nameToId(const QString &name)
-{
- QString res;
-
- // only allows simple characters
- QRegExp allowedCharacters("^[0-9a-zA-Z-]$");
-
- for (int i = 0, len = name.length(); i < len; ++i)
- {
- if (allowedCharacters.indexIn(name.at(i)) > -1)
- {
- // allowed character
- res += name[i];
- }
- else
- {
- // not allowed, replace by a space
- res += " ";
- }
- }
-
- // simplify all spaces
- res = res.simplified();
-
- // replace spaces by minus
- res.replace(" ", "-");
-
- return res;
-}
-
bool isDirectoryEmpty(const QString &directory, bool recursize)
{
bool res = true;
@@ -81,18 +51,21 @@ bool isDirectoryEmpty(const QString &directory, bool recursize)
if (dir.exists())
{
+ // process all files and directories excepted parent and current ones
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
- for (int i = 0; i < list.size(); ++i)
+ for (int i = 0, len = list.size(); i < len; ++i)
{
QFileInfo fileInfo = list.at(i);
if (fileInfo.isDir())
{
+ // don't consider empty directories as files, but process it recursively if required
if (recursize) if (!isDirectoryEmpty(fileInfo.absoluteFilePath(), true)) return false;
}
else
{
+ // we found a file, directory is not empty
return false;
}
}
@@ -127,6 +100,7 @@ qint64 getDirectorySize(const QString &directory, bool recursize)
if (dir.exists())
{
+ // process all files and directories excepted parent and current ones
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
for (int i = 0; i < list.size(); ++i)
@@ -343,11 +317,11 @@ bool createShortcut(const QString &shortcut, const QString &name, const QString
CConfigFile *config = CConfigFile::getInstance();
+ // HTML escape values because they'll be in a XML file
strings.clear();
- strings["NAME"] = name;
- strings["COPYRIGHT"] = config->getProductPublisher();
+ strings["NAME"] = name.toHtmlEscaped();
+ strings["COPYRIGHT"] = config->getProductPublisher().toHtmlEscaped();
strings["VERSION"] = QApplication::applicationVersion();
- strings["IDENTIFIER"] = "com.winchgate.Ryzom-" + nameToId(name);
// write Info.plist
if (!writeResourceWithTemplates(":/templates/Info.plist", plistFile, strings)) return false;
diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.h b/code/ryzom/tools/client/ryzom_installer/src/utils.h
index 296c439fd..e3de8155b 100644
--- a/code/ryzom/tools/client/ryzom_installer/src/utils.h
+++ b/code/ryzom/tools/client/ryzom_installer/src/utils.h
@@ -28,40 +28,61 @@
* \date 2016
*/
+// convert a size in bytes to a QString with larger unit (KiB, MiB, etc...)
QString qBytesToHumanReadable(qint64 bytes);
-QString nameToId(const QString &name);
+// return true is the specified directory is empty (has no file inside) (and all its subdirectories if recursize is true)
bool isDirectoryEmpty(const QString &directory, bool recursize);
+
+// check if specified directory is writable
bool isDirectoryWritable(const QString &directory);
+// return the total size in bytes of specified directtory (and all its subdirectories if recursize is true)
qint64 getDirectorySize(const QString &directory, bool recursize);
-// Convert a UTF-8 string to QString
+// convert a UTF-8 string to QString
QString qFromUtf8(const std::string &str);
-// Convert a QString to UTF-8 string
+// convert a QString to UTF-8 string
std::string qToUtf8(const QString &str);
-// Convert a UTF-16 string to QString
+// convert an UTF-16 string to QString
QString qFromUtf16(const ucstring &str);
-// Convert a QString to UTF-16 string
+// convert a QString to UTF-16 string
ucstring qToUtf16(const QString &str);
+// convert an wchar_t* to QString
QString qFromWide(const wchar_t *str);
+// convert an QString to wchar_t*
wchar_t* qToWide(const QString &str);
+// check if a shortcut already exists (the extension will be added)
bool shortcutExists(const QString &shortcut);
+
+// create a shortcut with the native format of the current platform
bool createShortcut(const QString &shortcut, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir);
+
+// remove a shortcut (the extension will be added)
bool removeShortcut(const QString &shortcut);
+
+// return the real path of shortcut
bool resolveShortcut(const QWidget &window, const QString &shortcut, QString &pathObj);
+
+// append the shortcut of current platform to specified path
QString appendShortcutExtension(const QString &shortcut);
+// launch an executable with --version parameter and parse version string
QString getVersionFromExecutable(const QString &path);
+
+// write a resource in QRC to disk
bool writeResource(const QString &resource, const QString &path);
+
+// write a resource in QRC to disk and replace all variables by specified values
bool writeResourceWithTemplates(const QString &resource, const QString &path, const QMap &strings);
+// a little helper class to unintialize COM after using it
class CCOMHelper
{
bool m_mustUninit;