From 9143d6f7bde8696bdec63b82a68c13a67d61aa96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Sat, 4 Feb 2017 23:02:47 +0200 Subject: [PATCH] Multiplayer|Client: Load local packages when joining a game The configured local packages are added to the server profile. No compatibility checks for made at the moment. --- .../apps/client/src/network/serverlink.cpp | 42 ++++++++++++++----- .../src/ui/dialogs/serverinfodialog.cpp | 39 ++--------------- .../ui/home/multiplayerpanelbuttonwidget.cpp | 9 +++- 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/doomsday/apps/client/src/network/serverlink.cpp b/doomsday/apps/client/src/network/serverlink.cpp index 2a454a3711..b810fd7e47 100644 --- a/doomsday/apps/client/src/network/serverlink.cpp +++ b/doomsday/apps/client/src/network/serverlink.cpp @@ -36,11 +36,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -375,20 +377,38 @@ void ServerLink::connectToServerAndChangeGame(shell::ServerInfo info) auto &win = ClientWindow::main(); win.glActivate(); - if (!serverProfile->isPlayable()) + // If additional packages are configured, set up the ad-hoc profile. + GameProfile const *joinProfile = serverProfile; + auto const localPackages = serverProfile->game().localMultiplayerPackages(); + if (localPackages.count()) { - auto prettyPkg = [] (String const &pkgId) -> String { - auto meta = Package::split(pkgId); - if (meta.second.isValid()) { - return String("%1 (version %2)").arg(meta.first).arg(meta.second.asText()); + // Make sure the packages are available. + for (String const &pkg : localPackages) + { + if (!PackageLoader::get().select(pkg)) + { + String const errorMsg = tr("The configured local multiplayer " + "package %1 is unavailable.") + .arg(Package::splitToHumanReadable(pkg)); + LOG_NET_ERROR("Failed to join %s: ") << info.address() << errorMsg; + d->reportError(errorMsg); + return; } - return pkgId; - }; + } - String const errorMsg = QString("Server's game \"%1\" is not playable on this system. " - "The following packages are unavailable:\n\n%2") + auto &adhoc = DoomsdayApp::app().adhocProfile(); + adhoc = *serverProfile; + adhoc.setPackages(serverProfile->packages() + localPackages); + joinProfile = &adhoc; + } + + if (!joinProfile->isPlayable()) + { + String const errorMsg = tr("Server's game \"%1\" is not playable on this system. " + "The following packages are unavailable:\n\n%2") .arg(info.gameId()) - .arg(String::join(de::map(serverProfile->unavailablePackages(), prettyPkg), "\n")); + .arg(String::join(de::map(joinProfile->unavailablePackages(), + Package::splitToHumanReadable), "\n")); LOG_NET_ERROR("Failed to join %s: ") << info.address() << errorMsg; d->reportError(errorMsg); return; @@ -397,7 +417,7 @@ void ServerLink::connectToServerAndChangeGame(shell::ServerInfo info) BusyMode_FreezeGameForBusyMode(); win.taskBar().close(); - DoomsdayApp::app().changeGame(*serverProfile, DD_ActivateGameWorker); + DoomsdayApp::app().changeGame(*joinProfile, DD_ActivateGameWorker); connectHost(info.address()); diff --git a/doomsday/apps/client/src/ui/dialogs/serverinfodialog.cpp b/doomsday/apps/client/src/ui/dialogs/serverinfodialog.cpp index 0f1b91dacb..345a38f9e9 100644 --- a/doomsday/apps/client/src/ui/dialogs/serverinfodialog.cpp +++ b/doomsday/apps/client/src/ui/dialogs/serverinfodialog.cpp @@ -188,7 +188,7 @@ DENG_GUI_PIMPL(ServerInfoDialog) QObject::connect(localPackages, &PackagesButtonWidget::packageSelectionChanged, [this] (QStringList const &packages) { - setLocalPackagesForGame(profile.gameId(), toStringList(packages)); + Game::setLocalMultiplayerPackages(profile.gameId(), toStringList(packages)); }); updateLayout(); @@ -284,10 +284,9 @@ DENG_GUI_PIMPL(ServerInfoDialog) // Local packages. { - localPackages->setDialogTitle(tr("Local Packages for %1 Multiplayer") - .arg(profile.name())); + localPackages->setDialogTitle(tr("Local Packages for %1 Multiplayer").arg(gameTitle)); localPackages->setGameProfile(profile); - localPackages->setPackages(localPackagesForGame(gameId)); + localPackages->setPackages(Game::localMultiplayerPackages(gameId)); } if (!serverInfo.packages().isEmpty()) @@ -304,7 +303,7 @@ DENG_GUI_PIMPL(ServerInfoDialog) else { auto const id_ver = Package::split(pkgId); - pkgId = String("%1 (%2)").arg(id_ver.first).arg(id_ver.second.asText()); + pkgId = Package::splitToHumanReadable(pkgId); Version localVersion; if (id_ver.second.isValid()) { @@ -341,36 +340,6 @@ DENG_GUI_PIMPL(ServerInfoDialog) serverPopup->openOrClose(); } - static StringList localPackagesForGame(String const &gameId) - { - try - { - auto const &pkgDict = Config::get().getdt("resource.localPackagesForGame"); - TextValue const key(gameId); - if (pkgDict.contains(key)) - { - return pkgDict.element(key).as().toStringList(); - } - return StringList(); - } - catch (Error const &) - { - return StringList(); - } - } - - static void setLocalPackagesForGame(String const &gameId, StringList const &packages) - { - std::unique_ptr ids(new ArrayValue); - for (String const &pkg : packages) - { - ids->add(pkg); - } - Config::get()["resource.localPackagesForGame"] - .value().as() - .setElement(TextValue(gameId), ids.release()); - } - //- Queries to the server --------------------------------------------------------------- void startQuery(Query query) diff --git a/doomsday/apps/client/src/ui/home/multiplayerpanelbuttonwidget.cpp b/doomsday/apps/client/src/ui/home/multiplayerpanelbuttonwidget.cpp index 501507b199..82d8004976 100644 --- a/doomsday/apps/client/src/ui/home/multiplayerpanelbuttonwidget.cpp +++ b/doomsday/apps/client/src/ui/home/multiplayerpanelbuttonwidget.cpp @@ -190,7 +190,14 @@ void MultiplayerPanelButtonWidget::updateContent(shell::ServerInfo const &info) icon().setImage(nullptr); } - infoText += "\n" _E(C) + String(info.description()); + infoText += "\n" _E(C) + String(info.description()) + _E(.); + + int const localCount = Game::localMultiplayerPackages(info.gameId()).size(); + if (localCount) + { + infoText += "\n" _E(D)_E(b) + String("%1 local package%2").arg(localCount) + .arg(DENG2_PLURAL_S(localCount)); + } d->info->setFont("small"); d->info->setText(infoText);