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/widgets/createserverdialogpage.h"
36 #include "ini/settingsproviderqt.h"
37 #include "plugins/engineplugin.h"
38 #include "serverapi/gamecreateparams.h"
39 #include "serverapi/gamehost.h"
40 #include "serverapi/message.h"
43 #include <QFileDialog>
44 #include <QKeySequence>
46 #include <QMessageBox>
50 DClass<CreateServerDialog> :
public Ui::CreateServerDialog
53 QList<CreateServerDialogPage *> currentCustomPages;
55 GameCreateParams::HostMode hostMode;
58 QAction *hostModeAction;
59 QAction *offlineModeAction;
61 bool canLoadHostModeFromConfig()
const
63 return hostMode == GameCreateParams::Host
64 || hostMode == GameCreateParams::Offline;
67 QString hostModeCfgName()
const
72 case GameCreateParams::Host:
return "host";
73 case GameCreateParams::Offline:
return "offline";
77 GameCreateParams::HostMode hostModeFromCfgName(
const QString &name)
79 if (name ==
"offline")
80 return GameCreateParams::Offline;
82 return GameCreateParams::Host;
95 setAttribute(Qt::WA_DeleteOnClose);
96 assert(hostMode == GameCreateParams::Offline
97 || hostMode == GameCreateParams::Host
98 || hostMode == GameCreateParams::Remote);
101 setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
103 d->currentEngine =
nullptr;
104 d->hostMode = hostMode;
111 d->generalSetupPanel->setCreateServerDialog(
this);
112 d->rulesPanel->setCreateServerDialog(
this);
114 d->tabWidget->setObjectName(
"createGameTabWidget");
115 d->tabWidget->setStyleSheet(
"#createGameTabWidget::pane { border: 0; }");
121 QTimer::singleShot(1,
this, SLOT(firstLoadConfigTimer()));
124 CreateServerDialog::~CreateServerDialog()
128 void CreateServerDialog::applyModeToUi()
130 d->generalSetupPanel->setupForHostMode(d->hostMode);
131 d->rulesPanel->setupForHostMode(d->hostMode);
134 d->modeMenu->setEnabled(d->hostMode != GameCreateParams::Remote);
135 d->hostModeAction->setChecked(d->hostMode == GameCreateParams::Host);
136 d->offlineModeAction->setChecked(d->hostMode == GameCreateParams::Offline);
138 if (d->hostMode == GameCreateParams::Host)
139 d->btnStart->setText(tr(
"Host server"));
141 d->btnStart->setText(tr(
"Play"));
146 case GameCreateParams::Remote:
147 windowTitle = tr(
"Doomseeker - Setup Remote Game");
149 case GameCreateParams::Host:
150 windowTitle = tr(
"Doomseeker - Host Online Game");
152 case GameCreateParams::Offline:
153 windowTitle = tr(
"Doomseeker - Play Offline Game");
156 windowTitle = tr(
"Doomseeker - [Unhandled Host Mode]");
159 setWindowTitle(windowTitle);
161 d->btnCommandLine->setVisible(d->hostMode != GameCreateParams::Remote);
164 void CreateServerDialog::changeToHostMode()
166 d->hostMode = GameCreateParams::Host;
170 void CreateServerDialog::changeToOfflineMode()
172 d->hostMode = GameCreateParams::Offline;
176 bool CreateServerDialog::commandLineArguments(QString &executable, QStringList &args,
bool offline)
178 const QString errorCapt = tr(
"Doomseeker - create game");
179 if (d->currentEngine ==
nullptr)
181 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
186 if (createHostInfo(gameParams, offline))
191 GameHost *gameRunner = d->currentEngine->gameHost();
198 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
203 executable = cli.
executable.absoluteFilePath();
211 bool CreateServerDialog::createHostInfo(
GameCreateParams ¶ms,
bool offline)
213 params.setHostMode(d->hostMode);
214 d->generalSetupPanel->fillInParams(params);
215 d->dmflagsPanel->fillInParams(params);
217 if (!fillInParamsFromPluginPages(params))
220 d->customParamsPanel->fillInParams(params);
221 d->serverPanel->fillInParams(params);
222 d->rulesPanel->fillInParams(params);
224 createHostInfoDemoRecord(params, offline);
228 void CreateServerDialog::createHostInfoDemoRecord(
GameCreateParams ¶ms,
bool offline)
230 if (gConfig.doomseeker.bRecordDemo && offline)
232 params.setDemoPath(GameDemo::mkDemoFullPath(GameDemo::Managed, *d->currentEngine));
233 params.setDemoRecord(GameDemo::Managed);
237 GameMode CreateServerDialog::currentGameMode()
const
239 return d->generalSetupPanel->currentGameMode();
242 void CreateServerDialog::firstLoadConfigTimer()
244 initEngineSpecific(d->generalSetupPanel->currentPlugin());
245 QString tmpGameCfgPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
247 QFileInfo fi(tmpGameCfgPath);
249 loadConfig(tmpGameCfgPath,
true);
252 void CreateServerDialog::initDMFlagsTabs()
254 bool flagsAdded = d->dmflagsPanel->initDMFlagsTabs(d->currentEngine);
255 int tabIndex = d->tabWidget->indexOf(d->tabFlags);
256 if (flagsAdded && tabIndex < 0)
257 d->tabWidget->insertTab(d->tabWidget->indexOf(d->tabCustomParameters), d->tabFlags, tr(
"Flags"));
258 else if (!flagsAdded && tabIndex >= 0)
259 d->tabWidget->removeTab(tabIndex);
262 void CreateServerDialog::initEngineSpecific(
EnginePlugin *engine)
264 if (engine == d->currentEngine || engine ==
nullptr)
267 d->currentEngine = engine;
269 d->generalSetupPanel->setupForEngine(engine);
271 initEngineSpecificPages(engine);
276 void CreateServerDialog::initEngineSpecificPages(
EnginePlugin *engine)
281 d->currentCustomPages.clear();
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() && d->hostMode != GameCreateParams::Offline);
305 void CreateServerDialog::initRules()
307 d->rulesPanel->setupForEngine(d->currentEngine, currentGameMode());
308 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabRules), d->rulesPanel->isAnythingAvailable());
311 bool CreateServerDialog::loadConfig(
const QString &filename,
bool loadingPrevious)
313 QSettings settingsFile(filename, QSettings::IniFormat);
315 Ini ini(&settingsProvider);
317 d->generalSetupPanel->loadConfig(ini, loadingPrevious);
318 d->rulesPanel->loadConfig(ini);
319 d->serverPanel->loadConfig(ini);
320 d->dmflagsPanel->loadConfig(ini);
325 d->customParamsPanel->loadConfig(ini);
327 if (d->canLoadHostModeFromConfig())
329 d->hostMode = d->hostModeFromCfgName(ini.section(
"General")[
"hostMode"]);
336 void CreateServerDialog::makeRemoteGameSetupDialog(
EnginePlugin *plugin)
338 initEngineSpecific(plugin);
339 d->hostMode = GameCreateParams::Remote;
345 return d->rulesPanel->mapListPanel();
348 QString CreateServerDialog::mapName()
const
350 return d->generalSetupPanel->mapName();
353 QStringList CreateServerDialog::wadPaths()
const
355 return d->generalSetupPanel->getAllWadPaths();
358 bool CreateServerDialog::fillInParamsFromPluginPages(
GameCreateParams ¶ms)
367 d->tabWidget->setCurrentIndex(d->tabWidget->indexOf(page));
374 void CreateServerDialog::runGame(
bool offline)
376 const QString errorCapt = tr(
"Doomseeker - create game");
377 if (d->currentEngine ==
nullptr)
379 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
384 if (createHostInfo(gameParams, offline))
388 GameHost *gameRunner = d->currentEngine->gameHost();
394 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
397 QString tmpGameConfigPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
398 saveConfig(tmpGameConfigPath);
403 bool CreateServerDialog::saveConfig(
const QString &filename)
405 QSettings settingsFile(filename, QSettings::IniFormat);
407 Ini ini(&settingsProvider);
409 d->generalSetupPanel->saveConfig(ini);
410 d->rulesPanel->saveConfig(ini);
411 d->serverPanel->saveConfig(ini);
412 d->dmflagsPanel->saveConfig(ini);
417 d->customParamsPanel->saveConfig(ini);
419 ini.section(
"General")[
"hostMode"] = d->hostModeCfgName();
421 if (settingsFile.isWritable())
429 void CreateServerDialog::setIwadByName(
const QString &iwad)
431 d->generalSetupPanel->setIwadByName(iwad);
434 void CreateServerDialog::setupMenu()
436 QMenuBar *mainMenu =
new QMenuBar(
this);
438 d->modeMenu = mainMenu->addMenu(tr(
"&Mode"));
439 d->hostModeAction = d->modeMenu->addAction(tr(
"&Host server"),
440 this, SLOT(changeToHostMode()));
441 d->hostModeAction->setCheckable(
true);
442 d->offlineModeAction = d->modeMenu->addAction(tr(
"&Play offline"),
443 this, SLOT(changeToOfflineMode()));
444 d->offlineModeAction->setCheckable(
true);
446 auto *settingsMenu = mainMenu->addMenu(tr(
"&Settings"));
448 auto *loadConfigAction = settingsMenu->addAction(tr(
"&Load game configuration"),
449 this, SLOT(showLoadConfig()));
450 loadConfigAction->setIcon(style()->standardIcon(QStyle::SP_DirIcon));
451 loadConfigAction->setShortcut(QKeySequence(
"Ctrl+O"));
453 auto *saveConfigAction = settingsMenu->addAction(tr(
"&Save game configuration"),
454 this, SLOT(showSaveConfig()));
455 saveConfigAction->setIcon(QIcon(
":/icons/diskette.png"));
456 saveConfigAction->setShortcut(QKeySequence(
"Ctrl+S"));
457 settingsMenu->addSeparator();
459 auto *programSettings = settingsMenu->addAction(tr(
"&Program settings"),
460 this, SLOT(showConfiguration()));
461 programSettings->setIcon(QIcon(
":/icons/preferences-system-4.png"));
463 d->dialogLayout->setMenuBar(mainMenu);
466 void CreateServerDialog::showConfiguration()
468 DoomseekerConfigurationDialog::openConfiguration(
this, d->currentEngine);
469 d->generalSetupPanel->reloadAppConfig();
472 void CreateServerDialog::showCommandLine(
bool offline)
476 if (commandLineArguments(executable, args, offline))
482 QString title = offline ?
483 tr(
"Run game command line:") :
484 tr(
"Host server command line:");
485 CopyTextDlg ctd(executable +
" " + args.join(
" "), title,
this);
490 void CreateServerDialog::showLoadConfig()
492 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
493 QString strFile = QFileDialog::getOpenFileName(
this, tr(
"Doomseeker - load game setup config"), dialogDir, tr(
"Config files (*.ini)"));
495 if (!strFile.isEmpty())
497 QFileInfo fi(strFile);
498 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
500 loadConfig(strFile,
false);
504 void CreateServerDialog::showSaveConfig()
506 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
507 QString strFile = QFileDialog::getSaveFileName(
this, tr(
"Doomseeker - save game setup config"), dialogDir, tr(
"Config files (*.ini)"));
508 if (!strFile.isEmpty())
510 QFileInfo fi(strFile);
511 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
513 if (fi.suffix().isEmpty())
516 if (!saveConfig(strFile))
517 QMessageBox::critical(
nullptr, tr(
"Doomseeker - save game setup config"), tr(
"Unable to save game setup configuration!"));
521 void CreateServerDialog::showStartGameCommandLine()
523 showCommandLine(d->hostMode == GameCreateParams::Offline);
526 void CreateServerDialog::startGame()
528 if (d->hostMode != GameCreateParams::Remote)
529 runGame(d->hostMode == GameCreateParams::Offline);