Skip to content

Commit

Permalink
Fixed|Server|libcommon: Starting a server with obsolete episode/map c…
Browse files Browse the repository at this point in the history
…vars

Maps are identified by URI nowadays, however server-game-map and
server-game-episode from an old .cfg file will contain a numeric map id.
In this case, the configured values are ignored and the default episode
and map are used.

IssueID #1931
  • Loading branch information
skyjake committed Jan 4, 2015
1 parent 9d41220 commit b0b6b09
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 15 deletions.
6 changes: 6 additions & 0 deletions doomsday/plugins/common/include/d_net.h
Expand Up @@ -26,6 +26,9 @@
#include "dd_share.h"
#include <de/reader.h>
#include <de/writer.h>
#ifdef __cplusplus
# include <de/String>
#endif

#include "common.h"

Expand Down Expand Up @@ -259,6 +262,9 @@ void D_NetMessageNoSound(int player, char const *msg);

#ifdef __cplusplus
} // extern "C"

de::String D_NetDefaultEpisode();
de::Uri D_NetDefaultMap();
#endif

#include "d_netsv.h"
Expand Down
57 changes: 42 additions & 15 deletions doomsday/plugins/common/src/d_net.cpp
Expand Up @@ -56,13 +56,31 @@ static void notifyAllowCheatsChange()
}
}

String D_NetDefaultEpisode()
{
return FirstPlayableEpisodeId();
}

de::Uri D_NetDefaultMap()
{
String const episodeId = D_NetDefaultEpisode();

de::Uri map("Maps:", RC_NULL);
if(!episodeId.isEmpty())
{
map = de::Uri(Defs().episodes.find("id", episodeId).gets("startMap"), RC_NULL);
DENG2_ASSERT(!map.isEmpty());
}
return map;
}

void D_NetConsoleRegister()
{
C_VAR_CHARPTR("mapcycle", &mapCycle, CVF_HIDE | CVF_NO_ARCHIVE, 0, 0);
C_VAR_CHARPTR("mapcycle", &mapCycle, CVF_HIDE | CVF_NO_ARCHIVE, 0, 0);

C_CMD ("setcolor", "i", SetColor);
#if __JHEXEN__
C_CMD_FLAGS ("setclass", "i", SetClass, CMDF_NO_DEDICATED);
C_CMD_FLAGS ("setclass", "i", SetClass, CMDF_NO_DEDICATED);
#endif
C_CMD ("startcycle", "", MapCycle);
C_CMD ("endcycle", "", MapCycle);
Expand All @@ -73,17 +91,10 @@ void D_NetConsoleRegister()
C_VAR_CHARPTR("server-game-episode", &cfg.common.netEpisode, 0, 0, 0);
C_VAR_URIPTR ("server-game-map", &cfg.common.netMap, 0, 0, 0);

String episodeId = FirstPlayableEpisodeId();
de::Uri map("Maps:", RC_NULL);
if(!episodeId.isEmpty())
{
map = de::Uri(Defs().episodes.find("id", episodeId).gets("startMap"), RC_NULL);
DENG2_ASSERT(!map.isEmpty());
}
else
{
LOG_NET_WARNING("No playable episode available. It will not be possible to start the server");
}
// Use the first playable map as the default.
String episodeId = D_NetDefaultEpisode();
de::Uri map = D_NetDefaultMap();

Con_SetString("server-game-episode", episodeId.toUtf8().constData());
Con_SetUri ("server-game-map", reinterpret_cast<uri_s *>(&map));
}
Expand Down Expand Up @@ -197,15 +208,31 @@ int D_NetServerStarted(int before)
#endif
P_ResetPlayerRespawnClasses();

String const episodeId = Con_GetString("server-game-episode");
String episodeId = Con_GetString("server-game-episode");
de::Uri mapUri = *reinterpret_cast<de::Uri const *>(Con_GetUri("server-game-map"));
if(mapUri.scheme().isEmpty()) mapUri.setScheme("Maps");

GameRuleset rules(COMMON_GAMESESSION->rules()); // Make a copy of the current rules.
rules.skill = skillmode_t(cfg.common.netSkill);

COMMON_GAMESESSION->end();
COMMON_GAMESESSION->begin(rules, episodeId, mapUri);

try
{
// First try the configured map.
COMMON_GAMESESSION->begin(rules, episodeId, mapUri);
}
catch(Error const &er)
{
LOGDEV_ERROR("Failed to start server: %s") << er.asText();
episodeId = D_NetDefaultEpisode();
mapUri = D_NetDefaultMap();
LOG_INFO("Using the default map (%s) to start the server due to failure to load the configured map")
<< mapUri;

COMMON_GAMESESSION->begin(rules, episodeId, mapUri);
}

G_SetGameAction(GA_NONE); /// @todo Necessary?

return true;
Expand Down

0 comments on commit b0b6b09

Please sign in to comment.