23 #include "gameclientrunner.h"
25 #include "configuration/doomseekerconfig.h"
26 #include "ini/inisection.h"
27 #include "ini/inivariable.h"
28 #include "pathfinder/pathfinder.h"
29 #include "pathfinder/wadpathfinder.h"
30 #include "plugins/engineplugin.h"
31 #include "serverapi/exefile.h"
32 #include "serverapi/gameexeretriever.h"
33 #include "serverapi/message.h"
34 #include "serverapi/server.h"
35 #include "apprunner.h"
36 #include "commandlinetokenizer.h"
39 #include <QScopedPointer>
40 #include <QStringList>
42 DClass<ServerConnectParams>
45 QString connectPassword;
47 QString inGamePassword;
67 ServerConnectParams::~ServerConnectParams()
73 return d->connectPassword;
83 return d->inGamePassword;
86 void ServerConnectParams::setConnectPassword(
const QString& val)
88 d->connectPassword = val;
91 void ServerConnectParams::setDemoName(
const QString& val)
96 void ServerConnectParams::setInGamePassword(
const QString& val)
98 d->inGamePassword = val;
101 #define BAIL_ON_ERROR(method) \
104 if (isFatalError()) \
111 DClass<GameClientRunner>
114 QString argBexLoading;
116 QString argConnectPassword;
117 QString argDehLoading;
118 QString argInGamePassword;
119 QString argIwadLoading;
120 QString argOptionalWadLoading;
122 QString argPwadLoading;
123 QString argDemoRecord;
126 mutable QString cachedIwadPath;
130 QList<PWad> missingPwads;
145 POLYMORPHIC_DEFINE(
void, GameClientRunner, addExtra, (), ());
146 POLYMORPHIC_DEFINE(
void, GameClientRunner, addInGamePassword, (), ());
147 POLYMORPHIC_DEFINE(
void, GameClientRunner, addIwad, (), ());
148 POLYMORPHIC_DEFINE(
void, GameClientRunner, addPassword, (), ());
149 POLYMORPHIC_DEFINE(
void, GameClientRunner, createCommandLineArguments, (), ());
151 GameClientRunner::GameClientRunner(ServerPtr server)
153 set_addConnectCommand(&GameClientRunner::addConnectCommand_default);
154 set_addExtra(&GameClientRunner::addExtra_default);
155 set_addInGamePassword(&GameClientRunner::addInGamePassword_default);
156 set_addIwad(&GameClientRunner::addIwad_default);
157 set_addPassword(&GameClientRunner::addPassword_default);
158 set_createCommandLineArguments(&GameClientRunner::createCommandLineArguments_default);
159 d->argBexLoading =
"-deh";
160 d->argConnect =
"-connect";
161 d->argDehLoading =
"-deh";
162 d->argIwadLoading =
"-iwad";
163 d->argOptionalWadLoading =
"-file";
164 d->argPort =
"-port";
165 d->argPwadLoading =
"-file";
166 d->argDemoRecord =
"-record";
171 GameClientRunner::~GameClientRunner()
175 void GameClientRunner::addConnectCommand_default()
177 QString address = QString(
"%1:%2").arg(d->server->address().toString()).arg(d->server->port());
183 IniSection config = gConfig.iniSectionForPlugin(d->server->plugin());
184 QString customParameters = config[
"CustomParameters"];
186 args() << tokenizer.tokenize(customParameters);
196 GamePaths paths = gamePaths();
197 if (!paths.isValid())
203 QDir applicationDir = paths.workingDir;
204 if (paths.workingDir.isEmpty())
206 d->joinError.setType(JoinError::ConfigurationError);
207 d->joinError.setError(tr(
"Path to working directory for game \"%1\" is empty.\n\n"
208 "Make sure the configuration for the client executable is set properly.")
212 else if (!applicationDir.exists())
214 d->joinError.setType(JoinError::ConfigurationError);
215 d->joinError.setError(tr(
"%1\n\nThis directory cannot be used as working "
216 "directory for game: %2\n\nExecutable: %3")
217 .arg(paths.workingDir, pluginName(), paths.clientExe));
221 d->cli->executable = paths.clientExe;
222 d->cli->applicationDir = applicationDir;
225 void GameClientRunner::addInGamePassword_default()
233 gLog << tr(
"BUG: Plugin doesn't specify argument for in-game "
234 "password, but the server requires such password.");
238 void GameClientRunner::addExtra_default()
242 void GameClientRunner::addIwad_default()
252 if (!isIwadFound() || !d->missingPwads.isEmpty())
256 d->joinError.setMissingIwad(d->server->iwad());
258 d->joinError.setMissingWads(d->missingPwads);
259 foreach(
const PWad &wad, d->missingPwads)
264 d->joinError.setType(JoinError::MissingWads);
271 void GameClientRunner::addPassword_default()
279 gLog << tr(
"BUG: Plugin doesn't specify argument for connect "
280 "password, but the server is passworded.");
286 for (
int i = 0; i < d->server->numWads(); ++i)
288 QString pwad =
findWad(d->server->wad(i).name());
295 if (pwad.toLower().endsWith(
".deh"))
299 else if (pwad.toLower().endsWith(
".bex"))
301 args() << argForBexLoading() << pwad;
316 const QString& GameClientRunner::argForBexLoading()
const
318 return d->argBexLoading;
323 return d->argConnect;
328 return d->argConnectPassword;
333 return d->argDehLoading;
338 return d->argInGamePassword;
343 return d->argIwadLoading;
348 return d->argOptionalWadLoading;
358 return d->argPwadLoading;
363 return d->argDemoRecord;
366 bool GameClientRunner::canDownloadWadsInGame()
const
368 return d->server->plugin()->data()->inGameFileDownloads;
373 return d->connectParams.connectPassword();
376 void GameClientRunner::createCommandLineArguments_default()
380 if (d->server->isLocked())
384 if (d->server->isLockedInGame())
401 d->cli->args.clear();
402 d->connectParams = params;
406 if (d->joinError.isError())
417 return d->connectParams.demoName();
420 QString GameClientRunner::findIwad()
const
422 return findWad(d->server->iwad().toLower());
430 GameClientRunner::GamePaths GameClientRunner::gamePaths()
435 QScopedPointer<ExeFile> exeFile(d->server->clientExe());
436 result.clientExe = exeFile->pathToExe(msg);
437 if (result.clientExe.isEmpty())
444 d->joinError.setError(msg.
contents());
448 d->joinError.setError(tr(
"Game can be installed by Doomseeker"));
453 d->joinError.setType(JoinError::ConfigurationError);
454 QString error = tr(
"Client binary cannot be obtained for %1, please "
455 "check the location given in the configuration.").arg(pluginName());
460 d->joinError.setError(error);
464 result.workingDir = exeFile->workingDirectory(msg);
474 return d->connectParams.inGamePassword();
477 bool GameClientRunner::isFatalError()
const
479 if (d->joinError.isError())
481 if (d->joinError.isMissingWadsError() && canDownloadWadsInGame())
490 bool GameClientRunner::isIwadFound()
const
492 return !d->cachedIwadPath.isEmpty();
495 const QString& GameClientRunner::iwadPath()
const
499 d->cachedIwadPath = findIwad();
501 return d->cachedIwadPath;
506 d->missingPwads << pwadName;
511 return d->pathFinder;
517 return exeRetriever.pathToOfflineExe(msg);
520 const QString& GameClientRunner::pluginName()
const
522 return d->server->plugin()->data()->name;
527 return d->connectParams;
530 void GameClientRunner::setArgForBexLoading(
const QString& arg)
532 d->argBexLoading = arg;
535 void GameClientRunner::setArgForConnect(
const QString& arg)
540 void GameClientRunner::setArgForConnectPassword(
const QString& arg)
542 d->argConnectPassword = arg;
545 void GameClientRunner::setArgForDehLoading(
const QString& arg)
547 d->argDehLoading = arg;
550 void GameClientRunner::setArgForInGamePassword(
const QString& arg)
552 d->argInGamePassword = arg;
555 void GameClientRunner::setArgForIwadLoading(
const QString& arg)
557 d->argIwadLoading = arg;
560 void GameClientRunner::setArgForOptionalWadLoading(
const QString& arg)
562 d->argOptionalWadLoading = arg;
565 void GameClientRunner::setArgForPort(
const QString& arg)
570 void GameClientRunner::setArgForPwadLoading(
const QString& arg)
572 d->argPwadLoading = arg;
575 void GameClientRunner::setArgForDemoRecord(
const QString& arg)
577 d->argDemoRecord = arg;
590 void GameClientRunner::setupPathFinder()
592 d->pathFinder = d->server->wadPathFinder();
const QString & argForIwadLoading() const
Command line parameter that is used to set IWAD.
const QString & inGamePassword() const
"Join" password required in game.
const QString & argForOptionalWadLoading() const
Command line parameter that is used to load optional WADs.
Performs a case-insensitive (OS independent) file searches.
const QString & argForDehLoading() const
Command line parameter that is used to load a DEHACKED file.
const QString & argForConnect() const
Command line parameter that specifies the target server's IP and port.
Structure holding parameters for application launch.
Message object used to pass messages throughout the Doomseeker's system.
A convenience wrapper class for GameExeFactory.
void addCustomParameters()
Adds custom parameters defined by user in configuration box to the args list.
ServerConnectParams & serverConnectParams()
Direct access to ServerConnectParams associated with current command line generation.
void addDemoRecordCommand()
Adds command for demo recording.
A DTO for GameClientRunner; exchanges information between main program and plugins, and allows future extensions.
const QString & demoName() const
Name of the demo if demo should be recorded, otherwise empty.
QString wadTargetDirectory() const
Directory where Doomseeker stores downloaded WADs.
QStringList & args()
Output command line arguments.
void addPwads()
Finds and adds each PWAD to the args list, marks missing WADs.
JoinError joinError() const
JoinError set by last call to createJoinCommandLine().
static const unsigned GAME_NOT_FOUND_BUT_CAN_BE_INSTALLED
Indicates that program executable was not found, but Doomseeker or plugin are capable of performing t...
const QString & argForConnectPassword() const
Command line parameter that is used to specify connection password.
Indicator of error for the server join process.
const QString & argForPort() const
Command line parameter that is used to set internet port for the game.
JoinError createJoinCommandLine(CommandLineInfo &cli, const ServerConnectParams ¶ms)
Fills out CommandLineInfo object that allows client executables to be launched.
bool isIgnore() const
True for 'Null' messages.
PathFinder & pathFinder()
Reference to a PathFinder belonging to this GameClientRunner.
QString findWad(const QString &wad) const
Finds WAD in a way that supports user configured aliases.
const QString & argForPwadLoading() const
Command line parameter that is used to load a PWAD.
const QString & connectPassword() const
Password for server connection.
void addWads()
Calls addIwad() then addPwads(), sets JoinError::MissingWads in case of failure.
static DoomseekerConfig & config()
Returns the Singleton.
const QString & argForDemoRecord() const
Command line parameter for recording a demo.
void setJoinError(const JoinError &e)
Apply error that is passed to the launching routine and can be displayed to user. ...
const QString & argForInGamePassword() const
Command line parameter that is used to specify in-game ("join") password.
void addConnectCommand()
[Virtual] Adds connection arguments to the list.
INI section representation.
const QString & demoName() const
Name of demo if demo is to be recorded.
Splits command line into separate arguments in a manner appropriate for current OS.
Game executable was not found but it can be automatically installed by the plugin.
void addGamePaths()
Sets working directory and path to executable in out put CommandLineInfo.
bool isOptional() const
Is this WAD required to join the server?
const QString & inGamePassword() const
In-game "join" password.
void addPassword()
[Virtual] Adds connect password to the args list.
void addIwad()
[Virtual] Plugins can replace IWAD discovery mechanism and generation of relevant executable paramete...
Wrapper for PathFinder that specializes in findings WADs.
unsigned type() const
Message::Type.
QString contents() const
Customized displayable contents of this Message.
void addExtra()
[Virtual] Plugins can easily add plugin-specific arguments here.
Creates command line that launches the client executable of the game and connects it to a server...
QString pathToOfflineExe(Message &msg)
Retrieves path to offline exe from plugin's ExeFile.
void markPwadAsMissing(const PWad &pwadName)
Stores PWAD in an internal list of missing WADs.
void createCommandLineArguments()
[Virtual] Spawns entire command line for client executable launch.
const QString & connectPassword() const
Password for server connection.
void addInGamePassword()
[Virtual] Adds in-game password to the args list.