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,
177 bool offline, CommandLinePurpose purpose)
179 const QString errorCapt = tr(
"Doomseeker - create game");
180 if (d->currentEngine ==
nullptr)
182 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
187 if (createHostInfo(gameParams, offline, purpose))
192 GameHost *gameRunner = d->currentEngine->gameHost();
199 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
204 executable = cli.
executable.absoluteFilePath();
212 bool CreateServerDialog::createHostInfo(
GameCreateParams ¶ms,
bool offline, CommandLinePurpose purpose)
214 params.setHostMode(d->hostMode);
215 d->generalSetupPanel->fillInParams(params);
216 d->dmflagsPanel->fillInParams(params);
218 if (!fillInParamsFromPluginPages(params))
221 d->customParamsPanel->fillInParams(params);
222 d->serverPanel->fillInParams(params);
223 d->rulesPanel->fillInParams(params);
225 return createHostInfoDemoRecord(params, offline, purpose);
228 bool CreateServerDialog::createHostInfoDemoRecord(
GameCreateParams ¶ms,
bool offline, CommandLinePurpose purpose)
230 if (gConfig.doomseeker.bRecordDemo && offline)
232 const GameDemo::Control demoMode = purpose == CommandLinePurpose::Run
233 ? GameDemo::Managed : GameDemo::Unmanaged;
234 if (demoMode == GameDemo::Managed)
236 if (!GameDemo::ensureStorageExists(
this))
242 params.setDemoPath(GameDemo::mkDemoFullPath(demoMode, *d->currentEngine));
243 params.setDemoRecord(demoMode);
248 GameMode CreateServerDialog::currentGameMode()
const
250 return d->generalSetupPanel->currentGameMode();
253 void CreateServerDialog::firstLoadConfigTimer()
255 initEngineSpecific(d->generalSetupPanel->currentPlugin());
256 QString tmpGameCfgPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
258 QFileInfo fi(tmpGameCfgPath);
260 loadConfig(tmpGameCfgPath,
true);
263 void CreateServerDialog::initDMFlagsTabs()
265 bool flagsAdded = d->dmflagsPanel->initDMFlagsTabs(d->currentEngine);
266 int tabIndex = d->tabWidget->indexOf(d->tabFlags);
267 if (flagsAdded && tabIndex < 0)
268 d->tabWidget->insertTab(d->tabWidget->indexOf(d->tabCustomParameters), d->tabFlags, tr(
"Flags"));
269 else if (!flagsAdded && tabIndex >= 0)
270 d->tabWidget->removeTab(tabIndex);
273 void CreateServerDialog::initEngineSpecific(
EnginePlugin *engine)
275 if (engine == d->currentEngine || engine ==
nullptr)
278 d->currentEngine = engine;
280 d->generalSetupPanel->setupForEngine(engine);
282 initEngineSpecificPages(engine);
287 void CreateServerDialog::initEngineSpecificPages(
EnginePlugin *engine)
292 d->currentCustomPages.clear();
298 int idxInsertAt = d->tabWidget->indexOf(d->tabCustomParameters);
299 d->tabWidget->insertTab(idxInsertAt, page, page->name());
303 void CreateServerDialog::initGamemodeSpecific(
const GameMode &gameMode)
305 d->rulesPanel->setupForEngine(d->currentEngine, gameMode);
308 void CreateServerDialog::initServerTab()
310 if (d->currentEngine !=
nullptr)
311 d->serverPanel->setupForEngine(d->currentEngine);
312 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabServer),
313 d->serverPanel->isAnythingAvailable() && d->hostMode != GameCreateParams::Offline);
316 void CreateServerDialog::initRules()
318 d->rulesPanel->setupForEngine(d->currentEngine, currentGameMode());
319 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabRules), d->rulesPanel->isAnythingAvailable());
322 bool CreateServerDialog::loadConfig(
const QString &filename,
bool loadingPrevious)
324 QSettings settingsFile(filename, QSettings::IniFormat);
326 Ini ini(&settingsProvider);
328 d->generalSetupPanel->loadConfig(ini, loadingPrevious);
329 d->rulesPanel->loadConfig(ini);
330 d->serverPanel->loadConfig(ini);
331 d->dmflagsPanel->loadConfig(ini);
336 d->customParamsPanel->loadConfig(ini);
338 if (d->canLoadHostModeFromConfig())
340 d->hostMode = d->hostModeFromCfgName(ini.section(
"General")[
"hostMode"]);
347 void CreateServerDialog::makeRemoteGameSetupDialog(
EnginePlugin *plugin)
349 initEngineSpecific(plugin);
350 d->hostMode = GameCreateParams::Remote;
356 return d->rulesPanel->mapListPanel();
359 QString CreateServerDialog::mapName()
const
361 return d->generalSetupPanel->mapName();
364 QStringList CreateServerDialog::wadPaths()
const
366 return d->generalSetupPanel->getAllWadPaths();
369 bool CreateServerDialog::fillInParamsFromPluginPages(
GameCreateParams ¶ms)
378 d->tabWidget->setCurrentIndex(d->tabWidget->indexOf(page));
385 void CreateServerDialog::runGame(
bool offline)
387 const QString errorCapt = tr(
"Doomseeker - create game");
388 if (d->currentEngine ==
nullptr)
390 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
395 if (createHostInfo(gameParams, offline, CommandLinePurpose::Run))
399 GameHost *gameRunner = d->currentEngine->gameHost();
405 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), 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->hostModeCfgName();
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(
bool offline)
487 if (commandLineArguments(executable, args, offline, CommandLinePurpose::Show))
493 QString title = offline ?
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::showStartGameCommandLine()
534 showCommandLine(d->hostMode == GameCreateParams::Offline);
537 void CreateServerDialog::startGame()
539 if (d->hostMode != GameCreateParams::Remote)
540 runGame(d->hostMode == GameCreateParams::Offline);