23 #include "createserverdialog.h"
24 #include "ui_createserverdialog.h"
26 #include "apprunner.h"
27 #include "commandline.h"
28 #include "configuration/doomseekerconfig.h"
29 #include "copytextdlg.h"
30 #include "datapaths.h"
32 #include "gui/commongui.h"
33 #include "gui/configuration/doomseekerconfigurationdialog.h"
34 #include "gui/createserver/hostmodetraits.h"
35 #include "gui/widgets/createserverdialogpage.h"
37 #include "ini/settingsproviderqt.h"
38 #include "plugins/engineplugin.h"
39 #include "serverapi/gamecreateparams.h"
40 #include "serverapi/gamehost.h"
41 #include "serverapi/message.h"
43 #include <QFileDialog>
44 #include <QKeySequence>
46 #include <QMessageBox>
47 #include <QScopedPointer>
51 DClass<CreateServerDialog> :
public Ui::CreateServerDialog
54 QList<CreateServerDialogPage *> currentCustomPages;
60 QAction *hostModeAction;
61 QAction *offlineModeAction;
73 setAttribute(Qt::WA_DeleteOnClose);
75 d->currentEngine =
nullptr;
76 d->hostMode = hostMode;
84 d->generalSetupPanel->setCreateServerDialog(
this);
85 d->rulesPanel->setCreateServerDialog(
this);
87 d->tabWidget->setObjectName(
"createGameTabWidget");
88 d->tabWidget->setStyleSheet(
"#createGameTabWidget::pane { border: 0; }");
94 QTimer::singleShot(1,
this, SLOT(firstLoadConfigTimer()));
97 CreateServerDialog::~CreateServerDialog()
101 void CreateServerDialog::applyModeToUi()
103 d->generalSetupPanel->setupForHostMode(d->hostMode);
104 d->rulesPanel->setupForHostMode(d->hostMode);
107 d->modeMenu->setEnabled(d->hostMode.canChangeMode());
108 d->hostModeAction->setChecked(d->hostMode == GameCreateParams::Host);
109 d->offlineModeAction->setChecked(d->hostMode == GameCreateParams::Offline);
111 switch (d->hostMode.mode)
113 case GameCreateParams::Demo:
114 setWindowTitle(tr(
"Doomseeker - Play Demo"));
115 d->btnStart->setText(tr(
"Play demo"));
117 case GameCreateParams::Host:
118 setWindowTitle(tr(
"Doomseeker - Host Online Game"));
119 d->btnStart->setText(tr(
"Host server"));
121 case GameCreateParams::Offline:
122 setWindowTitle(tr(
"Doomseeker - Play Offline Game"));
123 d->btnStart->setText(tr(
"Play"));
125 case GameCreateParams::Remote:
126 setWindowTitle(tr(
"Doomseeker - Setup Remote Game"));
127 d->btnStart->setText(tr(
"Play online"));
130 setWindowTitle(tr(
"Doomseeker - Create Game"));
131 d->btnStart->setText(tr(
"Create game"));
135 d->btnCommandLine->setVisible(d->hostMode.canShowCommandLine());
138 void CreateServerDialog::changeToHostMode()
140 d->hostMode = GameCreateParams::Host;
144 void CreateServerDialog::changeToOfflineMode()
146 d->hostMode = GameCreateParams::Offline;
150 bool CreateServerDialog::commandLineArguments(QString &executable, QStringList &args,
151 CommandLinePurpose purpose)
153 const QString errorCapt = tr(
"Doomseeker - create game");
154 if (d->currentEngine ==
nullptr)
156 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
161 if (createHostInfo(gameParams, purpose))
166 GameHost *gameRunner = d->currentEngine->gameHost();
173 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
178 executable = cli.
executable.absoluteFilePath();
186 bool CreateServerDialog::createHostInfo(
GameCreateParams ¶ms, CommandLinePurpose purpose)
188 params.setHostMode(d->hostMode);
189 d->generalSetupPanel->fillInParams(params);
190 d->dmflagsPanel->fillInParams(params);
192 if (!fillInParamsFromPluginPages(params))
195 d->customParamsPanel->fillInParams(params);
196 if (d->hostMode.canChangeAnyGameRules())
198 if (d->hostMode.isCreatingServer())
200 d->serverPanel->fillInParams(params);
202 d->rulesPanel->fillInParams(params);
205 return createHostInfoDemoRecord(params, purpose);
208 bool CreateServerDialog::createHostInfoDemoRecord(
GameCreateParams ¶ms, CommandLinePurpose purpose)
210 if (gConfig.doomseeker.bRecordDemo && d->hostMode.canRecordDemo())
216 if (!d->demoStore.ensureStorageExists(
this))
221 const QString demoPath = d->demoStore.mkDemoFullPath(demoMode, *d->currentEngine,
false);
222 if (demoPath.isEmpty())
227 params.setDemoPath(demoPath);
228 params.setDemoRecord(demoMode);
233 GameMode CreateServerDialog::currentGameMode()
const
235 return d->generalSetupPanel->currentGameMode();
238 void CreateServerDialog::firstLoadConfigTimer()
240 initEngineSpecific(d->generalSetupPanel->currentPlugin());
241 QString tmpGameCfgPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
243 QFileInfo fi(tmpGameCfgPath);
245 loadConfig(tmpGameCfgPath,
true);
248 void CreateServerDialog::initDMFlagsTabs()
250 bool flagsAdded = d->hostMode.canChangeAnyGameRules() &&
251 d->dmflagsPanel->initDMFlagsTabs(d->currentEngine);
252 int tabIndex = d->tabWidget->indexOf(d->tabFlags);
253 if (flagsAdded && tabIndex < 0)
254 d->tabWidget->insertTab(d->tabWidget->indexOf(d->tabCustomParameters), d->tabFlags, tr(
"Flags"));
255 else if (!flagsAdded && tabIndex >= 0)
256 d->tabWidget->removeTab(tabIndex);
259 void CreateServerDialog::initEngineSpecific(
EnginePlugin *engine)
261 if (engine == d->currentEngine || engine ==
nullptr)
264 d->currentEngine = engine;
266 d->generalSetupPanel->setupForEngine(engine);
268 initEngineSpecificPages(engine);
273 void CreateServerDialog::initEngineSpecificPages(
EnginePlugin *engine)
278 d->currentCustomPages.clear();
280 if (!d->hostMode.canChangeAnyGameRules())
287 int idxInsertAt = d->tabWidget->indexOf(d->tabCustomParameters);
288 d->tabWidget->insertTab(idxInsertAt, page, page->name());
292 void CreateServerDialog::initGamemodeSpecific(
const GameMode &gameMode)
294 d->rulesPanel->setupForEngine(d->currentEngine, gameMode);
297 void CreateServerDialog::initServerTab()
299 if (d->currentEngine !=
nullptr)
300 d->serverPanel->setupForEngine(d->currentEngine);
301 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabServer),
302 d->serverPanel->isAnythingAvailable()
303 && d->hostMode.isSettingUpOnlineGame()
304 && d->hostMode.canChangeAnyGameRules());
307 void CreateServerDialog::initRules()
309 d->rulesPanel->setupForEngine(d->currentEngine, currentGameMode());
310 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabRules),
311 d->rulesPanel->isAnythingAvailable()
312 && d->hostMode.canChangeAnyGameRules());
315 bool CreateServerDialog::loadConfig(
const QString &filename,
bool loadingPrevious)
317 QSettings settingsFile(filename, QSettings::IniFormat);
319 Ini ini(&settingsProvider);
321 d->generalSetupPanel->loadConfig(ini, loadingPrevious);
322 d->rulesPanel->loadConfig(ini);
323 d->serverPanel->loadConfig(ini);
324 d->dmflagsPanel->loadConfig(ini);
329 d->customParamsPanel->loadConfig(ini);
331 if (d->hostMode.canChangeMode())
340 void CreateServerDialog::makeDemoPlaybackSetupDialog(
EnginePlugin *plugin,
341 const GameDemo &demo,
const QString &iwad,
const QList<PickedGameFile> &wads)
343 initEngineSpecific(plugin);
344 switchToMode(GameCreateParams::Demo);
345 d->generalSetupPanel->setDemoPath(demo.
demopath);
346 d->generalSetupPanel->setIwadByPath(iwad);
347 d->generalSetupPanel->setPwads(wads);
350 void CreateServerDialog::makeRemoteGameSetupDialog(
EnginePlugin *plugin)
352 initEngineSpecific(plugin);
353 switchToMode(GameCreateParams::Remote);
358 return d->rulesPanel->mapListPanel();
361 QString CreateServerDialog::mapName()
const
363 return d->generalSetupPanel->mapName();
366 QStringList CreateServerDialog::wadPaths()
const
368 return d->generalSetupPanel->getAllWadPaths();
371 bool CreateServerDialog::fillInParamsFromPluginPages(
GameCreateParams ¶ms)
380 d->tabWidget->setCurrentIndex(d->tabWidget->indexOf(page));
387 void CreateServerDialog::runGame()
389 const QString errorCapt = tr(
"Doomseeker - create game");
390 if (d->currentEngine ==
nullptr)
392 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
397 if (createHostInfo(gameParams, CommandLinePurpose::Run))
399 QScopedPointer<GameHost> gameRunner(d->currentEngine->gameHost());
402 if (message.isError())
404 QMessageBox::critical(
nullptr, errorCapt, message.contents());
408 QString tmpGameConfigPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
409 saveConfig(tmpGameConfigPath);
414 bool CreateServerDialog::saveConfig(
const QString &filename)
416 QSettings settingsFile(filename, QSettings::IniFormat);
418 Ini ini(&settingsProvider);
420 d->generalSetupPanel->saveConfig(ini);
421 d->rulesPanel->saveConfig(ini);
422 d->serverPanel->saveConfig(ini);
423 d->dmflagsPanel->saveConfig(ini);
428 d->customParamsPanel->saveConfig(ini);
430 ini.section(
"General")[
"hostMode"] = d->hostMode.cfgName();
432 if (settingsFile.isWritable())
440 void CreateServerDialog::setIwadByName(
const QString &iwad)
442 d->generalSetupPanel->setIwadByName(iwad);
445 void CreateServerDialog::setupMenu()
447 QMenuBar *mainMenu =
new QMenuBar(
this);
449 d->modeMenu = mainMenu->addMenu(tr(
"&Mode"));
450 d->hostModeAction = d->modeMenu->addAction(tr(
"&Host server"),
451 this, SLOT(changeToHostMode()));
452 d->hostModeAction->setCheckable(
true);
453 d->offlineModeAction = d->modeMenu->addAction(tr(
"&Play offline"),
454 this, SLOT(changeToOfflineMode()));
455 d->offlineModeAction->setCheckable(
true);
457 auto *settingsMenu = mainMenu->addMenu(tr(
"&Settings"));
459 auto *loadConfigAction = settingsMenu->addAction(tr(
"&Load game configuration"),
460 this, SLOT(showLoadConfig()));
461 loadConfigAction->setIcon(style()->standardIcon(QStyle::SP_DirIcon));
462 loadConfigAction->setShortcut(QKeySequence(
"Ctrl+O"));
464 auto *saveConfigAction = settingsMenu->addAction(tr(
"&Save game configuration"),
465 this, SLOT(showSaveConfig()));
466 saveConfigAction->setIcon(QIcon(
":/icons/diskette.png"));
467 saveConfigAction->setShortcut(QKeySequence(
"Ctrl+S"));
468 settingsMenu->addSeparator();
470 auto *programSettings = settingsMenu->addAction(tr(
"&Program settings"),
471 this, SLOT(showConfiguration()));
472 programSettings->setIcon(QIcon(
":/icons/preferences-system-4.png"));
474 d->dialogLayout->setMenuBar(mainMenu);
477 void CreateServerDialog::showConfiguration()
479 DoomseekerConfigurationDialog::openConfiguration(
this, d->currentEngine);
480 d->generalSetupPanel->reloadAppConfig();
483 void CreateServerDialog::showCommandLine()
487 if (commandLineArguments(executable, args, CommandLinePurpose::Show))
493 QString title = !d->hostMode.isCreatingServer() ?
494 tr(
"Run game command line:") :
495 tr(
"Host server command line:");
496 CopyTextDlg ctd(executable +
" " + args.join(
" "), title,
this);
501 void CreateServerDialog::showLoadConfig()
503 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
504 QString strFile = QFileDialog::getOpenFileName(
this, tr(
"Doomseeker - load game setup config"), dialogDir, tr(
"Config files (*.ini)"));
506 if (!strFile.isEmpty())
508 QFileInfo fi(strFile);
509 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
511 loadConfig(strFile,
false);
515 void CreateServerDialog::showSaveConfig()
517 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
518 QString strFile = QFileDialog::getSaveFileName(
this, tr(
"Doomseeker - save game setup config"), dialogDir, tr(
"Config files (*.ini)"));
519 if (!strFile.isEmpty())
521 QFileInfo fi(strFile);
522 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
524 if (fi.suffix().isEmpty())
527 if (!saveConfig(strFile))
528 QMessageBox::critical(
nullptr, tr(
"Doomseeker - save game setup config"), tr(
"Unable to save game setup configuration!"));
532 void CreateServerDialog::startGame()
537 if (d->hostMode != GameCreateParams::Remote)
543 void CreateServerDialog::switchToMode(GameCreateParams::HostMode mode)