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/configuration/doomseekerconfigurationdialog.h" 33 #include "gui/widgets/createserverdialogpage.h" 35 #include "ini/settingsproviderqt.h" 36 #include "plugins/engineplugin.h" 37 #include "serverapi/gamecreateparams.h" 38 #include "serverapi/gamehost.h" 39 #include "serverapi/message.h" 42 #include <QFileDialog> 43 #include <QKeySequence> 45 #include <QMessageBox> 49 DClass<CreateServerDialog> :
public Ui::CreateServerDialog
52 QList<CreateServerDialogPage *> currentCustomPages;
54 GameCreateParams::HostMode hostMode;
57 QAction *hostModeAction;
58 QAction *offlineModeAction;
60 bool canLoadHostModeFromConfig()
const 62 return hostMode == GameCreateParams::Host
63 || hostMode == GameCreateParams::Offline;
66 QString hostModeCfgName()
const 71 case GameCreateParams::Host:
return "host";
72 case GameCreateParams::Offline:
return "offline";
76 GameCreateParams::HostMode hostModeFromCfgName(
const QString &name)
78 if (name ==
"offline")
79 return GameCreateParams::Offline;
81 return GameCreateParams::Host;
93 setAttribute(Qt::WA_DeleteOnClose);
94 assert(hostMode == GameCreateParams::Offline
95 || hostMode == GameCreateParams::Host
96 || hostMode == GameCreateParams::Remote);
99 setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
101 d->currentEngine =
nullptr;
102 d->hostMode = hostMode;
109 d->generalSetupPanel->setCreateServerDialog(
this);
110 d->rulesPanel->setCreateServerDialog(
this);
112 d->tabWidget->setObjectName(
"createGameTabWidget");
113 d->tabWidget->setStyleSheet(
"#createGameTabWidget::pane { border: 0; }");
119 QTimer::singleShot(1,
this, SLOT(firstLoadConfigTimer()));
122 CreateServerDialog::~CreateServerDialog()
126 void CreateServerDialog::applyModeToUi()
128 d->generalSetupPanel->setupForHostMode(d->hostMode);
129 d->rulesPanel->setupForHostMode(d->hostMode);
132 d->modeMenu->setEnabled(d->hostMode != GameCreateParams::Remote);
133 d->hostModeAction->setChecked(d->hostMode == GameCreateParams::Host);
134 d->offlineModeAction->setChecked(d->hostMode == GameCreateParams::Offline);
136 if (d->hostMode == GameCreateParams::Host)
137 d->btnStart->setText(tr(
"Host server"));
139 d->btnStart->setText(tr(
"Play"));
144 case GameCreateParams::Remote:
145 windowTitle = tr(
"Doomseeker - Setup Remote Game");
147 case GameCreateParams::Host:
148 windowTitle = tr(
"Doomseeker - Host Online Game");
150 case GameCreateParams::Offline:
151 windowTitle = tr(
"Doomseeker - Play Offline Game");
154 windowTitle = tr(
"Doomseeker - [Unhandled Host Mode]");
157 setWindowTitle(windowTitle);
159 d->btnCommandLine->setVisible(d->hostMode != GameCreateParams::Remote);
162 void CreateServerDialog::changeToHostMode()
164 d->hostMode = GameCreateParams::Host;
168 void CreateServerDialog::changeToOfflineMode()
170 d->hostMode = GameCreateParams::Offline;
174 bool CreateServerDialog::commandLineArguments(QString &executable, QStringList &args,
bool offline)
176 const QString errorCapt = tr(
"Doomseeker - create game");
177 if (d->currentEngine ==
nullptr)
179 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
184 if (createHostInfo(gameParams, offline))
189 GameHost *gameRunner = d->currentEngine->gameHost();
196 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
201 executable = cli.
executable.absoluteFilePath();
209 bool CreateServerDialog::createHostInfo(
GameCreateParams ¶ms,
bool offline)
211 params.setHostMode(d->hostMode);
212 d->generalSetupPanel->fillInParams(params);
213 d->dmflagsPanel->fillInParams(params);
215 if (!fillInParamsFromPluginPages(params))
218 d->customParamsPanel->fillInParams(params);
219 d->serverPanel->fillInParams(params);
220 d->rulesPanel->fillInParams(params);
222 createHostInfoDemoRecord(params, offline);
226 void CreateServerDialog::createHostInfoDemoRecord(
GameCreateParams ¶ms,
bool offline)
228 if (gConfig.doomseeker.bRecordDemo && offline)
230 params.setDemoPath(GameDemo::mkDemoFullPath(GameDemo::Managed, *d->currentEngine));
231 params.setDemoRecord(GameDemo::Managed);
235 GameMode CreateServerDialog::currentGameMode()
const 237 return d->generalSetupPanel->currentGameMode();
240 void CreateServerDialog::firstLoadConfigTimer()
242 initEngineSpecific(d->generalSetupPanel->currentPlugin());
243 QString tmpGameCfgPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
245 QFileInfo fi(tmpGameCfgPath);
247 loadConfig(tmpGameCfgPath,
true);
250 void CreateServerDialog::initDMFlagsTabs()
252 bool flagsAdded = d->dmflagsPanel->initDMFlagsTabs(d->currentEngine);
253 int tabIndex = d->tabWidget->indexOf(d->tabFlags);
254 if (flagsAdded && tabIndex < 0)
255 d->tabWidget->insertTab(d->tabWidget->indexOf(d->tabCustomParameters), d->tabFlags, tr(
"Flags"));
256 else if (!flagsAdded && tabIndex >= 0)
257 d->tabWidget->removeTab(tabIndex);
260 void CreateServerDialog::initEngineSpecific(
EnginePlugin *engine)
262 if (engine == d->currentEngine || engine ==
nullptr)
265 d->currentEngine = engine;
267 d->generalSetupPanel->setupForEngine(engine);
269 initEngineSpecificPages(engine);
274 void CreateServerDialog::initEngineSpecificPages(
EnginePlugin *engine)
279 d->currentCustomPages.clear();
285 int idxInsertAt = d->tabWidget->indexOf(d->tabCustomParameters);
286 d->tabWidget->insertTab(idxInsertAt, page, page->name());
290 void CreateServerDialog::initGamemodeSpecific(
const GameMode &gameMode)
292 d->rulesPanel->setupForEngine(d->currentEngine, gameMode);
295 void CreateServerDialog::initServerTab()
297 if (d->currentEngine !=
nullptr)
298 d->serverPanel->setupForEngine(d->currentEngine);
299 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabServer),
300 d->serverPanel->isAnythingAvailable() && d->hostMode != GameCreateParams::Offline);
303 void CreateServerDialog::initRules()
305 d->rulesPanel->setupForEngine(d->currentEngine, currentGameMode());
306 d->tabWidget->setTabEnabled(d->tabWidget->indexOf(d->tabRules), d->rulesPanel->isAnythingAvailable());
309 bool CreateServerDialog::loadConfig(
const QString &filename,
bool loadingPrevious)
311 QSettings settingsFile(filename, QSettings::IniFormat);
313 Ini ini(&settingsProvider);
315 d->generalSetupPanel->loadConfig(ini, loadingPrevious);
316 d->rulesPanel->loadConfig(ini);
317 d->serverPanel->loadConfig(ini);
318 d->dmflagsPanel->loadConfig(ini);
323 d->customParamsPanel->loadConfig(ini);
325 if (d->canLoadHostModeFromConfig())
327 d->hostMode = d->hostModeFromCfgName(ini.section(
"General")[
"hostMode"]);
334 void CreateServerDialog::makeRemoteGameSetupDialog(
EnginePlugin *plugin)
336 initEngineSpecific(plugin);
337 d->hostMode = GameCreateParams::Remote;
343 return d->rulesPanel->mapListPanel();
346 QString CreateServerDialog::mapName()
const 348 return d->generalSetupPanel->mapName();
351 QStringList CreateServerDialog::wadPaths()
const 353 return d->generalSetupPanel->getAllWadPaths();
356 bool CreateServerDialog::fillInParamsFromPluginPages(
GameCreateParams ¶ms)
365 d->tabWidget->setCurrentIndex(d->tabWidget->indexOf(page));
372 void CreateServerDialog::runGame(
bool offline)
374 const QString errorCapt = tr(
"Doomseeker - create game");
375 if (d->currentEngine ==
nullptr)
377 QMessageBox::critical(
nullptr, errorCapt, tr(
"No game selected"));
382 if (createHostInfo(gameParams, offline))
386 GameHost *gameRunner = d->currentEngine->gameHost();
392 QMessageBox::critical(
nullptr, tr(
"Doomseeker - error"), message.
contents());
395 QString tmpGameConfigPath = gDefaultDataPaths->programsDataDirectoryPath() + TEMP_GAME_CONFIG_FILENAME;
396 saveConfig(tmpGameConfigPath);
401 bool CreateServerDialog::saveConfig(
const QString &filename)
403 QSettings settingsFile(filename, QSettings::IniFormat);
405 Ini ini(&settingsProvider);
407 d->generalSetupPanel->saveConfig(ini);
408 d->rulesPanel->saveConfig(ini);
409 d->serverPanel->saveConfig(ini);
410 d->dmflagsPanel->saveConfig(ini);
415 d->customParamsPanel->saveConfig(ini);
417 ini.section(
"General")[
"hostMode"] = d->hostModeCfgName();
419 if (settingsFile.isWritable())
427 void CreateServerDialog::setIwadByName(
const QString &iwad)
429 d->generalSetupPanel->setIwadByName(iwad);
432 void CreateServerDialog::setupMenu()
434 QMenuBar *mainMenu =
new QMenuBar(
this);
436 d->modeMenu = mainMenu->addMenu(tr(
"&Mode"));
437 d->hostModeAction = d->modeMenu->addAction(tr(
"&Host server"),
438 this, SLOT(changeToHostMode()));
439 d->hostModeAction->setCheckable(
true);
440 d->offlineModeAction = d->modeMenu->addAction(tr(
"&Play offline"),
441 this, SLOT(changeToOfflineMode()));
442 d->offlineModeAction->setCheckable(
true);
444 auto *settingsMenu = mainMenu->addMenu(tr(
"&Settings"));
446 auto *loadConfigAction = settingsMenu->addAction(tr(
"&Load game configuration"),
447 this, SLOT(showLoadConfig()));
448 loadConfigAction->setIcon(style()->standardIcon(QStyle::SP_DirIcon));
449 loadConfigAction->setShortcut(QKeySequence(
"Ctrl+O"));
451 auto *saveConfigAction = settingsMenu->addAction(tr(
"&Save game configuration"),
452 this, SLOT(showSaveConfig()));
453 saveConfigAction->setIcon(QIcon(
":/icons/diskette.png"));
454 saveConfigAction->setShortcut(QKeySequence(
"Ctrl+S"));
455 settingsMenu->addSeparator();
457 auto *programSettings = settingsMenu->addAction(tr(
"&Program settings"),
458 this, SLOT(showConfiguration()));
459 programSettings->setIcon(QIcon(
":/icons/preferences-system-4.png"));
461 d->dialogLayout->setMenuBar(mainMenu);
464 void CreateServerDialog::showConfiguration()
466 DoomseekerConfigurationDialog::openConfiguration(
this, d->currentEngine);
467 d->generalSetupPanel->reloadAppConfig();
470 void CreateServerDialog::showCommandLine(
bool offline)
474 if (commandLineArguments(executable, args, offline))
480 QString title = offline ?
481 tr(
"Run game command line:") :
482 tr(
"Host server command line:");
483 CopyTextDlg ctd(executable +
" " + args.join(
" "), title,
this);
488 void CreateServerDialog::showLoadConfig()
490 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
491 QString strFile = QFileDialog::getOpenFileName(
this, tr(
"Doomseeker - load game setup config"), dialogDir, tr(
"Config files (*.ini)"));
493 if (!strFile.isEmpty())
495 QFileInfo fi(strFile);
496 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
498 loadConfig(strFile,
false);
502 void CreateServerDialog::showSaveConfig()
504 QString dialogDir = gConfig.doomseeker.previousCreateServerConfigDir;
505 QString strFile = QFileDialog::getSaveFileName(
this, tr(
"Doomseeker - save game setup config"), dialogDir, tr(
"Config files (*.ini)"));
506 if (!strFile.isEmpty())
508 QFileInfo fi(strFile);
509 gConfig.doomseeker.previousCreateServerConfigDir = fi.absolutePath();
511 if (fi.suffix().isEmpty())
514 if (!saveConfig(strFile))
515 QMessageBox::critical(
nullptr, tr(
"Doomseeker - save game setup config"), tr(
"Unable to save game setup configuration!"));
519 void CreateServerDialog::showStartGameCommandLine()
521 showCommandLine(d->hostMode == GameCreateParams::Offline);
524 void CreateServerDialog::startGame()
526 if (d->hostMode != GameCreateParams::Remote)
527 runGame(d->hostMode == GameCreateParams::Offline);
virtual bool saveConfig(Ini &ini)=0
Saves variables defined by this page to a config.
Game parametrization data used when creating new games.
Structure holding parameters for application launch.
Message object used to pass messages throughout the Doomseeker's system.
QStringList args
launch parameters
bool isError() const
True if type() is equal to or greater than CUSTOM_ERROR.
virtual void fillInGameCreateParams(GameCreateParams ¶ms)=0
Fills in GameCreateParams structure with the page's contents.
Dialog window allowing user to create a game.
Game mode representation.
Base class to be used by plugins to define custom pages in Create Game dialog.
Message createHostCommandLine(const GameCreateParams ¶ms, CommandLineInfo &cmdLine)
static void escapeExecutable(QString &arg)
Escapes the executable path and handles OS X bundles.
Creates game servers, offline games or demo playbacks.
virtual QList< CreateServerDialogPage * > createServerDialogPages(CreateServerDialog *pDialog)
Creates a list of custom Create Game dialog pages.
QString contents() const
Customized displayable contents of this Message.
static void escapeArgs(QStringList &args)
Escapes all characters in all strings on the list.
Message host(const GameCreateParams ¶ms)
QFileInfo executable
path to the executable
virtual bool validate()
Validates contents of the page before fillInGameCreateParams().
virtual bool loadConfig(Ini &ini)=0
Loads variables that are stored in the config into the GUI.