23 #include "generalgamesetuppanel.h"
24 #include "ui_generalgamesetuppanel.h"
26 #include "configuration/doomseekerconfig.h"
27 #include "filefilter.h"
28 #include "gui/createserver/maplistpanel.h"
29 #include "gui/createserverdialog.h"
31 #include "plugins/engineplugin.h"
32 #include "plugins/pluginloader.h"
33 #include "serverapi/gamecreateparams.h"
34 #include "serverapi/gameexefactory.h"
35 #include "serverapi/gamefile.h"
36 #include "templatedpathresolver.h"
38 #include <QFileDialog>
40 #include <QMessageBox>
43 DClass<GeneralGameSetupPanel> :
public Ui::GeneralGameSetupPanel
47 GameCreateParams::HostMode hostMode;
48 bool iwadSetExplicitly;
53 int hostModeSpacerRow;
55 bool isValidExecutable(
const QString &executablePath)
57 QFileInfo fileInfo(executablePath);
58 return !executablePath.isEmpty() && fileInfo.isFile();
69 d->hostMode = GameCreateParams::Host;
70 d->iwadSetExplicitly =
false;
71 d->parentDialog =
nullptr;
73 d->hostExecutableInput->setAllowedExecutables(GameFile::Server);
74 d->offlineExecutableInput->setAllowedExecutables(GameFile::Offline);
75 d->remoteExecutableInput->setAllowedExecutables(GameFile::Client);
77 d->formLayout->getWidgetPosition(d->leServerName, &d->serverNameRow,
nullptr);
78 d->formLayout->getWidgetPosition(d->portArea, &d->portRow,
nullptr);
79 d->formLayout->getWidgetPosition(d->hostModeSpacer, &d->hostModeSpacerRow,
nullptr);
81 this->connect(d->cboEngine, SIGNAL(currentPluginChanged(
EnginePlugin*)),
85 GeneralGameSetupPanel::~GeneralGameSetupPanel()
89 QStringList GeneralGameSetupPanel::getAllWadPaths()
const
92 paths << d->iwadPicker->currentIwad() << d->wadsPicker->filePaths();
102 params.setPwadsOptional(d->wadsPicker->fileOptional());
103 params.setBroadcastToLan(d->cbBroadcastToLAN->isChecked());
104 params.setBroadcastToMaster(d->cbBroadcastToMaster->isChecked());
105 params.setMap(d->leMap->text());
106 params.setName(d->leServerName->text());
107 params.setPort(d->spinPort->isEnabled() ? d->spinPort->value() : 0);
108 params.setGameMode(currentGameMode());
109 params.setSkill(d->cboDifficulty->itemData(d->cboDifficulty->currentIndex()).toInt());
110 params.setUpnp(d->cbUpnp->isChecked());
111 params.setUpnpPort(d->spinUpnpPort->value());
114 void GeneralGameSetupPanel::loadConfig(
Ini &config,
bool loadingPrevious)
120 QString configEngineName = general[
"engine"];
121 bool engineChanged =
false;
122 if (d->hostMode != GameCreateParams::Remote)
124 if (!setEngine(configEngineName))
126 engineChanged = (prevEngine != d->currentEngine);
130 bool changeExecutable = engineChanged || !d->cbLockExecutable->isChecked();
131 if (d->hostMode == GameCreateParams::Remote)
136 auto *plugin = gPlugins->plugin(gPlugins->pluginIndexFromName(configEngineName));
137 if (plugin ==
nullptr || d->currentEngine != plugin->info())
138 changeExecutable =
false;
141 if (changeExecutable)
143 QString hostExecutablePath = *general[
"hostExecutable"];
144 if (d->isValidExecutable(hostExecutablePath))
145 d->hostExecutableInput->setPath(hostExecutablePath);
147 QString offlineExecutablePath = *general[
"offlineExecutable"];
148 if (d->isValidExecutable(offlineExecutablePath))
149 d->offlineExecutableInput->setPath(offlineExecutablePath);
151 QString remoteExecutablePath = *general[
"remoteExecutable"];
152 if (d->isValidExecutable(remoteExecutablePath))
153 d->remoteExecutableInput->setPath(remoteExecutablePath);
157 d->leServerName->setText(general[
"name"]);
158 d->spinPort->setValue(general[
"port"]);
160 int gameModeIndex = d->cboGamemode->findData(static_cast<gamemode_id>(general[
"gamemode"]));
161 if (gameModeIndex >= 0)
162 d->cboGamemode->setCurrentIndex(gameModeIndex);
164 int difficultyIndex = d->cboDifficulty->findData(static_cast<int>(general[
"difficulty"]));
165 d->cboDifficulty->setCurrentIndex(qMax(0, difficultyIndex));
167 d->leMap->setText(general[
"map"]);
169 if (!(loadingPrevious && d->iwadSetExplicitly))
170 d->iwadPicker->addIwad(general[
"iwad"]);
172 d->logDirectoryPicker->setLoggingEnabled(general[
"logEnabled"]);
173 d->logDirectoryPicker->setPathAndUpdate(general[
"logDir"]);
175 QList<bool> optionalWads;
176 for (QString value : general[
"pwadsOptional"].valueString().split(
";"))
178 optionalWads << (value !=
"0");
180 d->wadsPicker->setFilePaths(general[
"pwads"].valueString().split(
";"), optionalWads);
182 d->cbBroadcastToLAN->setChecked(general[
"broadcastToLAN"]);
183 d->cbBroadcastToMaster->setChecked(general[
"broadcastToMaster"]);
184 d->cbUpnp->setChecked(general[
"upnp"]);
185 d->spinUpnpPort->setValue(general[
"upnpPort"]);
188 QTimer::singleShot(0,
this, SLOT(updateMapWarningVisibility()));
191 void GeneralGameSetupPanel::saveConfig(
Ini &config)
194 general[
"engine"] = d->cboEngine->currentText();
195 general[
"hostExecutable"] = d->hostExecutableInput->path();
196 general[
"offlineExecutable"] = d->offlineExecutableInput->path();
197 general[
"remoteExecutable"] = d->remoteExecutableInput->path();
198 general[
"name"] = d->leServerName->text();
199 general[
"port"] = d->spinPort->value();
200 general[
"logDir"] = d->logDirectoryPicker->currentPath();
201 general[
"logEnabled"] = d->logDirectoryPicker->isLoggingEnabled();
202 general[
"gamemode"] = d->cboGamemode->itemData(d->cboGamemode->currentIndex()).toInt();
203 general[
"map"] = d->leMap->text();
204 general[
"difficulty"] = d->cboDifficulty->itemData(d->cboDifficulty->currentIndex()).toInt();
205 general[
"iwad"] = d->iwadPicker->currentIwad();
207 general[
"pwads"] = d->wadsPicker->filePaths().join(
";");
208 QList<bool> optionalWads = d->wadsPicker->fileOptional();
209 QStringList optionalList;
210 for (
bool optional : optionalWads)
212 optionalList << (optional ?
"1" :
"0");
214 general[
"pwadsOptional"] = optionalList.join(
";");
216 general[
"broadcastToLAN"] = d->cbBroadcastToLAN->isChecked();
217 general[
"broadcastToMaster"] = d->cbBroadcastToMaster->isChecked();
218 general[
"upnp"] = d->cbUpnp->isChecked();
219 general[
"upnpPort"] = d->spinUpnpPort->value();
222 void GeneralGameSetupPanel::reloadAppConfig()
224 d->hostExecutableInput->reloadExecutables();
225 d->offlineExecutableInput->reloadExecutables();
226 d->remoteExecutableInput->reloadExecutables();
227 d->iwadPicker->loadIwads();
230 void GeneralGameSetupPanel::setupDifficulty(
const EnginePlugin *engine)
232 QVariant oldDifficulty = d->cboDifficulty->itemData(d->cboDifficulty->currentIndex());
233 d->cboDifficulty->clear();
235 QList<GameCVar> levels = engine->data()->
difficulty->get(QVariant());
236 d->labelDifficulty->setVisible(!levels.isEmpty());
237 d->cboDifficulty->setVisible(!levels.isEmpty());
239 for (
const GameCVar &level : levels)
241 d->cboDifficulty->addItem(level.name(), level.value());
243 int memorizedIndex = d->cboDifficulty->findData(oldDifficulty);
244 if (memorizedIndex >= 0)
245 d->cboDifficulty->setCurrentIndex(memorizedIndex);
248 void GeneralGameSetupPanel::setupForEngine(
EnginePlugin *engine)
250 d->currentEngine = engine;
252 d->cboEngine->setPluginByName(engine->data()->name);
253 d->labelIwad->setVisible(engine->data()->hasIwad);
254 d->iwadPicker->setVisible(engine->data()->hasIwad);
255 d->labelLogging->setVisible(engine->data()->allowsLogging);
256 d->logDirectoryPicker->setVisible(engine->data()->allowsLogging);
257 d->upnpArea->setVisible(engine->data()->allowsUpnp);
258 d->spinUpnpPort->setVisible(engine->data()->allowsUpnpPort);
260 d->hostExecutableInput->setPlugin(engine);
261 d->offlineExecutableInput->setPlugin(engine);
262 d->remoteExecutableInput->setPlugin(engine);
264 d->spinPort->setValue(d->currentEngine->data()->defaultServerPort);
266 d->cboGamemode->clear();
269 QList<GameMode> gameModes = d->currentEngine->gameModes();
270 for (
int i = 0; i < gameModes.count(); ++i)
271 d->cboGamemode->addItem(gameModes[i].name(), gameModes[i].index());
272 setupDifficulty(engine);
275 void GeneralGameSetupPanel::setupForHostMode(GameCreateParams::HostMode hostMode)
277 d->hostMode = hostMode;
279 d->cboEngine->setDisabled(hostMode == GameCreateParams::Remote);
281 d->hostExecutableInput->hide();
282 d->offlineExecutableInput->hide();
283 d->remoteExecutableInput->hide();
287 case GameCreateParams::Host: d->hostExecutableInput->show();
break;
288 case GameCreateParams::Offline: d->offlineExecutableInput->show();
break;
289 case GameCreateParams::Remote: d->remoteExecutableInput->show();
break;
292 d->labelServerName->setVisible(hostMode == GameCreateParams::Host);
293 d->leServerName->setVisible(hostMode == GameCreateParams::Host);
294 d->labelPort->setVisible(hostMode == GameCreateParams::Host);
295 d->portArea->setVisible(hostMode == GameCreateParams::Host);
296 d->hostModeSpacer->setVisible(hostMode == GameCreateParams::Host);
297 d->broadcastOptionsArea->setVisible(hostMode == GameCreateParams::Host);
301 if (hostMode == GameCreateParams::Host)
303 d->formLayout->insertRow(d->serverNameRow, d->labelServerName, d->leServerName);
304 d->formLayout->insertRow(d->portRow, d->labelPort, d->portArea);
305 d->formLayout->insertRow(d->hostModeSpacerRow, d->hostModeSpacer,
306 static_cast<QWidget *>(
nullptr));
310 d->formLayout->removeWidget(d->labelServerName);
311 d->formLayout->removeWidget(d->leServerName);
312 d->formLayout->removeWidget(d->labelPort);
313 d->formLayout->removeWidget(d->portArea);
314 d->formLayout->removeWidget(d->hostModeSpacer);
320 d->parentDialog = dialog;
323 void GeneralGameSetupPanel::setIwadByName(
const QString &iwad)
325 d->iwadSetExplicitly =
true;
326 d->iwadPicker->setIwadByName(iwad);
329 void GeneralGameSetupPanel::showEvent(QShowEvent *event)
332 updateMapWarningVisibility();
335 QString GeneralGameSetupPanel::mapName()
const
337 return d->leMap->text();
340 QString GeneralGameSetupPanel::pathToExe()
345 case GameCreateParams::Host:
return d->hostExecutableInput->path();
346 case GameCreateParams::Offline:
return d->offlineExecutableInput->path();
347 case GameCreateParams::Remote:
return d->remoteExecutableInput->path();
351 void GeneralGameSetupPanel::onGameModeChanged(
int index)
354 emit gameModeChanged(currentGameMode());
357 GameMode GeneralGameSetupPanel::currentGameMode()
const
359 QList<GameMode> gameModes = d->currentEngine->gameModes();
360 for (
const GameMode &mode : gameModes)
362 if (mode.index() == d->cboGamemode->itemData(d->cboGamemode->currentIndex()).toInt())
365 return GameMode::mkUnknown();
368 EnginePlugin *GeneralGameSetupPanel::currentPlugin()
const
370 return d->cboEngine->currentPlugin();
373 bool GeneralGameSetupPanel::setEngine(
const QString &engineName)
375 if (!d->cboEngine->setPluginByName(engineName))
377 QMessageBox::critical(
this, tr(
"Doomseeker - load server config"),
378 tr(
"Plugin for engine \"%1\" is not present!").arg(engineName));
384 void GeneralGameSetupPanel::updateMapWarningVisibility()
386 assert(d->parentDialog !=
nullptr);
387 MapListPanel *mapList = d->parentDialog->mapListPanel();
388 d->lblMapWarning->setVisible(mapList->hasMaps() && !mapList->isMapOnList(mapName()));