Skip to content

Commit

Permalink
Multiplayer|Client: Load local packages when joining a game
Browse files Browse the repository at this point in the history
The configured local packages are added to the server profile. No
compatibility checks for made at the moment.
  • Loading branch information
skyjake committed Feb 4, 2017
1 parent 48ab26c commit 9143d6f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 47 deletions.
42 changes: 31 additions & 11 deletions doomsday/apps/client/src/network/serverlink.cpp
Expand Up @@ -36,11 +36,13 @@
#include <de/GuiApp>
#include <de/Message>
#include <de/MessageDialog>
#include <de/PackageLoader>
#include <de/RecordValue>
#include <de/Socket>
#include <de/data/json.h>
#include <de/memory.h>
#include <de/shell/ServerFinder>
#include <doomsday/DoomsdayApp>
#include <doomsday/Games>
#include <QTimer>

Expand Down Expand Up @@ -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;
Expand All @@ -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());

Expand Down
39 changes: 4 additions & 35 deletions doomsday/apps/client/src/ui/dialogs/serverinfodialog.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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())
Expand All @@ -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())
{
Expand Down Expand Up @@ -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<ArrayValue>().toStringList();
}
return StringList();
}
catch (Error const &)
{
return StringList();
}
}

static void setLocalPackagesForGame(String const &gameId, StringList const &packages)
{
std::unique_ptr<ArrayValue> ids(new ArrayValue);
for (String const &pkg : packages)
{
ids->add(pkg);
}
Config::get()["resource.localPackagesForGame"]
.value().as<DictionaryValue>()
.setElement(TextValue(gameId), ids.release());
}

//- Queries to the server ---------------------------------------------------------------

void startQuery(Query query)
Expand Down
Expand Up @@ -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);
Expand Down

0 comments on commit 9143d6f

Please sign in to comment.