1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "mainwindow.h"
19 #include "configfile.h"
20 #include "migratedialog.h"
21 #include "installdialog.h"
22 #include "uninstalldialog.h"
23 #include "operationdialog.h"
30 #ifdef QT_STATICPLUGIN
34 #if defined(Q_OS_WIN32)
35 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin
)
36 #elif defined(Q_OS_MAC)
37 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin
)
38 #elif defined(Q_OS_UNIX)
39 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin
)
42 Q_IMPORT_PLUGIN(QICOPlugin
)
50 // copy all specified files from current directory to destination directory
51 bool copyInstallerFiles(const QStringList
&files
, const QString
&destination
)
53 QString path
= QApplication::applicationDirPath();
55 foreach(const QString
&file
, files
)
57 // convert to absolute path
58 QString srcPath
= path
+ "/" + file
;
59 QString dstPath
= destination
+ "/" + file
;
61 if (QFile::exists(srcPath
))
63 if (QFile::exists(dstPath
))
65 if (!QFile::remove(dstPath
))
67 nlwarning("Unable to delete %s", Q2C(dstPath
));
71 if (!QFile::copy(srcPath
, dstPath
))
73 nlwarning("Unable to copy %s to %s", Q2C(srcPath
), Q2C(dstPath
));
83 int main(int argc
, char *argv
[])
85 #if defined(_MSC_VER) && defined(_DEBUG)
86 _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF
| _CRTDBG_LEAK_CHECK_DF
);
93 NLMISC::CApplicationContext appContext
;
95 QApplication
app(argc
, argv
);
97 QApplication::setApplicationName("Ryzom");
98 QApplication::setApplicationVersion(RYZOM_VERSION
);
99 QApplication::setWindowIcon(QIcon(":/icons/ryzom.ico"));
101 // remove first argument because it's not really an argument
102 QStringList args
= QApplication::arguments();
105 QLocale locale
= QLocale::system();
107 // load application translations
108 QTranslator localTranslator
;
109 if (localTranslator
.load(locale
, "ryzom_installer", "_", ":/translations"))
111 QApplication::installTranslator(&localTranslator
);
114 // load Qt default translations
115 QTranslator qtTranslator
;
116 if (qtTranslator
.load(locale
, "qtbase", "_", ":/translations"))
118 QApplication::installTranslator(&qtTranslator
);
121 // define commandline arguments
122 QCommandLineParser parser
;
123 parser
.setApplicationDescription(QApplication::tr("Installation and launcher tool for Ryzom"));
124 parser
.addHelpOption();
126 QCommandLineOption
uninstallOption(QStringList() << "u" << "uninstall", QApplication::tr("Uninstall"));
127 parser
.addOption(uninstallOption
);
129 QCommandLineOption
silentOption(QStringList() << "s" << "silent", QApplication::tr("Silent mode"));
130 parser
.addOption(silentOption
);
132 QCommandLineOption
versionOption(QStringList() << "v" << "version", QApplication::tr("Version"));
133 parser
.addOption(versionOption
);
135 QCommandLineOption
installOption(QStringList() << "i" << "install", QApplication::tr("Install itself"));
136 parser
.addOption(installOption
);
138 // process the actual command line arguments given by the user
141 // don't need to load config file for version
142 if (parser
.isSet(versionOption
))
144 printf("Ryzom Installer %s (built on %s)\nCopyright (C) %s\n", RYZOM_VERSION
, BUILD_DATE
, COPYRIGHT
);
149 // instanciate ConfigFile
152 bool res
= config
.load();
155 CLogHelper
logHelper(config
.getInstallationDirectory().isEmpty() ? config
.getNewInstallationDirectory():config
.getInstallationDirectory());
157 nlinfo("Launched %s", Q2C(config
.getInstallerCurrentFilePath()));
159 OperationStep step
= res
? config
.getInstallNextStep():DisplayNoServerError
;
161 if (step
== DisplayNoServerError
)
163 QMessageBox::critical(NULL
, QApplication::tr("Error"), QApplication::tr("Unable to find ryzom_installer.ini"));
167 #if defined(Q_OS_WIN) && !defined(_DEBUG)
168 // under Windows, Ryzom Installer should always be copied in TEMP directory
169 QString tempPath
= QStandardPaths::writableLocation(QStandardPaths::TempLocation
);
171 // check if launched from TEMP directory
172 if (step
== Done
&& !config
.getInstallerCurrentDirPath().startsWith(tempPath
))
174 nlinfo("Not launched from TEMP directory");
176 // try to delete all temporary installers
177 QDir
tempDir(tempPath
);
180 filter
<< "ryzom_installer_*";
182 QStringList dirs
= tempDir
.entryList(filter
, QDir::Dirs
);
184 foreach(const QString
&dir
, dirs
)
186 // delete each directory
187 QDir
dirToRemove(tempDir
);
189 dirToRemove
.removeRecursively();
191 nlinfo("Delete directory %s", Q2C(dir
));
194 tempPath
+= QString("/ryzom_installer_%1").arg(QDateTime::currentMSecsSinceEpoch());
196 nlinfo("Creating directory %s", Q2C(tempPath
));
198 // copy installer and required files to TEMP directory
199 if (QDir().mkdir(tempPath
) && copyInstallerFiles(config
.getInstallerRequiredFiles(), tempPath
))
201 QString tempFile
= tempPath
+ "/" + QFileInfo(config
.getInstallerCurrentFilePath()).fileName();
203 nlinfo("Launching %s", Q2C(tempFile
));
205 // launch copy in TEMP directory with same arguments
206 if (QProcess::startDetached(tempFile
, args
, tempPath
)) return 0;
208 nlwarning("Unable to launch %s", Q2C(tempFile
));
213 // use product name from ryzom_installer.ini
214 if (!config
.getProductName().isEmpty()) QApplication::setApplicationName(config
.getProductName());
216 if (parser
.isSet(uninstallOption
))
218 nlinfo("Uninstalling...");
220 SComponents components
;
222 // add all servers by default
223 for (int i
= 0; i
< config
.getServersCount(); ++i
)
225 components
.servers
<< config
.getServer(i
).id
;
228 // show uninstall wizard dialog if not in silent mode
229 if (!parser
.isSet(silentOption
))
231 CUninstallDialog dialog
;
233 dialog
.setSelectedComponents(components
);
235 // exit if press Cancel button or close dialog
236 if (!dialog
.exec()) return 0;
238 components
= dialog
.getSelectedCompenents();
241 COperationDialog dialog
;
243 dialog
.setCurrentServerId(config
.getProfile().server
);
244 dialog
.setOperation(OperationUninstall
);
245 dialog
.setUninstallComponents(components
);
247 // TODO: set all components to uninstall
249 return dialog
.exec() ? 0 : 1;
252 if (step
== ShowMigrateWizard
)
254 nlinfo("Display migration dialog");
256 CMigrateDialog dialog
;
258 if (!dialog
.exec()) return 1;
260 step
= config
.getInstallNextStep();
262 nlwarning("Migration disabled under Linux and OS X");
265 else if (step
== ShowInstallWizard
)
267 nlinfo("Display installation dialog");
269 CInstallDialog dialog
;
271 if (!dialog
.exec()) return 1;
273 step
= config
.getInstallNextStep();
276 nlinfo("Next step is %s", Q2C(stepToString(step
)));
278 bool restartInstaller
= false;
282 COperationDialog dialog
;
283 dialog
.setCurrentServerId(config
.getProfile().server
);
284 dialog
.setOperation(config
.getSrcServerDirectory().isEmpty() ? OperationInstall
:OperationMigrate
);
286 if (!dialog
.exec()) return 1;
288 step
= config
.getInstallNextStep();
290 nlinfo("Last step is %s", Q2C(stepToString(step
)));
292 if (step
== LaunchInstalledInstaller
)
294 // restart more recent installed Installer version
295 restartInstaller
= true;
297 else if (step
== Done
)
299 #if defined(Q_OS_WIN) && !defined(_DEBUG)
300 // restart Installer, so it could be copied in TEMP and allowed to update itself
301 restartInstaller
= true;
306 if (restartInstaller
)
309 nlinfo("Restart Installer %s", Q2C(config
.getInstallerInstalledFilePath()));
312 // fix executable permissions under UNIX
313 QFile::setPermissions(config
.getInstallerInstalledFilePath(), QFile::permissions(config
.getInstallerInstalledFilePath()) | QFile::ExeGroup
| QFile::ExeUser
| QFile::ExeOther
);
316 if (QProcess::startDetached(config
.getInstallerInstalledFilePath(), args
, config
.getInstallationDirectory())) return 0;
318 nlwarning("Unable to restart Installer %s", Q2C(config
.getInstallerInstalledFilePath()));
322 CMainWindow mainWindow
;
325 return QApplication::exec();